summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xs_encdec.h163
-rw-r--r--xs_version.h2
2 files changed, 1 insertions, 164 deletions
diff --git a/xs_encdec.h b/xs_encdec.h
index d3178f4..f4ffe22 100644
--- a/xs_encdec.h
+++ b/xs_encdec.h
@@ -7,10 +7,6 @@
7 xs_str *xs_hex_enc(const xs_val *data, int size); 7 xs_str *xs_hex_enc(const xs_val *data, int size);
8 xs_val *xs_hex_dec(const xs_str *hex, int *size); 8 xs_val *xs_hex_dec(const xs_str *hex, int *size);
9 int xs_is_hex(const char *str); 9 int xs_is_hex(const char *str);
10 xs_str *xs_base32_enc(const xs_val *data, int sz);
11 xs_str *xs_base32hex_enc(const xs_val *data, int sz);
12 xs_val *xs_base32_dec(const xs_str *data, int *size);
13 xs_val *xs_base32hex_dec(const xs_str *data, int *size);
14 xs_str *xs_base64_enc(const xs_val *data, int sz); 10 xs_str *xs_base64_enc(const xs_val *data, int sz);
15 xs_val *xs_base64_dec(const xs_str *data, int *size); 11 xs_val *xs_base64_dec(const xs_str *data, int *size);
16 int xs_is_base64(const char *str); 12 int xs_is_base64(const char *str);
@@ -84,165 +80,6 @@ int xs_is_hex(const char *str)
84} 80}
85 81
86 82
87/** base32 */
88
89static char *xs_b32_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
90 "234567=";
91
92static char *xs_b32hex_tbl = "0123456789"
93 "ABCDEFGHIJKLMNOPQRSTUV=";
94
95/*
96 00000|00011|11111|12222|22223|33333|33444|44444
97*/
98
99xs_str *xs_base32_enc_tbl(const xs_val *data, int sz, const char *b32_tbl)
100/* encodes data to base32 using a table */
101{
102 xs_str *s = xs_str_new(NULL);
103 unsigned char *p;
104 int n;
105
106 p = (unsigned char *)data;
107
108 for (n = 0; n < sz; n += 5) {
109 int l = sz - n;
110 char enc[9] = "========";
111
112 enc[0] = b32_tbl[(p[n] >> 3) & 0x1f];
113
114 if (l > 1) {
115 enc[1] = b32_tbl[(p[n] << 2 | p[n + 1] >> 6) & 0x1f];
116 enc[2] = b32_tbl[(p[n + 1] >> 1) & 0x1f];
117
118 if (l > 2) {
119 enc[3] = b32_tbl[(p[n + 1] << 4 | p[n + 2] >> 4) & 0x1f];
120
121 if (l > 3) {
122 enc[4] = b32_tbl[(p[n + 2] << 1 | p[n + 3] >> 7) & 0x1f];
123 enc[5] = b32_tbl[(p[n + 3] >> 2) & 0x1f];
124
125 if (l > 4) {
126 enc[6] = b32_tbl[(p[n + 3] << 3 | p[n + 4] >> 5) & 0x1f];
127 enc[7] = b32_tbl[(p[n + 4]) & 0x1f];
128 }
129 else
130 enc[6] = b32_tbl[(p[n + 3] << 3) & 0x1f];
131 }
132 else
133 enc[4] = b32_tbl[(p[n + 2] << 1) & 0x1f];
134 }
135 else
136 enc[3] = b32_tbl[(p[n + 1] << 4) & 0x1f];
137 }
138 else
139 enc[1] = b32_tbl[(p[n] << 2) & 0x1f];
140
141 s = xs_str_cat(s, enc);
142 }
143
144 return s;
145}
146
147
148xs_str *xs_base32_enc(const xs_val *data, int sz)
149/* encodes data to base32 */
150{
151 return xs_base32_enc_tbl(data, sz, xs_b32_tbl);
152}
153
154
155xs_str *xs_base32hex_enc(const xs_val *data, int sz)
156/* encodes data to base32 with HEX alphabet (RFC4648) */
157{
158 return xs_base32_enc_tbl(data, sz, xs_b32hex_tbl);
159}
160
161
162xs_val *xs_base32_dec_tbl(const xs_str *data, int *size, const char *b32_tbl)
163/* decodes data from base32 using a table */
164{
165 xs_val *s = NULL;
166 int sz = 0;
167 char *p;
168
169 p = (char *)data;
170
171 /* size of data must be a multiple of 8 */
172 if (strlen(p) % 8)
173 return NULL;
174
175 for (p = (char *)data; *p; p += 8) {
176 int cs[8];
177 int n;
178 unsigned char tmp[5];
179
180 for (n = 0; n < 8; n++) {
181 char *ss = strchr(b32_tbl, p[n]);
182
183 if (ss == NULL) {
184 /* not a base32 char */
185 return xs_free(s);
186 }
187
188 cs[n] = ss - b32_tbl;
189 }
190
191 n = 0;
192
193 /* #0 byte */
194 tmp[n++] = cs[0] << 3 | cs[1] >> 2;
195
196 if (cs[2] != 32) {
197 /* #1 byte */
198 tmp[n++] = (cs[1] & 0x3) << 6 | cs[2] << 1 | (cs[3] & 0x10) >> 4;
199
200 if (cs[4] != 32) {
201 /* #2 byte */
202 tmp[n++] = (cs[3] & 0xf) << 4 | cs[4] >> 1;
203
204 if (cs[5] != 32) {
205 /* #3 byte */
206 tmp[n++] = (cs[4] & 0x1) << 7 | cs[5] << 2 | cs[6] >> 3;
207
208 if (cs[7] != 32) {
209 /* #4 byte */
210 tmp[n++] = (cs[6] & 0x7) << 5 | cs[7];
211 }
212 }
213 }
214 }
215
216 /* must be done manually because data can be pure binary */
217 s = xs_realloc(s, _xs_blk_size(sz + n));
218 memcpy(s + sz, tmp, n);
219 sz += n;
220 }
221
222 /* asciiz it to use it as a string */
223 s = xs_realloc(s, _xs_blk_size(sz + 1));
224 s[sz] = '\0';
225
226 *size = sz;
227
228 return s;
229}
230
231
232xs_val *xs_base32_dec(const xs_str *data, int *size)
233/* decodes data from base32 */
234{
235 return xs_base32_dec_tbl(data, size, xs_b32_tbl);
236}
237
238
239xs_val *xs_base32hex_dec(const xs_str *data, int *size)
240/* decodes data from base32 with HEX alphabet (RFC4648) */
241{
242 return xs_base32_dec_tbl(data, size, xs_b32hex_tbl);
243}
244
245
246/** base64 */ 83/** base64 */
247 84
248static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 85static char *xs_b64_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
diff --git a/xs_version.h b/xs_version.h
index c038df3..d2b2069 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
/* d8ec27efc55ba67403e88bfbe7d2ce9905364d6d */ /* 01bea7d4a0e631c0406b358dda9cc9409362c003 */