commit 26a102c

V. Luna  ·  2026-10-07 06:41:48 +0000 UTC
parent 37a2f72
add decoding
1 files changed,  +41, -10
+41, -10
 1@@ -24,11 +24,9 @@ xs_str* xs_base64_enc(const xs_val *data, int size);
 2  * meatride this lib so much but I hope this gets you to join minx cafe.
 3  * */
 4 
 5-#define MASK 0x3f
 6-#define PAD '='
 7 static const char b64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 8 
 9-static int base64_val(int c) {
10+static int b64_val(int c) {
11         if (c >= 'A' && c <= 'Z') return c - 'A';
12         if (c >= 'a' && c <= 'z') return c - 'a' + 26;
13         if (c >= '0' && c <= '9') return c - '0' + 52;
14@@ -52,9 +50,9 @@ xs_str* xs_base64_enc(const xs_val* data, int size) { // NOLINT
15         while (i + b64_bytes - 1 < size) {
16                 unsigned int v = (d[i] << 16) | (d[i + 1] << 8) | d[i + 2];
17 
18-                s[j++] = b64_tab[(v >> 18) & MASK];
19-                s[j++] = b64_tab[(v >> 12) & MASK];
20-                s[j++] = b64_tab[(v >> 6) & MASK];
21+                s[j++] = b64_tab[(v >> 18) & 0x3f];
22+                s[j++] = b64_tab[(v >> 12) & 0x3f];
23+                s[j++] = b64_tab[(v >> 6) & 0x3f];
24                 i += b64_bytes;
25         }
26 
27@@ -64,16 +62,49 @@ xs_str* xs_base64_enc(const xs_val* data, int size) { // NOLINT
28 
29                 if (rem == 2) { v |= d[i + 1] << 8; }
30 
31-                s[j++] = b64_tab[(v >> 18) & MASK];
32-                s[j++] = b64_tab[(v >> 12) & MASK];
33-                s[j++] = (rem == 2) ? b64_tab[(v >> 6) & MASK] : PAD;
34-                s[j++] = PAD;
35+                s[j++] = b64_tab[(v >> 18) & 0x3f];
36+                s[j++] = b64_tab[(v >> 12) & 0x3f];
37+                s[j++] = (rem == 2) ? b64_tab[(v >> 6) & 0x3f] : '=';
38+                s[j++] = '=';
39         }
40 
41         s[j] = '\0';
42         
43         return s;
44 }
45+
46+xs_val* xs_base64_dec(const xs_str* data, int* size) {
47+        int input_len = strlen(data);
48+        unsigned char* out = xs_realloc(NULL, _xs_blk_size(input_len + 1));
49+
50+        int o = 0, acc = 0, bits = 0, i;
51+
52+        for (i = 0; i < input_len; i++) {
53+                int c = (unsigned char)data[i];
54+                int v;
55+
56+                if (c == '=' || c == '\n' || c == '\r' || c == ' ' || c == '\t') {
57+                        continue;
58+                }
59+
60+                v = b64_val(c);
61+                if (v < 0) { continue; }
62+
63+                acc = (acc << 6) | v;
64+                bits += 6;
65+
66+                if (bits >= 8) {
67+                        bits -= 8;
68+                        out[o++] = (acc >> bits) & 0xff;
69+                }
70+
71+                out = xs_realloc(out, _xs_blk_size(o + 1));
72+                out[o] = '\0';
73+                *size = 0;
74+
75+                return (xs_val*)out;
76+        }
77+}
78 #endif // _XS_BASE64_H
79 
80 #endif // XS_IMPLEMENTATION