2011-04-19 18 views
23

मैं सर्वर और क्लाइंट कंप्यूटर के बीच फ़ाइल की सामग्री को सत्यापित करने के लिए एक बाइनरी फ़ाइल (FLV/f4v, आदि) का चेकसम बनाने की कोशिश कर रहा हूं। क्लाइंट कंप्यूटर पर चल रहा एप्लिकेशन पाइथन-आधारित है, जबकि सर्वर PHP का उपयोग कर रहा है।एमडी 5 हैश विसंगति?

$fh = fopen($filepath, 'rb'); 
$contents = fread($fh, filesize($filepath)); 
$checksum = md5(base64_encode($contents)); 
fclose($fh); 

अजगर कोड इस प्रकार है:: इस प्रकार

PHP कोड है

def _get_md5(filepath): 
    fh = open(filepath, 'rb') 
    md5 = hashlib.md5() 
    md5.update(f.read().encode('base64')) 
    checksum = md5.hexdigest() 
    f.close() 
    return checksum 
विशेष फ़ाइल मैं परीक्षण कर रहा हूँ पर

, PHP और अजगर MD5 हैश तार इस प्रकार हैं, क्रमश:

cfad0d835eb88e5342e843402cc42764 
0a96e9cc3bb0354d783dfcb729248ce0 

सर्वर सेंटोस चला रहा है, जबकि क्लाइंट एक मैकोज़क्स वातावरण है। मैं यह समझने में किसी भी मदद की सराहना करता हूं कि दोनों अलग हैंश परिणाम क्यों उत्पन्न कर रहे हैं, या अगर मैंने इसे अनदेखा किया है (मैं पाइथन के लिए अपेक्षाकृत नया हूं ...)। धन्यवाद!

[पोस्ट मॉर्टम: समस्या अंततः पायथन और PHP की बेस 64 एन्कोडिंग किस्मों के बीच का अंतर था। एमडी 5 दो स्क्रिप्टिंग प्लेटफॉर्म (कम से कम .hexdigest() का उपयोग पाइथन में करता है)।]

+1

मुझे पूरा यकीन है कि फाइल का बेस 64 प्रतिनिधित्व अलग है, एमडी 5 एल्गोरिदम नहीं, क्या आप इसे देख सकते हैं? – htf

+7

बेस 64 के साथ परेशान क्यों है? क्यों कच्चे बाइनरी md5 नहीं? –

+2

किसी भी कारण से आप बेस 64-एन्कोडिंग फ़ाइल की सामग्री पहले कर रहे हैं? एमडी 5 कार्य खुशी से कच्चे बाइनरी डेटा पर भी चले जाएंगे। जैसा कि एचटीएफ सुझाव देता है, समीकरण से बेस 64 हटाएं और देखें कि क्या होता है। यदि, किसी भी कारण से, पायथन और PHP लाइन बेस 64 डेटा (जैसे ईमेल सम्मिलन के लिए) को लपेटती है, और एक अलग लपेट बिंदु चुना है, जो हैश को फेंक देगा और आप कभी नहीं जानते क्योंकि आप बेस 64 आउटपुट की जांच नहीं कर रहे हैं समानता के लिए पहले। –

उत्तर

25

मैं नहीं बल्कि ग्रहण करेंगे कि बेस 64 कार्यान्वयन भिन्न होते हैं।

संपादित

पीएचपी:

php -r 'var_dump(base64_encode(str_repeat("x", 10)));' 
string(16) "eHh4eHh4eHh4eA==" 

अजगर (ध्यान दें अनुगामी newline):

>>> ("x" * 10).encode('base64') 
'eHh4eHh4eHh4eA==\n' 
+6

और प्रश्न की टिप्पणियां एक और महत्वपूर्ण बिंदु लाती हैं: आप ' यदि आप हैश चाहते हैं, तो बेस 64 की आवश्यकता है, आप स्ट्रिंग को सीधे हैश कर सकते हैं। – soulmerge

4

समस्या यह प्रतीत होती है कि फ़ाइल बेस आपके बेस -64-एन्कोडिंग, बाइनरी डेटा की संरचना को बदल रहा है , php I बेली में यह आधार_64 फ़ाइल को एन्कोड नहीं करता है।

def md5_file(filename): 
    //MD5 Object 
    crc = hashlib.md5() 
    //File Pointer Object 
    fp = open(filename, 'rb') 

    //Loop the File to update the hash checksum 
    for i in fp: 
     crc.update(i) 

    //Close the resource 
    fp.close() 

    //Return the hash 
    return crc.hexdigest() 

और PHP के भीतर md5_file का उपयोग और देखते हैं कि यदि उसके अनुसार काम करता है:

इस एक जाना दे।

अजगर से लिया: http://www.php2python.com/wiki/function.md5-file/

4

पायथन ने .encode का उपयोग करते समय स्ट्रिंग में एक नई लाइन '\ n' जोड़ दी है, इसलिए एमडी 5 फ़ंक्शन में इनपुट स्ट्रिंग अलग-अलग हैं। पाइथन बग ट्रैकर में This समस्या विस्तार से बताती है। इसके बारे में नीचे देखें:

>>> import base64 
>>> s='I am a string' 
>>> s.encode('base64') 
'SSBhbSBhIHN0cmluZw==\n' 
>>> base64.b64encode(s) 
'SSBhbSBhIHN0cmluZw==' 
>>> s.encode('base64')== base64.b64encode(s)+'\n' 
True 
संबंधित मुद्दे