我需要将字节数组转换为 base58。我发现以下函数比使用 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;
}
在尝试测试它的速度时,我发现它第一次给出了正确的答案。然后当使用相同的输入数据连续运行多次时,它会给出不同的答案。奇怪的是,每次运行时这些不同的答案都是相同的。我的测试方法:
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);
}
}
如果我跑encB58()
,我会得到
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
第一个是正确的。如果我将循环更改encB58()
为 4 次,我会得到
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
12XoTKEDFdsWtAa7RJF7EvMJhdDv3EFu4VeS9
1FD5HoTinBXBszw6CoxPddSb6UkH3yvzYogZ
另外,如果我将 encB58() 更改为使用两个不同的输入并输出到两个不同的字符数组
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);
}
}
我得到以下信息:
15uASzsR5JsK31Vs3ViKNV6fUM5T8TMp123AV
1rjdMG92vdQwp1bBmt3LpCnRyWaL9TzQ6Jbm
14g862Go94gqhyXQdndhKjZ5ZB8XeC3qqjiMT
1oBcJS1SK7taZQsGPXWYH2WEciL4EVzVRnfD
这些都不正确。这里发生了什么?