Frage

Ich begann vor kurzem bei MD5 suchen (in Java) Hashing und während ich habe Algorithmen und Methoden gefunden, dass ich erreichen zu helfen, ich frage mich, links, wie es tatsächlich funktioniert.

Zum einen fand ich folgende von dieser 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();
}

Ich habe keine Notwendigkeit zu verwenden Bitverschiebung in Java gefunden, so bin ich ein wenig eingerostet, dass auf. Jemand nett genug, um zu veranschaulichen (in einfachen Worten) wie genau funktioniert den obigen Code die Umwandlung tut? ">>>"?

Ich fand auch andere Lösungen auf Stackoverflow, wie hier und hier , die verwendet BigInteger statt:

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

Warum funktioniert das auch, und die Art und Weise ist effizienter?

Vielen Dank für Ihre Zeit.

War es hilfreich?

Lösung

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

Bis zu diesem Punkt ... nur Basis-Set und eine Schleife beginnend durch alle Bytes in dem Feld gehen

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

Bytes umgewandelt hex sind zwei hexadezimalen Ziffern oder 8 Binärziffern je nachdem, welche Basis man es betrachtet in. Die obige Aussage verschiebt die hohe 4 Bits nach unten (>>> ist unsigned Verschiebung nach rechts) und logische UND-Verknüpfung mit 0000 1111, so dass das Ergebnis eine ganze Zahl ist auf die hohen Bits des 4-Byte (ersten hex digit).

gleich

Say 23 war ein Eingang, ist dies 0001 0111 binär. Die Verschiebung macht und logische UND coverts dies 0000 0001.

        int two_halfs = 0;
        do {

Hier wird nur die do up / while-Schleife zweimal ausgeführt

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

Hier sind Anzeigen uns die tatsächliche Hexadezimalzeichens, im Grunde nur die Null oder ein Zeichen als Ausgangspunkt verwendet und auf den richtigen Charakter Hochschalten. Die erste if-Anweisung umfasst alle Ziffern 0-9 und der zweite umfasst alle Ziffern 10-15 (a-f in hex)

Auch mit unserem Beispiel 0000 0001 in dezimal ist gleich 1. Wir befinden uns im oberen verfangen, wenn Block und fügen Sie 1, um die Zeichen ‚0‘, um den Charakter zu erhalten ‚1‘, das auf den String anhängen und weitermachen .

                halfbyte = data[i] & 0x0F;

Jetzt setzen wir die ganze Zahl bis nur die niedrigen Bits aus dem Byte und wiederholen Sie entsprechen.

Auch wenn unser Eingang 23 ist ... 0001 0111 nach der logischen UND-Verknüpfung wird nur 0000 0111, die 7 in dezimal. Wiederholen Sie die gleiche Logik wie oben und das Zeichen ‚7‘ angezeigt wird.

            } while(two_halfs++ < 1);

Jetzt ziehen wir nur auf das nächste Byte in dem Array und wiederholen.

        }
    return buf.toString();
}

Ihre nächste Frage zu beantworten, hat der Java-API bereits eine Dienstprogramm Basis Umwandlung in bereits BigInteger gebaut. Sehen Sie sich die toString (int radix Dokumentation).

Nicht die Umsetzung durch die Java-API verwendet zu kennen, kann ich nicht sicher sagen, aber ich wäre bereit zu wetten, dass die Java-implenentation effizienter ist als die erste etwas einfacher Algorithmus Sie auf dem Laufenden.

Andere Tipps

Dieses Bit zu beantworten:

  

Warum funktioniert das auch

Es ist nicht. Zumindest nicht die gleiche Art und Weise, dass die Schleife Version der Fall ist. neuer BigInteger (...). toString (16) zeigt keine führenden Nullen, die die frühere Version wird. In der Regel für so etwas wie das Schreiben aus ein Byte-Array (vor allem eine, die etwas darstellt wie ein Hash) würden Sie wollen eine feste Länge ausgegeben, so, wenn Sie diese Version verwenden möchten Sie Pad haben würde es aus entsprechend.

Für eine ausführliche Erklärung auf bitshifting überprüfen Sie die Antworten auf die folgende Frage SO Was bitweise Verschiebung (Bit-Shift) Operatoren sind und wie funktionieren sie?

Er scheint zu versuchen, ein einziges Byte in eine Zahl zu konvertieren kleiner als 16 ist, indem so kann er leicht Weicht bestimmen caracther dass Byte mit dem Code repräsentiert

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

Dies ist eine einfache Antwort, aber im nicht so hell sowieso = D

Diese Sachen müssen Sie selbst nicht schreiben, weil es bereits in Apache-Commons-Codec steht geschrieben:

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

Es gibt eine Menge nützlicher Methoden in Hex Klasse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top