Running code multiple times in a row has different results even with same input data

262 Views Asked by At

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?

0

There are 0 best solutions below