Warum liefert meine Implementierung von hex to Base58check andere Ergebnisse als das Beispiel?

Schritt 8 dieser Wiki-Seite gibt diesen Hex-Wert:00010966776006953D5567439E5E39F86A0D273BEED61967F6

Schritt 9 wandelt es in diesen base58-String um:16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

Ich versuche, die Konvertierungsfunktion mit dem Pseudocode von dieser Wiki-Seite zu implementieren. Dies ist meine Implementierung (in Java):

    String input = "00010966776006953D5567439E5E39F86A0D273BEED61967F6"
    BigInteger bigInteger = new BigInteger(input , 16);
    String code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    StringBuilder output = new StringBuilder();

    while(bigInteger.compareTo(BigInteger.ZERO) == 1){
        BigInteger[] divAndRemainder = bigInteger.divideAndRemainder(BigInteger.valueOf(58));
        output.append(code_string.charAt(divAndRemainder[1].intValue()));
        bigInteger = divAndRemainder[0];
    }

    int i=0;
    while(concat.charAt(i) == '0'){
        i++;
        output.append(code_string.charAt(0));
    }
    System.out.println(output.reverse());

Das druckt aus 1116UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM. Dies kommt dem nahe, was die Wiki-Seite produziert, aber nicht ganz, es gibt 2 zusätzliche führende 1s. Dies ist von den 2 führenden 0s in der Eingabezeichenfolge. Warum bekommt das Wiki-Beispiel mein Ergebnis nicht?

die führenden Nullen werden nicht korrekt abgedeckt. Ich habe mir den Code nicht angesehen, aber hier ist ein sehr guter Diskussionsthread, einschließlich Java-Referenzen: bitcointalk.org/index.php?topic=1026.0 - außerdem gibt es diese Java-Implementierung hier: rosettacode.org/wiki/Bitcoin/address_validation #Java

Antworten (1)

Jedes hexadezimale Zeichen hat vier Informationsbits. Zwei Hex-Zeichen enthalten acht Informationsbits, bilden also ein Byte.

Für jedes Byte vor der Adresse 1sollte ein gesetzt werden. Da zwei Zeichen ein Byte bilden:

int i=0;
while(concat.charAt(i) == '0' && concat.charAt(i + 1) == '0'){
    i += 2;
    output.append(code_string.charAt(0));
}

Übrigens würde es besser aussehen, wenn es eine for-Schleife wäre:

for (int i = 0; concat.charAt(i++) == '0' && concat.charAt(i++) == '0';) {
    output.append(code_string.charAt(0));
}

Außerdem haben Sie wahrscheinlich beim Kopieren des Codes einen Fehler gemacht: Sie haben keine Variable namens deklariert concat. Es ist input.

Letzter Hinweis: Wenn Sie diese Codierung für andere Dinge als Bitcoin-Adressen verwenden (die eine Prüfsumme haben), stellen Sie sicher, dass sie iimmer kleiner als istconcat.length()