123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #include <stdint.h>
- #include <endian.h>
- #include <stddef.h>
- #define STYLE_9
- #include "fn85.h"
- static const char encoding[] = "0123456789"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "!$%&*+,-:;<=>?@[]^_`{|}";
- static const uint8_t decoding[256] = {
- ['0'] = 1, ['1'] = 2, ['2'] = 3, ['3'] = 4, ['4'] = 5, ['5'] = 6,
- ['6'] = 7, ['7'] = 8, ['8'] = 9, ['9'] = 10, ['a'] = 11, ['b'] = 12,
- ['c'] = 13, ['d'] = 14, ['e'] = 15, ['f'] = 16, ['g'] = 17, ['h'] = 18,
- ['i'] = 19, ['j'] = 20, ['k'] = 21, ['l'] = 22, ['m'] = 23, ['n'] = 24,
- ['o'] = 25, ['p'] = 26, ['q'] = 27, ['r'] = 28, ['s'] = 29, ['t'] = 30,
- ['u'] = 31, ['v'] = 32, ['w'] = 33, ['x'] = 34, ['y'] = 35, ['z'] = 36,
- ['A'] = 37, ['B'] = 38, ['C'] = 39, ['D'] = 40, ['E'] = 41, ['F'] = 42,
- ['G'] = 43, ['H'] = 44, ['I'] = 45, ['J'] = 46, ['K'] = 47, ['L'] = 48,
- ['M'] = 49, ['N'] = 50, ['O'] = 51, ['P'] = 52, ['Q'] = 53, ['R'] = 54,
- ['S'] = 55, ['T'] = 56, ['U'] = 57, ['V'] = 58, ['W'] = 59, ['X'] = 60,
- ['Y'] = 61, ['Z'] = 62, ['!'] = 63, ['$'] = 64, ['%'] = 65, ['&'] = 66,
- ['*'] = 67, ['+'] = 68, [','] = 69, ['-'] = 70, [':'] = 71, [';'] = 72,
- ['<'] = 73, ['='] = 74, ['>'] = 75, ['?'] = 76, ['@'] = 77, ['['] = 78,
- [']'] = 79, ['^'] = 80, ['_'] = 81, ['`'] = 82, ['{'] = 83, ['|'] = 84,
- ['}'] = 85
- };
- void
- fn85_encode(char *des, const void *src, size_t units)
- {
- const uint32_t *bytes = src;
- for (; units; --units) {
- uint32_t val = 0;
- /* treat bytes as 256-radix number */
- val = be32toh(*bytes++);
- /* convert to five 85-radix chars of des ("big endian") */
- for (int div = 85 * 85 * 85 * 85; div; div /= 85, ++des)
- *des = encoding[val / div % 85];
- }
- }
- Fn85_err
- fn85_decode(void *des, const char *src, size_t units,
- size_t *pos, const char **error)
- {
- uint32_t *bytes = des;
- for (; units; --units) {
- uint_fast64_t val = 0;
- for (int step = 0; step < 5; ++step, ++src, ++*pos) {
- uint8_t char_val = decoding[(uint8_t) *src];
- if (!char_val) {
- if (error)
- *error = "Not a valid digit";
- return FN85_INVALID;
- }
- if ((val = val * 85 + char_val - 1) > UINT32_MAX) {
- if (error)
- *error = "Number too large";
- return FN85_TOO_HIGH;
- }
- }
- *bytes++ = htobe32(val);
- }
- return FN85_OKAY;
- }
|