2010-02-06 16 views
14

बड़ी फ़ाइल पर एक एकल एमडी 5 चेकसम की गणना करते समय, विभिन्न एमडी 5 मानों को एक ही मूल्य में जोड़ने के लिए आम तौर पर किस तकनीक का उपयोग किया जाता है? क्या आप उन्हें एक साथ जोड़ते हैं? मुझे किसी भी विशेष भाषा, पुस्तकालय या एपीआई में वास्तव में दिलचस्पी नहीं है जो यह करेगा; बल्कि मैं इसके पीछे की तकनीक में दिलचस्पी रखता हूं। क्या कोई समझा सकता है कि यह कैसे किया जाता है?एमडी 5 हैश मानों का मिश्रण

छद्म कोड में निम्नलिखित कलन विधि को देखते हुए:

MD5Digest X 
for each file segment F 
    MD5Digest Y = CalculateMD5(F) 
    Combine(X,Y) 

लेकिन Combine वास्तव में क्या करना होगा? क्या यह दो एमडी 5 digests एक साथ जोड़ता है, या क्या?

+0

आप ऐसा क्यों करना चाहते हैं? – AndiDog

+0

फ़ाइलों के लिए MD5 मानों की गणना करने के लिए जो स्मृति – channel72

+5

में फ़िट होने के लिए बहुत बड़े हैं, एमडी 5 में केवल 128-बिट स्थिति है जो गणना के दौरान 512-बिट फ़ाइल खंड को ट्रैक करती है; कौन परवाह करता है कि फ़ाइल कितनी बड़ी है? –

उत्तर

16

फ़ाइलों जो मन में स्मृति में फिट करने के लिए

इसी के साथ

बहुत बड़ी हैं के लिए MD5 मूल्यों की गणना करने में, आप दो MD5 हैश "गठबंधन" करने के लिए नहीं करना चाहती। के साथ MD5 कार्यान्वयन के साथ, आपके पास एक ऑब्जेक्ट है जो वर्तमान चेकसम स्थिति रखता है। तो आप किसी भी समय एमडी 5 चेकसम को निकाल सकते हैं, जो बहुत ही आसान है जब दो फाइलें हैं जो समान शुरुआत साझा करती हैं। बड़ी फाइलों के लिए, आप केवल डेटा में भोजन करते रहते हैं - अगर आपको याद है कि फ़ाइल को एक बार या ब्लॉक में है, तो राज्य को याद किया जाता है। दोनों मामलों में आपको एक ही हैश मिलेगा।

2

openssl पुस्तकालय आप एक चल रही हैश (SHA1/MD5) फिर जब आप आप Final विधि कॉल और यह उत्पादन अंतिम हैश होगा सभी डेटा को जोड़ना समाप्त कर करने के लिए डेटा के ब्लॉक को जोड़ने के लिए अनुमति देता है।

आप प्रत्येक व्यक्तिगत ब्लॉक पर md5 की गणना नहीं करते हैं, फिर इसे जोड़ें, बल्कि आप openssl लाइब्रेरी से चल रहे हैश विधि में डेटा जोड़ते हैं। यह आपको इनपुट डेटा आकार पर कोई सीमा नहीं होने के साथ सभी व्यक्तिगत डेटा ब्लॉक का md5 हैश देगा।

http://www.openssl.org/docs/crypto/md5.html#

2

इस सवाल के रूप में MD5 एल्गोरिदम किसी भी लम्बाई इनपुट लेता ज्यादा मतलब नहीं है। एक सभ्य पुस्तकालय में कार्य होना चाहिए ताकि आपको पूरे संदेश को एक ही समय में जोड़ना न पड़े क्योंकि संदेश क्रमशः एक हैश किए गए ब्लॉक में टूटा हुआ है, जिसमें ब्लॉक को संसाधित किया जा रहा है, केवल पिछले परिणामस्वरूप हैश पर निर्भर करता है पाश।

wikipedia article में छद्म कोड को एल्गोरिदम कैसे काम करता है इसका एक अवलोकन देना चाहिए।

1

अधिकांश पाचन गणना कार्यान्वयन आपको उन्हें छोटे ब्लॉक में डेटा फ़ीड करने की अनुमति देता है। आप कई एमडी 5 डाइजेस्ट को इस तरह से गठबंधन नहीं कर सकते कि परिणाम पूरे इनपुट के एमडी 5 के बराबर होगा। एमडी 5 कुछ पैडिंग करता है और अंतिम चरण में प्रसंस्कृत बाइट्स की संख्या का उपयोग करता है जो मूल इंजन राज्य को अंतिम पाचन मूल्य से अप्राप्य बनाता है।

+0

तो निम्नलिखित कई MD5 संयोजनों को कार्यान्वित करने का एक शानदार उदाहरण है? वह उपयोगकर्ता बस एक बड़ी फ़ाइल के व्यक्तिगत ब्लॉक के लिए एकाधिक व्यक्तिगत हैंश को जोड़ रहा है। http://www.postgresql-archive.org/md5-large-object-id-tp5866710p5869128.html –

+0

@ थॉर्स्टन: यह निश्चित आकार ब्लॉक के हैश रकम को संयोजित करने के लिए उपयुक्त हो सकता है और फिर एक एकल प्राप्त करने के लिए फिर से संयोजित स्ट्रिंग हैश हैश मूल्य परिणामी हैश योग सिर्फ वही नहीं है जो आपको मिलेगा अगर आपने पूरी फाइल को छोड़ दिया था। इसका मतलब यह है कि यदि आप इस तरह की गणना नहीं करते हैं, तो इसकी तुलना करने की आवश्यकता है, लेकिन यदि आप अपने प्रोटोकॉल को परिभाषित करते हैं तो आप एक निश्चित ब्लॉक आकार को परिभाषित करने और हमेशा अपने हैंश की गणना करने का निर्णय ले सकते हैं। हैश की गुणवत्ता मूल हैश फ़ंक्शन से भी बदतर नहीं है। Edonkey p2p फ़ाइल साझाकरण इस तरह हैश का उपयोग करता है। – x4u

6

एमडी 5 एक पुनरावृत्त एल्गोरिदम है। आपको छोटे एमडी 5 के टन की गणना करने की आवश्यकता नहीं है और फिर उन्हें किसी भी तरह गठबंधन करें। आप फ़ाइल के छोटे हिस्सों को पढ़ते हैं और उन्हें पाचन में जोड़ते हैं क्योंकि आप जा रहे हैं, इसलिए आपको पूरी फाइल को स्मृति में कभी भी याद नहीं रखना चाहिए। यहां एक जावा कार्यान्वयन है।

FileInputStream f = new FileInputStream(new File("bigFile.txt")); 
MessageDigest digest = MessageDigest.getInstance("md5"); 
byte[] buffer = new byte[8192]; 
int len = 0; 
while (-1 != (len = f.read(buffer))) { 
    digest.update(buffer,0,len); 
} 
byte[] md5hash = digest.digest(); 

और voila। आपके पास एक ही फाइल में एमडी 5 है, बिना किसी फाइल में पूरी फाइल को कभी भी।

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

byte[] interimHash = ((MessageDigest)digest.clone()).digest(); 

यह वास्तविक को प्रभावित नहीं करता पचाने वस्तु ताकि आप समग्र MD5 हैश के साथ काम करने के लिए जारी कर सकते हैं।

इसका भी ध्यान देने योग्य है कि MD5 और इस तरह के SHA-1 के रूप में सबसे परिस्थितियों में कुछ बेहतर के साथ प्रतिस्थापित किया जाना चाहिए (जैसे कि एक अविश्वसनीय स्रोत से फ़ाइल प्रामाणिकता की पुष्टि करने के रूप में) क्रिप्टोग्राफिक प्रयोजनों के लिए एक पुरानी हैश है लायक। गैर-क्रिप्टोग्राफिक उद्देश्यों के लिए, जैसे दो विश्वसनीय स्रोतों के बीच फ़ाइल अखंडता की पुष्टि करना, एमडी 5 अभी भी पर्याप्त है।

+0

मेरे पास MD5s को योग करने की आवश्यकता के लिए उपयोग-केस है। मैंने समानांतर में कई फाइलें पढ़ी हैं और पूरे संग्रह के लिए एक एकल चेकसम होना चाहते हैं (फाइलनाम वर्णमाला क्रम में फाइलें मानना)। – Synesso

1

हैश को गठबंधन करने के लिए यहां एक सी # तरीका है। आइए उपयोगकर्ता कोड को सरल बनाने के लिए विस्तार विधियां करें।

public static class MD5Append 
{ 
    public static int Append(this MD5 md5, byte[] data) 
    { 
     return md5.TransformBlock(data, 0, data.Length, data, 0); 
    } 

    public static void AppendFinal(this MD5 md5, byte[] data) 
    { 
     md5.TransformFinalBlock(data, 0, data.Length); 
    } 
} 

उपयोग:

using (var md5 = MD5CryptoServiceProvider.Create("MD5")) 
     { 
      md5.Initialize(); 

      var abcBytes = Encoding.Unicode.GetBytes("abc"); 
      md5.Append(abcBytes); 
      md5.AppendFinal(abcBytes); 

      var h1 = md5.Hash; 

      md5.Initialize(); // mandatory 
      var h2= md5.ComputeHash(Encoding.Unicode.GetBytes("abcabc")); 

      Console.WriteLine(Convert.ToBase64String(h1)); 
      Console.WriteLine(Convert.ToBase64String(h2)); 
     } 

h1 और h2 ही हैं। बस।

+0

SO, user1326493 में आपका स्वागत है, और आपके उत्तर के लिए धन्यवाद। – Brian

1

एंडीडॉग के उत्तर के लिए एक पायथन 2.7 उदाहरण। फ़ाइल 123.txt में कई लाइनें हैं।

>>> import hashlib 
>>> md5_A, md5_B, md5_C = hashlib.md5(), hashlib.md5(), hashlib.md5() 
>>> with open('123.txt', 'r') as f_r: 
...  md5_A.update(f_r.read()) # read whole contents 
... 
>>> with open('123.txt', 'r') as f_r: 
...  for line in f_r: # read file line by line 
...   md5_B.update(line) 
... 
>>> with open('123.txt', 'r') as f_r: 
...  while True: # read file chunk by chunk 
...   chunk = f_r.read(10) 
...   if not chunk: break 
...   md5_C.update(chunk) 
... 
>>> md5_A.hexdigest() 
'5976ddfa19bc2e1669ac3bd836101f58' 
>>> md5_B.hexdigest() 
'5976ddfa19bc2e1669ac3bd836101f58' 
>>> md5_C.hexdigest() 
'5976ddfa19bc2e1669ac3bd836101f58' 

बड़ी फ़ाइल है कि स्मृति में फिट नहीं कर सकते के लिए, यह लाइन या हिस्सा द्वारा हिस्सा द्वारा लाइन पढ़ा जा सकता है। Diff कमांड विफल होने पर इस MD5 का एक उपयोग दो बड़ी फ़ाइलों की तुलना कर रहा है।

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