From de63b95142d35182ee5e9e424f608e64b9320891 Mon Sep 17 00:00:00 2001 From: mar77i Date: Thu, 25 Jun 2026 19:07:12 +0200 Subject: [PATCH] from_b32_inplace: use a lut --- encoding.h | 70 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/encoding.h b/encoding.h index a288c52..b01ac1e 100644 --- a/encoding.h +++ b/encoding.h @@ -63,50 +63,44 @@ static inline void to_hex(char c, char *s) { } static inline ssize_t from_b32_inplace(char *s) { - static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; - uint8_t accu = 0, bits, count; - char *ptr = s, *found; - size_t pos; - for (pos = count = 0; s[pos] != '\n' && s[pos] != '\0' && s[pos] != '='; pos++) { - if (s[pos] == ' ' || s[pos] == '\t') + const uint8_t b32_lut[256] = { + ['\0'] = 0xfd, ['\n'] = 0xfd, ['='] = 0xfd, + [' '] = 0xfe, ['\t'] = 0xfe, + ['A'] = 32, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, ['F'] = 5, + ['G'] = 6, ['H'] = 7, ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, + ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15, ['Q'] = 16, ['R'] = 17, + ['S'] = 18, ['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, + ['Y'] = 24, ['Z'] = 25, ['2'] = 26, ['3'] = 27, ['4'] = 28, ['5'] = 29, + ['6'] = 30, ['7'] = 31, + // Case insensitivity support handled directly in the table + ['a'] = 32, ['b'] = 1, ['c'] = 2, ['d'] = 3, ['e'] = 4, ['f'] = 5, + ['g'] = 6, ['h'] = 7, ['i'] = 8, ['j'] = 9, ['k'] = 10, ['l'] = 11, + ['m'] = 12, ['n'] = 13, ['o'] = 14, ['p'] = 15, ['q'] = 16, ['r'] = 17, + ['s'] = 18, ['t'] = 19, ['u'] = 20, ['v'] = 21, ['w'] = 22, ['x'] = 23, + ['y'] = 24, ['z'] = 25, + }; + register uint8_t val; + register int8_t bits_left = 0; + char *ptr = s - 1, *found; + size_t pos = 0; + for (; (val = b32_lut[s[pos]]) != 0xfd; pos++) { + if (val == 0xfe) continue; - if ((found = strchr(base32_alphabet, toupper(s[pos]))) == NULL) { + else if (val == 0) { UART_write_string("ERROR:INVALIDB32\n"); return -1; } - bits = found - base32_alphabet; - switch (count++ % 8) { - case 0: - accu = bits << 3; - break; - case 1: - *ptr++ = accu | (bits >> 2); - accu = bits << 6; - break; - case 2: - accu |= bits << 1; - break; - case 3: - *ptr++ = accu | (bits >> 4); - accu = bits << 4; - break; - case 4: - *ptr++ = accu | (bits >> 1); - accu = bits << 7; - break; - case 5: - accu |= bits << 2; - break; - case 6: - *ptr++ = accu | (bits >> 3); - accu = bits << 5; - break; - case 7: - *ptr++ = accu | bits; - break; + val &= 31; + bits_left -= 5; + if (bits_left < 0) { + bits_left = -bits_left; + *ptr++ |= val >> bits_left; + bits_left = 8 - bits_left; + *ptr = 0; } + *ptr |= val << bits_left; } - return ptr - s; + return ptr - s + (bits_left == 0); } static inline void to_decimal(uint32_t n, char *out, size_t out_len) { -- 2.54.0