لماذا هذين الملفين التجزئة بنفس القيمة عندما أستخدم موعد الذاكرة؟

StackOverflow https://stackoverflow.com/questions/1715362

  •  19-09-2019
  •  | 
  •  

سؤال

أنا أكتب روتين AC # الذي يخلق التجزئة من ملفات JPG. إذا مررت في صفيف بايت إلى كائن SHA512 الخاص بي، فاحصل على السلوك المتوقع، ومع ذلك، إذا مررت في دفق ذاكرة الملفين دائما التجزئة بنفس القيمة.

مثال 1:

        SHA512 mySHA512 = SHA512.Create();

        Image img1 = Image.FromFile(@"d:\img1.jpg");
        Image img2 = Image.FromFile(@"d:\img2.jpg");
        MemoryStream ms1 = new MemoryStream();
        MemoryStream ms2 = new MemoryStream();

        img1.Save(ms1, ImageFormat.Jpeg);
        byte[] buf1 = ms1.GetBuffer();
        byte[] hash1 = mySHA512.ComputeHash(buf1);

        img2.Save(ms2, ImageFormat.Jpeg);
        byte[] buf2 = ms2.GetBuffer();
        byte[] hash2 = mySHA512.ComputeHash(buf2);

        if (Convert.ToBase64String(hash1) == Convert.ToBase64String(hash2))
            MessageBox.Show("Hashed the same");
        else
            MessageBox.Show("Different hashes");

التي تنتج "تجزئة مختلفة". ولكن واحدة من الزائد من طريقة الأسلوب Computehash يأخذ كائن دفق وفي استخدام ذلك. عندما أفعل:

        SHA512 mySHA512 = SHA512.Create();

        Image img1 = Image.FromFile(@"d:\img1.jpg");
        Image img2 = Image.FromFile(@"d:\img2.jpg");
        MemoryStream ms1 = new MemoryStream();
        MemoryStream ms2 = new MemoryStream();

        img1.Save(ms1, ImageFormat.Jpeg);
        byte[] hash1 = mySHA512.ComputeHash(ms1);

        img2.Save(ms2, ImageFormat.Jpeg);
        byte[] hash2 = mySHA512.ComputeHash(ms2);

        if (Convert.ToBase64String(hash1) == Convert.ToBase64String(hash2))
            MessageBox.Show("Hashed the same");
        else
            MessageBox.Show("Different hashes");

التي تنتج "هاش نفسه".

ما الذي يحدث هنا أنا في عداد المفقودين؟

هل كانت مفيدة؟

المحلول

أنت لا تقم بترتيب مخصصاتك الخاصة بك، لذلك يتم حساب التجزئة من سلسلة فارغة من البايتات. يستخدم

ms1.Position = 0;
ms2.Position = 0;

بعد الاتصال Save.

ملاحظة أخرى أخرى: لا تستخدم GetBuffer في هذا الطريق. يستخدم ToArray والتي ستمنحك صفيف بايت بنفس الحجم مثل طول الدفق - GetBuffer إرجاع المخزن المؤقت الخام الذي سيكون (عادة) لديه بعض الحشو، والتي لن ترغب في استخدامها عن طريق الخطأ. يمكنك استخدام GetBuffer إذا كنت تتأكد من أنك تستخدم فقط الجزء ذو الصلة منه، بالطبع - يتجنب ذلك إنشاء نسخة جديدة من البيانات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top