2008-12-25 14 views
6

बोर्लैंड डेल्फी 7 में और डेल्फी 2007 में भी सबकुछ काम करता था, लेकिन डेल्फी 200 9 में यह गलत हैश वापस देता है!डेल्फी 200 9 में एमडी 5 हैशिंग

मैं wcrypt2 लिपि (http://pastebin.com/m2f015cfd) का उपयोग

बस एक नजर है:

स्ट्रिंग: "123456"

हैश:

डेल्फी 7: "e10adc3949ba59abbe56e057f20f883e" - वास्तविक हैश।
डेल्फी 2007: "e10adc3949ba59abbe56e057f20f883e" - असली हैश भी।
और ... डेल्फी 200 9: "5fa285e1bebe0a6623e33afc04a1fbd5" - डब्ल्यूटीएफ ??

मैंने बहुत सी एमडी 5 स्क्रिप्ट की कोशिश की है, लेकिन डेल्फी 200 उन सभी के साथ समान है। कोई मदद? धन्यवाद।

उत्तर

0

क्या आप एक सामान्य स्ट्रिंग कास्टिंग करते हैं (जो डेल्फी 200 9 में यूनिकोडस्ट्रिंग है) एक पेंसिहर में और हैश फ़ंक्शन में गुजर रहा है? यह काम नहीं करेगा। आप पहली बार एक AnsiString में स्ट्रिंग डाली और फिर डाली कि PAnsiChar करने के लिए एक, एक ला करना होगा:

PAnsiChar(AnsiString('123456')) 

इसके अलावा, बजाय RawByteString का उपयोग कर dmajkic तरह का सुझाव दिया AnsiString प्रयास करें। UTF8String से बचें क्योंकि यह AnsiString नहीं है और ASCII रेंज (0..127) के बाहर के किसी भी वर्ण को मल्टीबाइट वर्णों में पुन: परिभाषित किया जा सकता है।

1

क्या आपने जांच की है कि आपकी लाइब्रेरी को डी 200 9 और यूनिकोडिफिकेशन के लिए सही तरीके से अपडेट किया गया है? मुझे संदेह है कि इस तरह की चीजों के लिए एक ही कोड डी 7/डी 2007 और डी 200 9 करेगा।

1

यह स्पष्ट है कि आपका lib यूनिकोड सक्षम नहीं है।

temp AnsiString घोषित करके अपनी स्ट्रिंग को AnsiString या RawByteString या UTF8String में कनवर्ट करें और अपनी यूनीओड स्ट्रिंग को असाइन करें।

ध्यान दें कि यदि आप यूनिकोड विशिष्ट वर्णों का उपयोग कर रहे हैं जिन्हें एकल कोडपृष्ठ में अनुवादित नहीं किया जा सकता है, तो आपको अपनी स्ट्रिंग को यूटीएफ 8 में परिवर्तित करना चाहिए।

फिर MD5 (PAnsiChar (YourTempString) को कॉल करें)।

जांचें कि आपकी lib में PWideChar या UNICODE घोषणाएं हो सकती हैं, इसे छोड़ने के लिए।

30

आपकी लाइब्रेरी यूनिकोड को अवगत नहीं है। बस इसे एक AnsiString पास करने के लिए पर्याप्त नहीं होगा क्योंकि यह शायद डेटा स्टोर करने के लिए आंतरिक रूप से तारों का उपयोग करता है।

आप, कि लाइब्रेरी को अपडेट करने की कोशिश इसे अद्यतन करने के लेखक के लिए प्रतीक्षा, या बस MessageDigest_5.pas इस्तेमाल कर सकते हैं कि डेल्फी 2009 के साथ जहाजों यह स्रोत \ Win32 \ साबुन \ wsdlimporter फ़ोल्डर में है, जिसे आपको या तो अपने पथ में जोड़ना होगा, या स्पष्ट रूप से इसे अपनी परियोजना में शामिल करना होगा।

कुछ नमूने यहां डेल्फी 2009 में इसे प्रयोग कोड है:

uses Types, MessageDigest_5; 

procedure TForm16.Edit1Change(Sender: TObject); 
var 
    MD5: IMD5; 
begin 
    MD5 := GetMD5; 
    MD5.Init; 
    MD5.Update(TByteDynArray(RawByteString(Edit1.Text)), Length(Edit1.Text)); 
    Edit2.Text := LowerCase(MD5.AsString); 
end; 

और आप व्यवसाय में हैं:

MD5 (123456) = e10adc3949ba59abbe56e057f20f883e

आप लपेट सकता है यदि आप चाहते थे तो एक साधारण फंक्शन कॉल में। यह महत्वपूर्ण है कि आप के बाद से RawByteString डाली एक TByteDynArray को कास्टिंग से पहले एक RawByteString लिए डाली सभी अतिरिक्त यूनिकोड वर्ण चला जाता है। अनुमोदित अगर संपादन में यूनिकोड वर्ण हैं तो आप खराब डेटा के साथ समाप्त हो सकते हैं।

आदि

मेरी क्रिसमस ध्यान रखें कि GetMD5 एक अंतरफलक लौटने रखें, तो यह संदर्भ में गिना है,!

+1

यहां पर कास्ट पूरी तरह से फर्जी हैं। आप तर्कसंगत रूप से यूनिकोडस्ट्रिंग को RawByteString पर नहीं डाल सकते हैं। और आप पूरी तरह से बाइट सरणी में RawByteString नहीं डाल सकते हैं।यह उत्तर बहुत बुरी तरह गलत है, और इस तरह गलती से मतदान किया गया कि इसे हटा दिया जाना चाहिए। सही समाधान TEncoding.GetBytes का उपयोग करता है। –

-3

जिम की जवाब में:

अगर हम बदलने

MD5.Update (TByteDynArray (RawByteString (Edit1.Text)), लम्बाई (Edit1.Text));

को

MD5.Update (TByteDynArray (RawByteString (Edit1.Text)), लम्बाई (RawByteString (Edit1.Text)));

चीनी वर्ण मौजूद होने पर बेहतर समर्थन करेगा।

5

कोई हैशिंग एल्गोरिदम पर टिप्पणी करने से पहले, इससे मदद मिलती है कि उनके पास अंतर्निहित अवधारणाओं और सिद्धांतों की कम से कम मौलिक समझ है। अंतहीन टाइपकास्टिंग पर ध्यान केंद्रित करने वाले सभी प्रतिक्रियाएं पूरी तरह से अधिक हैं, लेकिन इससे भी बदतर, परिणामस्वरूप अविश्वसनीय परिणाम होंगे यदि यूनिकोड स्ट्रिंग को धोया जा रहा है।

पहली बात यह समझने की आवश्यकता है कि हैशिंग और एन्क्रिप्शन एल्गोरिदम बाइट-स्तर पर काम करते हैं। इसका मतलब है कि वे परवाह नहीं करते हैं कि आप क्या कर रहे हैं या एन्क्रिप्टिंग कर रहे हैं। आप हैश पूर्णांक, वर्ण, सादा ASCII, पूर्ण यूनिकोड, बाइट्स, लॉन्गवर्ड इत्यादि आदि कर सकते हैं। एल्गोरिदम परवाह नहीं है।

तारों के साथ काम करते समय, केवल यह सुनिश्चित करना है कि आपके हैशिंग लाइब्रेरी का आंतरिक कार्य उस फ़ंक्शन में AnsiString देता है जो आपके परिणामी हैश को थकाता है। बस। यही बात मायने रखती है।

आपकी परियोजना के लिए आपका वास्तविक कोड (और चाहिए) सामान्य स्ट्रिंग इनपुट पर आधारित हो सकता है, जो डेल्फी 200 9 में यूनिकोडेस्ट्रिंग के लिए मानचित्र करता है। आपको उत्तर देने या कच्चे बाइटिंग करने के लिए कुछ भी टाइपकास्टिंग नहीं करना चाहिए। ऐसा करके, आप तुरंत टूटा हुआ हैश बनाते हैं यदि उपयोगकर्ता एएनएसआई चरित्र सेट के दायरे से बाहर कुछ भी हैश करने की कोशिश करता है। और हैशिंग की दुनिया में, एक टूटा हुआ हैश अविश्वसनीय और असुरक्षित दोनों है।

+0

कारण की आवाज़ के लिए धन्यवाद। +1। – mghie

1

यदि आपके पास wcrypt2.pas है, तो इस फ़ंक्शन का उपयोग करें।

function md5ansi(const Input: AnsiString): AnsiString; 
var 
    hCryptProvider: HCRYPTPROV; 
    hHash: HCRYPTHASH; 
    bHash: array[0..$7f] of Byte; 
    dwHashBytes: Cardinal; 
    pbContent: PByte; 
    i: Integer; 
begin 
    dwHashBytes := 16; 
    pbContent := Pointer(PAnsiChar(Input)); 
    Result := ''; 

    if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET) then 
    begin 
    if CryptCreateHash(hCryptProvider, CALG_MD5, 0, 0, @hHash) then 
    begin 
     if CryptHashData(hHash, pbContent, Length(Input) * sizeof(AnsiChar), 0) then 
     begin 
     if CryptGetHashParam(hHash, HP_HASHVAL, @bHash[0], @dwHashBytes, 0) then 
     begin 
      for i := 0 to dwHashBytes - 1 do 
      begin 
      Result := Result + AnsiString(Format('%.2x', [bHash[i]])); 
      end; 
     end; 
     end; 
     CryptDestroyHash(hHash); 
    end; 
    CryptReleaseContext(hCryptProvider, 0); 
    end; 

    Result := AnsiString(AnsiLowerCase(String(Result))); 
end; 
+0

@ जेडब्ल्यू किम, स्टैक ओवरफ्लो में आपका स्वागत है। कृपया, [faq] (http://stackoverflow.com/faq) पढ़ने में कुछ समय दें। यदि आपके पास फ़ोरम या न्यूजगॉप्स के साथ पिछले अनुभव हैं, तो आप देखेंगे कि साइट एक अलग तरीके से काम करती है। आप एक स्वीकृत उत्तर के साथ एक पुराने प्रश्न का उत्तर दे रहे हैं, इस प्रकार यह मान्य है, इसका उपयोग नहीं किया जाता है। स्रोत कोड प्रकाशित करने के लिए आपको इसे 4 कोड वर्णों से स्रोत कोड देखने के लिए इंडेंट करना होगा। :) – jachguate

संबंधित मुद्दे