• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  *
3  * Copyright 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com
4  * Copyright 2017 Matthieu Darbois
5  * All rights reserved.
6  *
7  * http://modp.com/release/base64
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  *  this list of conditions and the following disclaimer.
15  *
16  * - Redistributions in binary form must reproduce the above copyright
17  *   notice, this list of conditions and the following disclaimer in the
18  *   documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 /****************************/
35 
36 #include <stdint.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <inttypes.h>
41 
42 static uint8_t b64chars[64] = {
43 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
44 	'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
45 	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
46 	'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
47 	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
48 };
49 
50 static uint8_t padchar = '=';
51 
printStart(void)52 static void printStart(void)
53 {
54 	printf("#include <stdint.h>\n");
55 	printf("#define CHAR62 '%c'\n", b64chars[62]);
56 	printf("#define CHAR63 '%c'\n", b64chars[63]);
57 	printf("#define CHARPAD '%c'\n", padchar);
58 }
59 
clearDecodeTable(uint32_t * ary)60 static void clearDecodeTable(uint32_t* ary)
61 {
62 	int i = 0;
63 	for (i = 0; i < 256; ++i) {
64 		ary[i] = 0xFFFFFFFF;
65 	}
66 }
67 
68 /* dump uint32_t as hex digits */
uint32_array_to_c_hex(const uint32_t * ary,size_t sz,const char * name)69 void uint32_array_to_c_hex(const uint32_t* ary, size_t sz, const char* name)
70 {
71 	size_t i = 0;
72 
73 	printf("const uint32_t %s[%d] = {\n", name, (int)sz);
74 	for (;;) {
75 		printf("0x%08" PRIx32, ary[i]);
76 		++i;
77 		if (i == sz)
78 			break;
79 		if (i % 6 == 0) {
80 			printf(",\n");
81 		} else {
82 			printf(", ");
83 		}
84 	}
85 	printf("\n};\n");
86 }
87 
main(int argc,char ** argv)88 int main(int argc, char** argv)
89 {
90 	uint32_t x;
91 	uint32_t i = 0;
92 	uint32_t ary[256];
93 
94 	/*  over-ride standard alphabet */
95 	if (argc == 2) {
96 		uint8_t* replacements = (uint8_t*)argv[1];
97 		if (strlen((char*)replacements) != 3) {
98 			fprintf(stderr, "input must be a string of 3 characters '-', '.' or '_'\n");
99 			exit(1);
100 		}
101 		fprintf(stderr, "fusing '%s' as replacements in base64 encoding\n", replacements);
102 		b64chars[62] = replacements[0];
103 		b64chars[63] = replacements[1];
104 		padchar = replacements[2];
105 	}
106 
107 	printStart();
108 
109 	printf("\n\n#if BASE64_LITTLE_ENDIAN\n");
110 
111 	printf("\n\n/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */\n\n");
112 
113 	clearDecodeTable(ary);
114 	for (i = 0; i < 64; ++i) {
115 		x = b64chars[i];
116 		ary[x] = i << 2;
117 	}
118 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d0");
119 	printf("\n\n");
120 
121 	clearDecodeTable(ary);
122 	for (i = 0; i < 64; ++i) {
123 		x = b64chars[i];
124 		ary[x] = ((i & 0x30) >> 4) | ((i & 0x0F) << 12);
125 	}
126 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d1");
127 	printf("\n\n");
128 
129 	clearDecodeTable(ary);
130 	for (i = 0; i < 64; ++i) {
131 		x = b64chars[i];
132 		ary[x] = ((i & 0x03) << 22) | ((i & 0x3c) << 6);
133 	}
134 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d2");
135 	printf("\n\n");
136 
137 	clearDecodeTable(ary);
138 	for (i = 0; i < 64; ++i) {
139 		x = b64chars[i];
140 		ary[x] = i << 16;
141 	}
142 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d3");
143 	printf("\n\n");
144 
145 	printf("#else\n");
146 
147 	printf("\n\n/* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */\n\n");
148 
149 	clearDecodeTable(ary);
150 	for (i = 0; i < 64; ++i) {
151 		x = b64chars[i];
152 		ary[x] = i << 26;
153 	}
154 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d0");
155 	printf("\n\n");
156 
157 	clearDecodeTable(ary);
158 	for (i = 0; i < 64; ++i) {
159 		x = b64chars[i];
160 		ary[x] = i << 20;
161 	}
162 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d1");
163 	printf("\n\n");
164 
165 	clearDecodeTable(ary);
166 	for (i = 0; i < 64; ++i) {
167 		x = b64chars[i];
168 		ary[x] = i << 14;
169 	}
170 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d2");
171 	printf("\n\n");
172 
173 	clearDecodeTable(ary);
174 	for (i = 0; i < 64; ++i) {
175 		x = b64chars[i];
176 		ary[x] = i << 8;
177 	}
178 	uint32_array_to_c_hex(ary, sizeof(ary) / sizeof(uint32_t), "base64_table_dec_32bit_d3");
179 	printf("\n\n");
180 
181 	printf("#endif\n");
182 
183 	return 0;
184 }
185