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.
27 * If compatible is true, the bin_to_base64 routine will be compatible
28 * with what the rest of the world uses. However, this would destroy
29 * existing database compatibility.
31 const bool compatible = false;
38 static uint8_t const base64_digits[64] =
40 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
41 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
42 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
43 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
44 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
47 static int base64_inited = 0;
48 static uint8_t base64_map[128];
51 /* Initialize the Base 64 conversion routines */
56 memset(base64_map, 0, sizeof(base64_map));
58 base64_map[(uint8_t)base64_digits[i]] = i;
62 /* Convert a value to base64 characters.
63 * The result is stored in where, which
64 * must be at least 8 characters long.
66 * Returns the number of characters
67 * stored (not including the EOS).
70 to_base64(intmax_t value, char *where)
76 /* Handle negative values */
82 /* Determine output size */
90 /* Output characters */
94 where[--i] = base64_digits[val & (uintmax_t)0x3F];
101 * Convert the Base 64 characters in where to
102 * a value. No checking is done on the validity
103 * of the characters!!
108 from_base64(intmax_t *value, char *where)
115 /* Check if it is negative */
117 if (where[i] == '-') {
121 /* Construct value */
122 while (where[i] != 0 && where[i] != ' ') {
124 val += base64_map[(uint8_t)where[i++]];
127 *value = neg ? -(intmax_t)val : (intmax_t)val;
133 * Encode binary data in bin of len bytes into
134 * buf as base64 characters.
136 * Returns: the number of characters stored not
140 bin_to_base64(char *buf, char *bin, int len)
142 uint32_t reg, save, mask;
152 reg |= (uint8_t)bin[i++];
154 reg |= (int8_t)bin[i++];
160 buf[j++] = base64_digits[reg & 0x3F];
167 for (i=1; i<rem; i++) {
168 mask = (mask << 1) | 1;
171 mask = (1 << rem) - 1;
174 buf[j++] = base64_digits[(reg & mask) << 6 - rem];
176 buf[j++] = base64_digits[reg & mask];
184 int main(int argc, char *argv[])
193 for (i=0; i < 1000; i++) {
194 bin_to_base64(buf, (char *)&xx, 4);
195 printf("xx=%s\n", buf);
200 for (i=1; i<100; i++) {
201 junk[i] = junk[i-1]-1;
203 len = bin_to_base64(buf, junk, 16);
204 printf("len=%d junk=%s\n", len, buf);
210 static int errfunc(const char *epath, int eernoo)
212 printf("in errfunc\n");
218 * Test the base64 routines by encoding and decoding
221 int main(int argc, char *argv[])
231 time_t t = 1028712799;
233 if (argc > 1 && strcmp(argv[1], "-v") == 0)
239 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
241 for (i=0; my_glob.gl_pathv[i]; i++) {
242 fname = my_glob.gl_pathv[i];
243 if (lstat(fname, &statp) < 0) {
244 printf("Cannot stat %s: %s\n", fname, strerror(errno));
247 encode_stat(where, &statp);
249 printf("Encoded stat=%s\n", where);
253 p += to_base64((intmax_t)(statp.st_atime), p);
255 p += to_base64((intmax_t)t, p);
256 printf("%s %s\n", fname, where);
258 printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
259 printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
260 printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
261 printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
262 printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
263 printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
264 printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
265 printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
266 printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
267 printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
268 printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
269 printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
270 printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
274 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
276 decode_stat(where, &statn);
278 if (statp.st_dev != statn.st_dev ||
279 statp.st_ino != statn.st_ino ||
280 statp.st_mode != statn.st_mode ||
281 statp.st_nlink != statn.st_nlink ||
282 statp.st_uid != statn.st_uid ||
283 statp.st_gid != statn.st_gid ||
284 statp.st_rdev != statn.st_rdev ||
285 statp.st_size != statn.st_size ||
286 statp.st_blksize != statn.st_blksize ||
287 statp.st_blocks != statn.st_blocks ||
288 statp.st_atime != statn.st_atime ||
289 statp.st_mtime != statn.st_mtime ||
290 statp.st_ctime != statn.st_ctime) {
292 printf("%s: %s\n", fname, where);
293 encode_stat(where, &statn);
294 printf("%s: %s\n", fname, where);
295 printf("NOT EQAL\n");
301 printf("%d files examined\n", i);
303 to_base64(UINT32_MAX, where);
304 printf("UINT32_MAX=%s\n", where);