#include #include #include #include #include #include static bool baseconv_internal( char outbuf[], size_t bufsize, const char *digits, size_t base, uintmax_t num ) { // Supported bases are 2 to number of digits inclusive if (base < 2 || base > strlen(digits)) return false; // Longest possible converted string is base-2, where we produce one // character per bit of input, so if we size the buffer to fit it we // can fit any converted string char buf[sizeof(uintmax_t) * CHAR_BIT]; // Place the digits in the buffer in a little-endian order size_t len = 0; while (num) { char digit = digits[num % base]; buf[len++] = digit; num /= base; } // Special case: if the original input was zero, previous loop ran // zero times, and there is nothing in the buffer. Place a single // zero there. if (!len) buf[len++] = digits[0]; // Can the output buffer hold the converted string as well as the // null terminator? if (!bufsize || bufsize - 1 < len) return false; // Copy the digits to the output buffer, reversing the order for (size_t i = 0; i < len; i++) outbuf[i] = buf[len - 1 - i]; // Null-terminate outbuf[len] = '\0'; return true; } bool baseconv(char outbuf[], size_t bufsize, size_t base, uintmax_t num) { const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; return baseconv_internal(outbuf, bufsize, digits, base, num); } bool baseconv_digits( char outbuf[], size_t bufsize, const char *digits, uintmax_t num ) { size_t base = strlen(digits); return baseconv_internal(outbuf, bufsize, digits, base, num); }