/* radare - LGPL - Copyright 2023-2024 - pancake */

#include <r_util.h>

static const char cb36[] = "0123456789abcdefghijklmnopqrstuvwxyz";

R_API void b36_fromnum(char *s, ut64 n) {
	const int amount = n? (int)(log ((double)n) / log ((double)36)): 0;
	char *p = s;
	*p++ = '0';
	*p++ = '_';
	p += amount + 1;
	*p-- = 0;
	if (n == 0) {
		*p = '0';
	} else while (n > 0) {
		*p-- = cb36[n % 36];
		n /= 36;
	}
}

static const ut64 pow36[36] = {
	1, 36, 1296, 46656, 1679616, 60466176,
	2176782336ULL, 78364164096ULL, 2821109907456ULL,
	101559956668416ULL, 3656158440062976ULL,
	131621703842267136ULL, 4738381338321616896ULL,
	9223372036854775808ULL,
};

static const int index36[0x100] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1,
	-1, -1, -1, -1,
	10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
	21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	32, 33, 34, 35,
	-1, -1, -1, -1, -1, -1,
	10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
	21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	32, 33, 34, 35,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, // 256
};

R_API ut64 b36_tonum(const char *s) {
	ut64 n = 0;
	int pos = 0;
	if (r_str_startswith (s, "0_")) {
		s += 2;
	}
	while (true) {
		int idx = index36 [(unsigned char )*s];
		if (idx < 0 || pos >= (int)R_ARRAY_SIZE (pow36)) {
			break;
		}
		n += pow36[pos] * idx;
		pos++;
		s++;
	}
	return n;
}
