একটি ফাইলের জন্য MD5 চেকসাম গণনা করুন


334

আমি ব্যাবহার করছি পিডিএফ ফাইল থেকে পাঠ্যটি পড়তে আইটেক্সটশার্প । যাইহোক, এমন সময় আছে যা আমি পাঠ্য আহরণ করতে পারি না, কারণ পিডিএফ ফাইলটিতে কেবল চিত্র থাকে। আমি প্রতিদিন একই পিডিএফ ফাইলগুলি ডাউনলোড করি এবং পিডিএফ সংশোধন করা হয়েছে কিনা তা দেখতে চাই। যদি পাঠ্য এবং পরিবর্তনের তারিখটি পাওয়া যায় না, তবে MD5 চেকসামটি ফাইলের পরিবর্তন হয়েছে কিনা তা বলার সবচেয়ে নির্ভরযোগ্য উপায়?

যদি এটি হয় তবে কিছু কোডের নমুনাগুলি প্রশংসা হবে, কারণ আমার কাছে ক্রিপ্টোগ্রাফি নিয়ে খুব বেশি অভিজ্ঞতা নেই।


উত্তর:


773

এটি সিস্টেম.সিকিউরিটি.ক্রিপ্টোগ্রাফি.এমডি 5 ব্যবহার করে খুব সহজ :

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

(আমি বিশ্বাস করি যে আসলে ব্যবহৃত MD5 বাস্তবায়ন বিন্যস্ত হতে হবে না, কিন্তু আমি সম্ভবত এখনও এত যাহাই হউক না কেন করতে চাই।)

পরবর্তী ফলাফলগুলি কীভাবে তুলনা করবেন তা আপনার উপর নির্ভর করে; আপনি উদাহরণস্বরূপ বাইট অ্যারে বেস 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
আপনি যদি "স্ট্যান্ডার্ড" খুঁজছেন এমডি 5 চান, আপনি এটি করতে পারেন: BitConverter.ToString(md5.ComputeHash(stream)).Replace("-","").ToLower();
ফিরুন

78
MD5 সিস্টেমে রয়েছে ecসিকিউরিটি Cক্রিপ্টোগ্রাফি - কেবল আরও তথ্যের উপর নজর রাখার জন্য।
হান্স

6
@ কালাজে: আপনি যদি ইচ্ছাকৃতভাবে ছন্দবদ্ধ হওয়ার চেষ্টা করছেন, তবে সিআরসি 32 সম্পূর্ণ অনুপযুক্ত। আপনি যদি কেবল ডেটা স্থানান্তর ব্যর্থতা চিহ্নিত করার কথা বলছেন তবে তা ঠিক। ব্যক্তিগতভাবে আমি সম্ভবত অভ্যাসের বাইরে SHA-256 ব্যবহার করতাম :)। নেট অফহেন্ডে সিআরসি 32 এর সমর্থন সম্পর্কে আমি জানি না, তবে আপনি সম্ভবত এটি হিসাবে যত তাড়াতাড়ি অনুসন্ধান করতে পারেন :)
জোন স্কিট

12
@ অ্যাকুইনাস আমি মনে করি .Replace("-", String.Empty)এটি একটি আরও ভাল পদ্ধতির। আমি এক ঘন্টা ডিবাগ সেশনটি পেরিয়েছি কারণ একটি ফাইল ইন হ্যাশের সাথে ইনপুট তুলনা করার সময় আমি ভুল ফলাফল পেয়েছি।
ফেবু

7
@ wuethrich44, আমি মনে করি আপনি যদি সমস্যাটি কোডটি কপিরাইট করে / অ্যাকুইনাস কমেন্ট ভারব্যাটিমে পেস্ট করেন তবে আপনার সমস্যা হচ্ছে having আমি একই জিনিস লক্ষ্য করতে ঘটেছে। দুটি অদৃশ্য অক্ষর রয়েছে - কাঁচা এইচটিএমএলের "খালি" উদ্ধৃতিগুলির মধ্যে একটি "শূন্য-প্রস্থের নন-জয়দার" এবং একটি ইউনিকোড "শূন্য প্রস্থের স্থান"। আমি জানি না এটি আসল মন্তব্যে ছিল বা এসওকে যদি এখানে দোষ দেওয়া হয়।
ক্রিস সিমন্স

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 অক্ষর হেক্স মান নয়।
নিকিজে

3
এই কোডটি প্রত্যাশিত ফলাফল তৈরি করে না (অনুমানিত প্রত্যাশা)। @ নাইকিজে
নিক

1
@ কিউবিলসোম, আমি কেবল সাধারণ ধারণাটি প্রচারের চেষ্টা করছিলাম যে বিবৃতি ব্যবহারের বাসা বাঁধার ক্রমটি গুরুত্বপূর্ণ। অন্য কোথাও, পার্থক্যটি উল্লেখযোগ্য হতে পারে। ব্যর্থতা শনাক্ত করার অভ্যাসটি তাড়াতাড়ি অনুশীলন করবেন না কেন? আমি সম্মত হই, যদিও, এই নির্দিষ্ট স্নিপেটে, অভ্যাসটি প্রায় কোনও লাভ করে না।
পলেক

7

আমি জানি এই প্রশ্নের উত্তর ইতিমধ্যে দেওয়া হয়েছিল, তবে আমি এটি ব্যবহার করি:

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

কোথায় GetHash :

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();
}

সম্ভবত সবচেয়ে ভাল উপায় না, তবে এটি কার্যকর হতে পারে।


আমি আপনার গেটহ্যাশ ফাংশনে একটি ছোট পরিবর্তন করেছি। আমি এটিকে একটি এক্সটেনশন পদ্ধতিতে পরিণত করেছি এবং প্রতিবিম্ব কোডটি সরিয়েছি।
লেসলি মার্শাল

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 চর এমডি 5 স্ট্রিং উত্পাদন করে। এটি একটু বেশি জটিল যা আমি পছন্দ করি তবে এটি অবশ্যই কাজ করে।
Troublesum

1
@ লেসলি মার্শাল যদি আপনি এটি কোনও এক্সটেনশন পদ্ধতি হিসাবে ব্যবহার করতে চলেছেন তবে আপনার স্ট্রিমের অবস্থানটি শেষ অবস্থানে রেখে যাওয়ার পরিবর্তে পুনরায় সেট করা উচিত
মাইকটি

3

আমি এখানে পেয়েছি যে একটি সামান্য সহজ সংস্করণ। এটি পুরো ফাইলটি একসাথে পড়ে এবং কেবলমাত্র একটি একক usingনির্দেশিকা প্রয়োজন।

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

50
ব্যবহারের খারাপ দিকটি ReadAllBytesহ'ল এটি সম্পূর্ণ ফাইলটি একটি একক অ্যারেতে লোড করে। এটি 2 GiB এর চেয়ে বড় ফাইলগুলির জন্য মোটেও কাজ করে না এবং মাঝারি আকারের ফাইলগুলির জন্য এমনকি জিসির উপরও প্রচুর চাপ ফেলে। জনের উত্তরটি কিছুটা জটিল, তবে এই সমস্যাগুলিতে ভোগেনা। সুতরাং আমি আপনার উত্তর তার চেয়ে পছন্দ করি।
কোডসইনচাউস

1
usingপ্রথম কোঁকড়া ধনুর্বন্ধনী সঙ্গে একে অপরের পরে রাখুন using (var md5 = MD5.Create()) using (var stream = File.OpenRead(filename))আপনাকে অপ্রয়োজনীয় ইন্ডেন্টেশন ছাড়াই প্রতি লাইন ব্যবহার করে এক করে দেয়।
নাইকিজে

3
@ নাইকিজে আপনি একটি সম্পূর্ণ প্রোগ্রাম এক লাইনে রেখে সমস্ত ইন্ডেন্টেশন দূর করতে পারেন। আপনি এমনকি পরিবর্তনশীল নাম হিসাবে XYZ ব্যবহার করতে পারেন! অন্যের কী লাভ?
ডেরেক জনসন

@ ডেরেক জনসন যে বিষয়টি আমি তৈরি করার চেষ্টা করছিলাম সেটি সম্ভবত এটি ছিল "এবং এর জন্য কেবল একটি usingনির্দেশিকা প্রয়োজন " " মেমরির মধ্যে সমস্ত কিছু পড়ার পক্ষে আসলেই কোনও ভাল কারণ ছিল না। আরও কার্যকর পদ্ধতির মধ্যে ডেটা প্রবাহিত করা ComputeHashএবং যদি সম্ভব হয় usingতবে কেবল এটিই ব্যবহার করা উচিত, তবে আপনি অতিরিক্ত স্তরের ইন্ডেন্টেশন এড়াতে চান কিনা তা আমি পুরোপুরি বুঝতে পারি।
নিককিজে

3

আমি জানি যে আমি পার্টি করতে দেরি করেছি তবে সমাধানটি বাস্তবায়নের আগে পরীক্ষার কাজ করেছি।

আমি MD5 বর্গ Inbuilt এবং বিরুদ্ধে পরীক্ষা সম্পাদন করেছেন md5sum.exe । আমার ক্ষেত্রে ইনবিল্ট ক্লাসটি 13 সেকেন্ড নিয়েছিল যেখানে এমডি 5sum.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 গণনা করতে হয় এটি কোনও অ্যাজুরে ব্লবের MD5 এর সাথে মেলে কিনা তা দেখার জন্য, তাহলে এই এই প্রশ্নোত্তরটি কার্যকর হতে পারে: অ্যাজুরেতে আপলোড করা ব্লাবের MD5 হ্যাশ স্থানীয় মেশিনে একই ফাইলের সাথে মেলে না


আপনি যদি মনে করেন যে উত্তরটি দুর্দান্ত না, তবে ডাউনভোটিং ভাল। তবে ডাউনওয়েটের কারণগুলি বর্ণনা করে একটি মন্তব্য দেওয়া সময়ের সাথে সাথে উত্তরগুলি উন্নত করতে সহায়তা করবে। উত্তরের উন্নতির জন্য পরামর্শ সহ একটি মন্তব্য রেখে আপনি স্ট্যাক ওভারফ্লোতে আরও অবদান রাখতে পারেন। ধন্যবাদ!
ম্যানফ্রেড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.