ef1c6c99bc8f9f096f3bb04f4f24a94f7f7d6253
[openafs.git] / src / util / flipbase64.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  *
9  * Portions Copyright (c) 2003 Apple Computer, Inc.
10  */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16
17 #if defined(AFS_NAMEI_ENV)
18 #include <sys/types.h>
19 #include "afsutil.h"
20
21 /* This version of base64 gets it right and starts converting from the low
22  * bits to the high bits.
23  */
24 /* This table needs to be in lexical order to efficiently map back from
25  * characters to the numerical value.
26  *
27  * In c_reverse, we use 99 to represent an illegal value, rather than -1
28  * which would assume "char" is signed.
29  */
30 #ifdef AFS_DARWIN_ENV
31 static char c_xlate[80] =
32         "!\"#$%&()*+,-0123456789:;<=>?@[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
33 static char c_reverse[] = {
34     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
35     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
36     99,  0,  1,  2,  3,  4,  5, 99,  6,  7,  8,  9, 10, 11, 99, 99,
37     12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
38     28, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
39     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 29, 99, 30, 31, 32,
40     33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
41     49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 99,
42     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
43     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
44     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
45     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
46     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
47     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
48     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
49     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99
50 };
51 #else /* AFS_DARWIN_ENV */
52 static char c_xlate[80] =
53     "+=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
54 static char c_reverse[] = {
55     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
56     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
57     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,  0, 99, 99, 99, 99,
58      2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 99, 99, 99,  1, 99, 99,
59     99, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
60     27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 99, 99, 99, 99, 99,
61     99, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
62     53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 99, 99, 99, 99, 99,
63     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
64     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
65     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
66     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
67     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
68     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
69     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
70     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99
71 };
72 #endif /* AFS_DARWIN_ENV */
73
74 /* int_to_base64
75  * Create a base 64 string representation of a number.
76  * The supplied string 's' must be at least 12 bytes long.
77  * lb64_string in stds.h provides a typedef to get the length.
78  */
79 char *
80 int64_to_flipbase64(lb64_string_t s, afs_uint64 a)
81 {
82     int i;
83     afs_uint64 n;
84
85     i = 0;
86     if (a == 0)
87         s[i++] = c_xlate[0];
88     else {
89         for (n = a & 0x3f; a; n = ((a >>= 6) & 0x3f)) {
90             s[i++] = c_xlate[n];
91         }
92     }
93     s[i] = '\0';
94     return s;
95 }
96
97
98 afs_int64
99 flipbase64_to_int64(char *s)
100 {
101     afs_int64 n = 0;
102     afs_int64 result = 0;
103     int shift;
104
105     for (shift = 0; *s; s++) {
106         n = c_reverse[*(unsigned char *)s];
107         if (n >= 64)    /* should never happen */
108             continue;
109         n <<= shift;
110         result |= n ;
111         shift += 6;
112     }
113     return result;
114 }
115
116
117 #endif /* AFS_NAMEI_ENV */