2 * Generic base 64 input and output routines
4 * Written by Kern E. Sibbald, March MM.
9 Copyright (C) 2000-2006 Kern Sibbald
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 version 2 as amended with additional clauses defined in the
14 file LICENSE in the main source directory.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 the file LICENSE for additional details.
26 const bool compatible = true;
33 static uint8_t const base64_digits[64] =
35 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
36 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
37 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
38 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
39 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
42 static int base64_inited = 0;
43 static uint8_t base64_map[128];
46 /* Initialize the Base 64 conversion routines */
51 memset(base64_map, 0, sizeof(base64_map));
53 base64_map[(uint8_t)base64_digits[i]] = i;
57 /* Convert a value to base64 characters.
58 * The result is stored in where, which
59 * must be at least 8 characters long.
61 * Returns the number of characters
62 * stored (not including the EOS).
65 to_base64(intmax_t value, char *where)
71 /* Handle negative values */
77 /* Determine output size */
85 /* Output characters */
89 where[--i] = base64_digits[val & (uintmax_t)0x3F];
96 * Convert the Base 64 characters in where to
97 * a value. No checking is done on the validity
103 from_base64(intmax_t *value, char *where)
110 /* Check if it is negative */
112 if (where[i] == '-') {
116 /* Construct value */
117 while (where[i] != 0 && where[i] != ' ') {
119 val += base64_map[(uint8_t)where[i++]];
122 *value = neg ? -(intmax_t)val : (intmax_t)val;
128 * Encode binary data in bin of len bytes into
129 * buf as base64 characters.
131 * Returns: the number of characters stored not
135 bin_to_base64(char *buf, char *bin, int len)
137 uint32_t reg, save, mask;
147 reg |= (int8_t)bin[i++] & 0xFF;
149 reg |= (int8_t)bin[i++];
155 buf[j++] = base64_digits[reg & (uint32_t)0x3F];
161 for (i=1; i<rem; i++) {
162 mask = (mask << 1) | 1;
165 buf[j++] = base64_digits[(reg & mask) << 6 - rem];
167 buf[j++] = base64_digits[reg & mask];
175 int main(int argc, char *argv[])
184 for (i=0; i < 1000; i++) {
185 bin_to_base64(buf, (char *)&xx, 4);
186 printf("xx=%s\n", buf);
191 for (i=1; i<100; i++) {
192 junk[i] = junk[i-1]-1;
194 len = bin_to_base64(buf, junk, 16);
195 printf("len=%d junk=%s\n", len, buf);
201 static int errfunc(const char *epath, int eernoo)
203 printf("in errfunc\n");
209 * Test the base64 routines by encoding and decoding
212 int main(int argc, char *argv[])
222 time_t t = 1028712799;
224 if (argc > 1 && strcmp(argv[1], "-v") == 0)
230 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
232 for (i=0; my_glob.gl_pathv[i]; i++) {
233 fname = my_glob.gl_pathv[i];
234 if (lstat(fname, &statp) < 0) {
235 printf("Cannot stat %s: %s\n", fname, strerror(errno));
238 encode_stat(where, &statp);
240 printf("Encoded stat=%s\n", where);
244 p += to_base64((intmax_t)(statp.st_atime), p);
246 p += to_base64((intmax_t)t, p);
247 printf("%s %s\n", fname, where);
249 printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
250 printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
251 printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
252 printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
253 printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
254 printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
255 printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
256 printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
257 printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
258 printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
259 printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
260 printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
261 printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
265 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
267 decode_stat(where, &statn);
269 if (statp.st_dev != statn.st_dev ||
270 statp.st_ino != statn.st_ino ||
271 statp.st_mode != statn.st_mode ||
272 statp.st_nlink != statn.st_nlink ||
273 statp.st_uid != statn.st_uid ||
274 statp.st_gid != statn.st_gid ||
275 statp.st_rdev != statn.st_rdev ||
276 statp.st_size != statn.st_size ||
277 statp.st_blksize != statn.st_blksize ||
278 statp.st_blocks != statn.st_blocks ||
279 statp.st_atime != statn.st_atime ||
280 statp.st_mtime != statn.st_mtime ||
281 statp.st_ctime != statn.st_ctime) {
283 printf("%s: %s\n", fname, where);
284 encode_stat(where, &statn);
285 printf("%s: %s\n", fname, where);
286 printf("NOT EQAL\n");
292 printf("%d files examined\n", i);
294 to_base64(UINT32_MAX, where);
295 printf("UINT32_MAX=%s\n", where);