#include <stdint.h>
void hex_encode(char *output, uint8_t *input, uint32_t length)
{
for (int i = 0; i < length; i++)
{
uint8_t h = (input[i] >> 4);
*output++ = h > 9 ? h + 'a' - 10 : '0' + h;
uint8_t l = (input[i] & 0x0f);
*output++ = l > 9 ? l + 'a' - 10 : '0' + l;
}
}
void hex_encode_rev(char *output, uint8_t *input, uint32_t length)
{
for (int i = length - 1; i >= 0; i--)
{
uint8_t h = (input[i] >> 4);
*output++ = h > 9 ? h + 'a' - 10 : '0' + h;
uint8_t l = (input[i] & 0x0f);
*output++ = l > 9 ? l + 'a' - 10 : '0' + l;
}
}
char *uint2hex(char *output, uint8_t *input, uint32_t length)
{
while (length > 1 && input[length - 1] == 0)
length--;
*output++ = '0';
*output++ = 'x';
uint8_t h = (input[length - 1] >> 4);
if (h > 0)
*output++ = h > 9 ? h + 'a' - 10 : '0' + h;
uint8_t l = (input[length - 1] & 0x0f);
*output++ = l > 9 ? l + 'a' - 10 : '0' + l;
while (--length)
{
uint8_t h = (input[length - 1] >> 4);
*output++ = h > 9 ? h + 'a' - 10 : '0' + h;
uint8_t l = (input[length - 1] & 0x0f);
*output++ = l > 9 ? l + 'a' - 10 : '0' + l;
}
return output;
}
char *uint2bin(char *output, uint8_t *input, uint32_t length)
{
while (length > 1 && input[length - 1] == 0)
length--;
*output++ = '0';
*output++ = 'b';
uint8_t v = input[length - 1];
int i = 8;
while (i > 0 && !(v & 0x80))
{
v <<= 1;
i--;
}
while (i--)
{
*output++ = v & 0x80 ? '1' : '0';
v <<= 1;
}
while (--length)
{
uint8_t v = input[length - 1];
for (i = 0; i < 8; i++)
{
*output++ = v & 0x80 ? '1' : '0';
v <<= 1;
}
}
return output;
}
char *uint2dec(char *output, uint64_t val)
{
char buf[20];
int len = 0;
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
while (len--)
{
*output++ = buf[len] + '0';
}
return output;
}
extern int udivmod128(const __uint128_t *dividend, const __uint128_t *divisor, __uint128_t *remainder,
__uint128_t *quotient);
char *uint128dec(char *output, __uint128_t val128)
{
const __uint128_t billion = 10000000000;
const __uint128_t divisor = billion * 1000000000;
__uint128_t q, r;
char buf[40];
int len = 0;
udivmod128(&val128, &divisor, &r, &q);
uint64_t val = r;
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
udivmod128(&q, &divisor, &r, &q);
val = r;
if (val)
{
while (len < 19)
{
buf[len++] = 0;
}
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
}
val = q;
if (val)
{
while (len < 38)
{
buf[len++] = 0;
}
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
}
while (len--)
{
*output++ = buf[len] + '0';
}
return output;
}
typedef unsigned _BitInt(256) uint256_t;
extern int udivmod256(const uint256_t *dividend, const uint256_t *divisor, uint256_t *remainder, uint256_t *quotient);
char *uint256dec(char *output, uint256_t *val256)
{
const uint256_t n1e10 = 10000000000;
const uint256_t n1e9 = 1000000000;
uint256_t divisor = n1e10 * n1e9;
uint256_t q = *val256, r;
char buf[80];
int len = 0;
for (int digits = 0; digits < 76; digits += 19)
{
udivmod256(&q, &divisor, &r, &q);
uint64_t val = r;
while (len < digits)
{
buf[len++] = 0;
}
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
if (q == (uint256_t)0)
{
break;
}
}
uint64_t val = q;
if (val)
{
do
{
buf[len++] = val % 10;
val /= 10;
} while (val);
}
while (len--)
{
*output++ = buf[len] + '0';
}
return output;
}
static const char b58digits[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
void base58_encode_solana_address(uint8_t *data, uint32_t data_len, uint8_t *output, uint32_t output_len)
{
uint32_t j, carry, zero_count = 0;
while (zero_count < data_len && !data[zero_count])
++zero_count;
for (uint32_t i = zero_count, high = output_len - 1; i < data_len; i++, high = j)
{
for (carry = data[i], j = output_len - 1; (j > high) || carry; --j)
{
carry += 256 * output[j];
output[j] = carry % 58;
carry /= 58;
if (!j)
{
break;
}
}
}
for (j = 0; j < output_len; j++)
{
output[j] = b58digits[output[j]];
}
}