I need to convert a byte array to base58. I found the following function that is faster than using Bignums:
void EncodeAdrBase58(const uint8_t *bytes, unsigned char* result) //only accepts 25-byte arrays (1 byte for addressbyte, 20 for hash160, and 4 for checksum)
{
unsigned char digits[25 * 137 / 100];
int digitslen = 1;
for (int i = 0; i < 25; i++)
{
unsigned int carry = (unsigned int)bytes[i];
for (int j = 0; j < digitslen; j++)
{
carry += (unsigned int)(digits[j]) << 8;
digits[j] = (unsigned char)(carry % 58);
carry /= 58;
}
while (carry > 0)
{
digits[digitslen++] = (unsigned char)(carry % 58);
carry /= 58;
}
}
int resultlen = 0;
// leading zero bytes
for (; resultlen < 25 && bytes[resultlen] == 0;)
result[resultlen++] = '1';
// reverse
for (int i = 0; i < digitslen; i++)
result[resultlen + i] = ALPHABET[digits[digitslen - 1 - i]];
result[digitslen + resultlen] = 0;
}
When trying to test its speed I found that it gives the right answer- the first time. Then when running multiple times in a row with the same input data, it gives different answers. Oddly enough, those different answers are the same every time it's run. My testing method:
void encB58()
{
uint8_t data[] = { 0x00, 0x01, 0x09, 0x66, 0x77, 0x60, 0x06, 0x95, 0x3D, 0x55, 0x67, 0x43, 0x9E, 0x5E, 0x39, 0xF8, 0x6A, 0x0D, 0x27, 0x3B, 0xEE, 0xD6, 0x19, 0x67, 0xF6 };
unsigned char result[25 * 137 / 100];
for (int i = 0; i < 2; i++)
{
EncodeAdrBase58(&data, &result);
printf("%s\n", result);
}
}
If I run encB58(), I get
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
The first one is correct. If I change the loop in encB58() to 4 times, I get
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
12XoTKEDFdsWtAa7RJF7EvMJhdDv3EFu4VeS9
1FD5HoTinBXBszw6CoxPddSb6UkH3yvzYogZ
Also, if I change encB58() to use two different inputs and output to two different char arrays
void encB58()
{
uint8_t data[] = { 0x00, 0x01, 0x09, 0x66, 0x77, 0x60, 0x06, 0x95, 0x3D, 0x55, 0x67, 0x43, 0x9E, 0x5E, 0x39, 0xF8, 0x6A, 0x0D, 0x27, 0x3B, 0xEE, 0xD6, 0x19, 0x67, 0xF6 };
uint8_t data2[] = { 0x00, 0xED, 0xA9, 0x96, 0xA7, 0x21, 0x2D, 0x7D, 0xBB, 0x38, 0x22, 0xE8, 0x53, 0x20, 0x68, 0x91, 0x49, 0x95, 0x00, 0xDE, 0x4C, 0xD6, 0xB3, 0x5E, 0x9C };
unsigned char result[25 * 137 / 100];
unsigned char result2[25 * 137 / 100];
for (int i = 0; i < 2; i++)
{
EncodeAdrBase58(&data, &result);
EncodeAdrBase58(&data2, &result2);
printf("%s\n", result);
printf("%s\n", result2);
}
}
I get the following:
15uASzsR5JsK31Vs3ViKNV6fUM5T8TMp123AV
1rjdMG92vdQwp1bBmt3LpCnRyWaL9TzQ6Jbm
14g862Go94gqhyXQdndhKjZ5ZB8XeC3qqjiMT
1oBcJS1SK7taZQsGPXWYH2WEciL4EVzVRnfD
NONE of those are correct. What is happening here?