किसी फ़ाइल के लिए MD5 चेकसम की गणना करें


334

मैं पीडीएफ फाइल से टेक्स्ट पढ़ने के लिए iTextSharp का उपयोग कर रहा हूं । हालाँकि, कई बार मैं टेक्स्ट नहीं निकाल सकता, क्योंकि पीडीएफ फाइल में केवल चित्र होते हैं। मैं एक ही पीडीएफ फाइलों को रोज डाउनलोड करता हूं, और मैं देखना चाहता हूं कि पीडीएफ को संशोधित किया गया है या नहीं। यदि पाठ और संशोधन तिथि प्राप्त नहीं की जा सकती है, तो क्या एमडी 5 चेकसम यह बताने का सबसे विश्वसनीय तरीका है कि क्या फ़ाइल बदल गई है?

यदि यह है, तो कुछ कोड नमूनों की सराहना की जाएगी, क्योंकि मुझे क्रिप्टोग्राफी के साथ बहुत अनुभव नहीं है।


जवाबों:


773

यह System.Security.Cryptography.MD5 का उपयोग करके बहुत सरल है :

using (var md5 = MD5.Create())
{
    using (var stream = File.OpenRead(filename))
    {
        return md5.ComputeHash(stream);
    }
}

(मेरा मानना ​​है कि वास्तव में एमडी 5 कार्यान्वयन का उपयोग करने की आवश्यकता नहीं है, लेकिन मैं अभी भी वैसे भी ऐसा करूँगा।)

आप बाद में परिणामों की तुलना कैसे करते हैं यह आपके ऊपर है; आप उदाहरण के लिए बाइट सरणी को बेस 64 में बदल सकते हैं, या बाइट की सीधे तुलना कर सकते हैं। (बस ध्यान रखें कि सरणियां ओवरराइड नहीं करती हैं Equals। बेस 64 का उपयोग करना सही पाने के लिए सरल है, लेकिन थोड़ा कम कुशल है यदि आप वास्तव में केवल हैश की तुलना करने में रुचि रखते हैं।)

यदि आपको एक स्ट्रिंग के रूप में हैश का प्रतिनिधित्व करने की आवश्यकता है, तो आप इसका उपयोग करके इसे हेक्स में बदल सकते हैं BitConverter:

static string CalculateMD5(string filename)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(filename))
        {
            var hash = md5.ComputeHash(stream);
            return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        }
    }
}

251
यदि आप चाहते हैं "मानक" देख md5, तो आप कर सकते हैं: वापसीBitConverter.ToString(md5.ComputeHash(stream)).Replace("-","").ToLower();
एक्विनास

78
MD5 System.Security.Cryptography में है - बस अधिक जानकारी को धरातल पर लाने के लिए।
हंस

6
@KalaJ: यदि आप जानबूझकर छेड़छाड़ करने की कोशिश कर रहे हैं, तो CRC32 पूरी तरह से अनुचित है। यदि आप केवल डेटा ट्रांसफर विफलताओं के बारे में बात कर रहे हैं, तो यह ठीक है। व्यक्तिगत रूप से मैं शायद SHA-256 का उपयोग आदत से बाहर कर दूंगा :) मुझे .NET offhand में CRC32 के समर्थन के बारे में पता नहीं है, लेकिन आप संभवतः इसे जितनी जल्दी हो सके खोज सकते हैं :)
जॉन स्कीट

12
@ अक्विनस मुझे लगता .Replace("-", String.Empty)है कि एक बेहतर दृष्टिकोण है। मैं एक घंटे के डिबग सत्र के माध्यम से चला गया क्योंकि फ़ाइल हैश में उपयोगकर्ता इनपुट की तुलना करते समय मुझे गलत परिणाम मिलते हैं।
फब्बू

7
@ wuethrich44, मुझे लगता है कि आपको जो समस्या हो रही है अगर आप एक्विनास कमेंट वर्बेटिम में कोड कॉपी / पेस्ट करते हैं; मैं एक ही बात नोटिस करने के लिए हुआ। कच्चे HTML में "खाली" उद्धरणों के बीच दो अदृश्य अक्षर हैं - एक "शून्य-चौड़ाई वाला गैर-योजक" और एक यूनिकोड "शून्य चौड़ाई का स्थान"। मुझे नहीं पता कि यह मूल टिप्पणी में था या एसओ को यहां दोष देना है।
क्रिस सिमंस

66

यह मेरा इसे करने का तरीका है:

using System.IO;
using System.Security.Cryptography;

public string checkMD5(string filename)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(filename))
        {
            return Encoding.Default.GetString(md5.ComputeHash(stream));
        }
    }
}

2
मैंने आपको अपवित्र किया क्योंकि अधिक लोगों को इस तरह की चीजें करने की जरूरत है।
क्रीथिक

6
मुझे लगता है कि usingब्लॉक की अदला-बदली उपयोगी होगी, क्योंकि एक फ़ाइल खोलना शायद विफल होना है। जल्दी / तेज गति से विफल होना आपको ऐसे परिदृश्यों में एमडी 5 उदाहरण बनाने (और नष्ट करने) के लिए आवश्यक संसाधनों को बचाता है। इसके अलावा, आप पहले के ब्रेसिज़ को छोड़ सकते हैं usingऔर पठनीयता को खोए बिना इंडेंटेशन के स्तर को बचा सकते हैं ।
पालेक

10
यह 16 बाइट्स को लंबे समय तक 16 वर्णों के एक स्ट्रिंग में परिवर्तित करता है, न कि अपेक्षित 32 वर्ण हेक्स मान को।
19

3
यह कोड अपेक्षित परिणाम (अनुमानित उम्मीद) का उत्पादन नहीं करता है। @NiKiZe
Nick

1
@ प्रश्न, मैं केवल सामान्य विचार को बढ़ावा देने की कोशिश कर रहा था कि बयान मामलों के उपयोग के घोंसले का क्रम। कहीं और, अंतर महत्वपूर्ण हो सकता है। असफलता का जल्द पता लगाने की आदत क्यों नहीं? मैं मानता हूं, हालांकि, इस विशिष्ट स्निपेट में, आदत लगभग कोई लाभ नहीं लाती है।
पलक

7

मुझे पता है कि यह प्रश्न पहले ही उत्तर दे दिया गया था, लेकिन यह वह है जो मैं उपयोग करता हूं:

using (FileStream fStream = File.OpenRead(filename)) {
    return GetHash<MD5>(fStream)
}

जहां गेटश :

public static String GetHash<T>(Stream stream) where T : HashAlgorithm {
    StringBuilder sb = new StringBuilder();

    MethodInfo create = typeof(T).GetMethod("Create", new Type[] {});
    using (T crypt = (T) create.Invoke(null, null)) {
        byte[] hashBytes = crypt.ComputeHash(stream);
        foreach (byte bt in hashBytes) {
            sb.Append(bt.ToString("x2"));
        }
    }
    return sb.ToString();
}

शायद सबसे अच्छा तरीका नहीं है, लेकिन यह आसान हो सकता है।


मैंने आपके GetHash फ़ंक्शन में एक छोटा सा परिवर्तन किया है। मैंने इसे एक विस्तार विधि में बदल दिया है और प्रतिबिंब कोड हटा दिया है।
लेस्ली मार्शल

3
public static String GetHash<T>(this Stream stream) where T : HashAlgorithm, new() { StringBuilder sb = new StringBuilder(); using (T crypt = new T()) { byte[] hashBytes = crypt.ComputeHash(stream); foreach (byte bt in hashBytes) { sb.Append(bt.ToString("x2")); } } return sb.ToString(); }
लेस्ली मार्शल

यह वास्तव में काम किया .... धन्यवाद!। मैंने लंबे समय तक ऑनलाइन रिजल्ट देखने के लिए खर्च किया, जो सामान्य 32 char md5 स्ट्रिंग पैदा करेगा, जिसकी मैंने अपेक्षा की थी। यह थोड़ा और जटिल है जिसे मैं पसंद करूंगा लेकिन यह निश्चित रूप से काम करता है।
Troublesum

1
@LeslieMarshall आप तो आप बल्कि अंत की स्थिति में इसे छोड़ने से धारा स्थान पुनर्स्थापित करना चाहिए एक विस्तार पद्धति के रूप में उपयोग करने के लिए जा रहे हैं
MikeT

3

यहाँ थोड़ा सरल संस्करण है जो मुझे मिला। यह पूरी फाइल को एक बार में पढ़ता है और केवल एक usingनिर्देश की आवश्यकता होती है ।

byte[] ComputeHash(string filePath)
{
    using (var md5 = MD5.Create())
    {
        return md5.ComputeHash(File.ReadAllBytes(filePath));
    }
}

50
उपयोग करने ReadAllBytesका नकारात्मक पक्ष यह है कि यह पूरी फ़ाइल को एक ही सरणी में लोड करता है। यह 2 GiB से बड़ी फ़ाइलों के लिए बिल्कुल भी काम नहीं करता है और मध्यम आकार की फ़ाइलों के लिए भी GC पर बहुत अधिक दबाव डालता है। जॉन का जवाब केवल थोड़ा और अधिक जटिल है, लेकिन इन समस्याओं से ग्रस्त नहीं है। इसलिए मैं तुम्हारा जवाब पसंद करता हूं।
कोडइन्चोस

1
usingपहले घुंघराले ब्रेसिज़ के साथ एक दूसरे के बाद एस में रखो using (var md5 = MD5.Create()) using (var stream = File.OpenRead(filename))आप अनावश्यक खरोज के बिना प्रति पंक्ति का उपयोग कर एक देता है।
NiKiZe

3
@NiKiZe आप पूरे कार्यक्रम को एक पंक्ति में रख सकते हैं और सभी इंडेंटेशन को समाप्त कर सकते हैं। तुम भी चर नामों के रूप में XYZ का उपयोग कर सकते हैं! दूसरों को क्या फायदा है?
डेरेक जॉनसन

@DerekJohnson जिस बिंदु को मैं बनाने की कोशिश कर रहा था, वह शायद "और केवल एक ही usingनिर्देश की आवश्यकता थी ।" वास्तव में सब कुछ स्मृति में पढ़ने का एक अच्छा कारण नहीं था। अधिक प्रभावी दृष्टिकोण डेटा में स्ट्रीम करना है ComputeHash, और यदि संभव हो तो usingकेवल इसका उपयोग किया जाना चाहिए, लेकिन मैं पूरी तरह से समझ सकता हूं कि क्या आप इंडेंटेशन के अतिरिक्त स्तर से बचना चाहते हैं।
NiKiZe

3

मुझे पता है कि मुझे पार्टी करने में देर हो गई है लेकिन वास्तव में समाधान को लागू करने से पहले परीक्षण किया गया।

मैंने इनबिल्ट एमडी 5 क्लास और भी md5sum.exe के खिलाफ टेस्ट किया । मेरे मामले में इनबिल्ट क्लास ने 13 सेकंड का समय लिया जहाँ md5sum.exe भी हर रन में 16-18 सेकंड के आसपास था।

    DateTime current = DateTime.Now;
    string file = @"C:\text.iso";//It's 2.5 Gb file
    string output;
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(file))
        {
            byte[] checksum = md5.ComputeHash(stream);
            output = BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
            Console.WriteLine("Total seconds : " + (DateTime.Now - current).TotalSeconds.ToString() + " " + output);
        }
    }

2

और अगर आपको यह देखने के लिए एमडी 5 की गणना करने की आवश्यकता है कि क्या यह एक एज़्योर ब्लॉब के एमडी 5 से मेल खाता है, तो यह एसओ प्रश्न और उत्तर सहायक हो सकता है: एज़ुरे पर अपलोड की गई एमडी 5 हैश स्थानीय मशीन पर एक ही फाइल के साथ मेल नहीं खाता


अगर आपको लगता है कि जवाब बढ़िया नहीं है, तो डाउनवोटिंग ठीक है। हालांकि, एक टिप्पणी को छोड़ने के कारणों का वर्णन करते हुए समय के साथ उत्तर सुधारने में मदद मिलेगी। एक उत्तर को बेहतर बनाने के लिए सुझावों के साथ एक टिप्पणी छोड़ कर आप स्टैक ओवरफ्लो में बेहतर योगदान दे सकते हैं। धन्यवाद!
मैनफ्रेड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.