Step 8 of this wiki page gives this hex value: 00010966776006953D5567439E5E39F86A0D273BEED61967F6

Step 9 converts it to this base58 string:16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

I'm trying to implement the conversion function using the pseudocode from this wiki page. This is my implementation (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));
        bigInteger = divAndRemainder[0];

    int i=0;
    while(concat.charAt(i) == '0'){

This prints out 1116UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM. This is close to what the wiki page produces, but not quite, there are 2 extra leading 1s. This is from the 2 leading 0s in the input string. Why doesn't the wiki example get my result?


Each hexadecimal character has four bits of information. Two hex characters contains eight bits of information, so they form a byte.

For each byte in front of the address, a 1 should be put. Since two characters form a byte:

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

BTW, it would look better if it was a for loop:

for (int i = 0; concat.charAt(i++) == '0' && concat.charAt(i++) == '0';) {

Also, probably you've made a mistake while copying the code: You haven't declared a variable named concat. It's input.

Last note: If you're going to use this encoding for things other than Bitcoin addresses (which have checksum), make sure that i will always be smaller than concat.length()

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.