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.
32 static uint8_t const base64_digits[64] =
34 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
35 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
36 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
37 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
38 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
41 static int base64_inited = 0;
42 static uint8_t base64_map[128];
45 /* Initialize the Base 64 conversion routines */
50 memset(base64_map, 0, sizeof(base64_map));
52 base64_map[(uint8_t)base64_digits[i]] = i;
56 /* Convert a value to base64 characters.
57 * The result is stored in where, which
58 * must be at least 8 characters long.
60 * Returns the number of characters
61 * stored (not including the EOS).
64 to_base64(intmax_t value, char *where)
70 /* Handle negative values */
76 /* Determine output size */
84 /* Output characters */
88 where[--i] = base64_digits[val & (uintmax_t)0x3F];
95 * Convert the Base 64 characters in where to
96 * a value. No checking is done on the validity
102 from_base64(intmax_t *value, char *where)
109 /* Check if it is negative */
111 if (where[i] == '-') {
115 /* Construct value */
116 while (where[i] != 0 && where[i] != ' ') {
118 val += base64_map[(uint8_t)where[i++]];
121 *value = neg ? -(intmax_t)val : (intmax_t)val;
127 * Encode binary data in bin of len bytes into
128 * buf as base64 characters.
130 * If compatible is true, the bin_to_base64 routine will be compatible
131 * with what the rest of the world uses.
133 * Returns: the number of characters stored not
137 bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
139 uint32_t reg, save, mask;
145 buflen--; /* allow for storing EOS */
146 for (i=0; i < binlen; ) {
150 reg |= (uint8_t)bin[i++];
152 reg |= (int8_t)bin[i++];
159 buf[j++] = base64_digits[reg & 0x3F];
164 if (rem && j < buflen) {
165 mask = (1 << rem) - 1;
167 buf[j++] = base64_digits[(reg & mask) << 6 - rem];
169 buf[j++] = base64_digits[reg & mask];
177 int main(int argc, char *argv[])
186 for (i=0; i < 1000; i++) {
187 bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
188 printf("xx=%s\n", buf);
193 for (i=1; i<100; i++) {
194 junk[i] = junk[i-1]-1;
196 len = bin_to_base64(buf, sizeof(buf) junk, 16, true);
197 printf("len=%d junk=%s\n", len, buf);
203 static int errfunc(const char *epath, int eernoo)
205 printf("in errfunc\n");
211 * Test the base64 routines by encoding and decoding
214 int main(int argc, char *argv[])
224 time_t t = 1028712799;
226 if (argc > 1 && strcmp(argv[1], "-v") == 0)
232 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
234 for (i=0; my_glob.gl_pathv[i]; i++) {
235 fname = my_glob.gl_pathv[i];
236 if (lstat(fname, &statp) < 0) {
237 printf("Cannot stat %s: %s\n", fname, strerror(errno));
240 encode_stat(where, &statp);
242 printf("Encoded stat=%s\n", where);
246 p += to_base64((intmax_t)(statp.st_atime), p);
248 p += to_base64((intmax_t)t, p);
249 printf("%s %s\n", fname, where);
251 printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
252 printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
253 printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
254 printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
255 printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
256 printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
257 printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
258 printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
259 printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
260 printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
261 printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
262 printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
263 printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
267 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
269 decode_stat(where, &statn);
271 if (statp.st_dev != statn.st_dev ||
272 statp.st_ino != statn.st_ino ||
273 statp.st_mode != statn.st_mode ||
274 statp.st_nlink != statn.st_nlink ||
275 statp.st_uid != statn.st_uid ||
276 statp.st_gid != statn.st_gid ||
277 statp.st_rdev != statn.st_rdev ||
278 statp.st_size != statn.st_size ||
279 statp.st_blksize != statn.st_blksize ||
280 statp.st_blocks != statn.st_blocks ||
281 statp.st_atime != statn.st_atime ||
282 statp.st_mtime != statn.st_mtime ||
283 statp.st_ctime != statn.st_ctime) {
285 printf("%s: %s\n", fname, where);
286 encode_stat(where, &statn);
287 printf("%s: %s\n", fname, where);
288 printf("NOT EQAL\n");
294 printf("%d files examined\n", i);
296 to_base64(UINT32_MAX, where);
297 printf("UINT32_MAX=%s\n", where);