هل يمكن لأي شخص أن يشرح التحويل من مجموعة البايت إلى سلسلة سداسية؟

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

  •  20-08-2019
  •  | 
  •  

سؤال

لقد بدأت مؤخرًا في النظر إلى تجزئة MD5 (في Java) وبينما وجدت خوارزميات وطرقًا لمساعدتي في تحقيق ذلك، إلا أنني أتساءل كيف يعمل بالفعل.

لأحد، وجدت ما يلي من عنوان URL هذا:

private static String convertToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do {
            if ((0 <= halfbyte) && (halfbyte <= 9))
                buf.append((char) ('0' + halfbyte));
            else
                buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        }
    return buf.toString();
}

لم أجد أي حاجة لاستخدام تبديل البت في Java، لذا فأنا متردد قليلاً في ذلك.شخص لطيف بما يكفي ليوضح (بعبارات بسيطة) كيف يقوم الكود أعلاه بالضبط بالتحويل؟">>>"؟

لقد وجدت أيضًا حلولًا أخرى على StackOverflow، مثل هنا و هنا, ، والذي يستخدم BigInteger بدلاً من ذلك:

try {
   String s = "TEST STRING";
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   md5.update(s.getBytes(),0,s.length());
   String signature = new BigInteger(1,md5.digest()).toString(16);
   System.out.println("Signature: "+signature);

} catch (final NoSuchAlgorithmException e) {
   e.printStackTrace();
}

لماذا يعمل هذا أيضًا، وما هي الطريقة الأكثر كفاءة؟

شكرا على وقتك.

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

المحلول

private static String convertToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {

حتى هذه اللحظة...ما عليك سوى الإعداد الأساسي وبدء حلقة لتصفح كافة البايتات في المصفوفة

        int halfbyte = (data[i] >>> 4) & 0x0F;

البايتات عند تحويلها إلى رقم سداسي عشري هي رقمان سداسي عشري أو 8 أرقام ثنائية اعتمادًا على القاعدة التي تنظر إليها فيها.العبارة المذكورة أعلاه تزيح الـ 4 بتات العالية للأسفل (>>> هي إزاحة لليمين غير موقعة) ومنطقية AND مع 0000 1111 بحيث تكون النتيجة عددًا صحيحًا يساوي الـ 4 بتات العالية للبايت (الرقم السداسي الأول).

لنفترض أن 23 كان مدخلاً، وهذا هو 0001 0111 في النظام الثنائي.يجعل هذا التحول منطقيًا ويخفي هذا إلى 0000 0001.

        int two_halfs = 0;
        do {

يؤدي هذا فقط إلى إعداد حلقة do/while ليتم تشغيلها مرتين

            if ((0 <= halfbyte) && (halfbyte <= 9))
                buf.append((char) ('0' + halfbyte));
            else
                buf.append((char) ('a' + (halfbyte - 10)));

نعرض هنا الرقم السداسي الفعلي، وذلك باستخدام الصفر أو الحرف كنقطة بداية والانتقال إلى الحرف الصحيح.تغطي عبارة if الأولى جميع الأرقام من 0 إلى 9، بينما تغطي عبارة if الثانية جميع الأرقام من 10 إلى 15 (a-f بالنظام الست عشري)

مرة أخرى، باستخدام مثالنا 0000 0001 بالنظام العشري يساوي 1.لقد وقعنا في الجزء العلوي من كتلة if وأضفنا 1 إلى الحرف "0" للحصول على الحرف "1"، ثم نلحقه بالسلسلة ونمضي قدمًا.

                halfbyte = data[i] & 0x0F;

الآن قمنا بإعداد عدد صحيح ليتساوى مع البتات المنخفضة من البايت ونكرر.

مرة أخرى، إذا كانت مدخلاتنا 23 ...0001 0111 بعد المنطقي AND يصبح فقط 0000 0111 وهو 7 بالنظام العشري.كرر نفس المنطق المذكور أعلاه وسيتم عرض الحرف "7".

            } while(two_halfs++ < 1);

ننتقل الآن إلى البايت التالي في المصفوفة ونكرر الأمر.

        }
    return buf.toString();
}

للإجابة على سؤالك التالي، تحتوي Java API بالفعل على أداة تحويل أساسية مدمجة في BigInteger بالفعل.انظر toString (الجذر int) توثيق.

لا أعرف التنفيذ الذي تستخدمه Java API، لا أستطيع أن أقول ذلك على وجه اليقين، لكنني سأكون على استعداد للمراهنة على أن تنفيذ Java أكثر كفاءة من الخوارزمية الأولى البسيطة إلى حد ما التي نشرتها.

نصائح أخرى

للرد على هذا الشيء:

<اقتباس فقرة>   

وماذا يفعل هذا العمل أيضا

وولا. على الأقل، وليس بنفس الطريقة التي النسخة حلقة لا. سوف جديدة BigInteger (...). toString (16) لا تظهر أصفار الرائدة، والتي سوف الصيغة السابقة. عادة عن شيء مثل كتابة خارج صفيف بايت (وخاصة تلك التي تمثل شيء من هذا القبيل تجزئة) كنت تريد انتاج ذات طول ثابت حتى إذا كنت ترغب في استخدام هذا الإصدار كنت قد لوحة بها بشكل مناسب.

لشرح دقيق على bitshifting تحقق من الإجابات في السؤال التالي SO ما هي التحول المختصة بالبت (التحول بت) المشغلين وكيف تعمل؟

ويبدو أنه محاولة لتحويل بايت واحد إلى عدد أصغر من 16 عاما، عن طريق القيام حتى يتمكن من تحديد بسهولة اللي تبونه caracther أن البايت يمثل برمز

  if ((0 <= halfbyte) && (halfbyte <= 9))
                buf.append((char) ('0' + halfbyte));
            else
                buf.append((char) ('a' + (halfbyte - 10)));

وهذا هو الجواب في التبسيط، ولكن ايم يست مشرقة على أية حال = D

وهذه الأشياء لم يكن لديك لكتابة من قبل نفسك، لأنه مكتوب بالفعل في اباتشي-المشتركة-الترميز:

import org.apache.commons.codec.binary.Hex;
...
Hex.encodeHexString(byte[] array)

وهناك الكثير من الطرق أكثر فائدة في الصف Hex.

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