¿Por qué mi implementación de hexadecimal en Base58check produce resultados diferentes a los del ejemplo?

El paso 8 de esta página wiki da este valor hexadecimal:00010966776006953D5567439E5E39F86A0D273BEED61967F6

El paso 9 lo convierte a esta cadena base58:16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

Estoy tratando de implementar la función de conversión usando el pseudocódigo de esta página wiki. Esta es mi implementación (en 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());

Esto se imprime 1116UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM. Esto está cerca de lo que produce la página wiki, pero no del todo, hay 2 1s iniciales adicionales. Esto es de las 2 0s iniciales en la cadena de entrada. ¿Por qué el ejemplo de wiki no obtiene mi resultado?

los ceros iniciales no están cubiertos correctamente. No he mirado el código, pero aquí hay un hilo de discusión muy bueno, que incluye referencias de java: bitcointalk.org/index.php?topic=1026.0 - también hay esta implementación de java aquí: rosettacode.org/wiki/Bitcoin/address_validation #Java

Respuestas (1)

Cada carácter hexadecimal tiene cuatro bits de información. Dos caracteres hexadecimales contienen ocho bits de información, por lo que forman un byte.

Para cada byte delante de la dirección, 1debe colocarse una. Dado que dos caracteres forman un byte:

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

Por cierto, se vería mejor si fuera un bucle for:

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

Además, probablemente haya cometido un error al copiar el código: no ha declarado una variable llamada concat. es input_

Última nota: si va a utilizar esta codificación para cosas que no sean direcciones de Bitcoin (que tienen suma de verificación), asegúrese de que isiempre sea menor queconcat.length()