2 https://github.com/superwills/NibbleAndAHalf
3 base64.h -- Fast base64 encoding and decoding.
4 version 1.0.0, April 17, 2013 143a
5 Copyright (C) 2013 William Sherif
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
21 YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz
24 Modified for RetroArch formatting, logging, and header files.
30 #include <encodings/base64.h>
32 const static char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
34 /* maps A=>0,B=>1.. */
35 const static unsigned char unb64[]={
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
41 54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
42 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
43 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
44 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
45 25, 0, 0, 0, 0, 0, 0, 26, 27, 28,
46 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
47 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
48 49, 50, 51, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 }; /* This array has 256 elements */
65 Converts binary data of length=len to base64 characters.
66 Length of the resultant string is stored in flen
67 (you must pass pointer flen).
69 char* base64(const void* binaryData, int len, int *flen)
72 int byteNo; /* I need this after the loop */
73 const unsigned char* bin = (const unsigned char*) binaryData;
74 int rc = 0; /* result counter */
75 int modulusLen = len % 3 ;
76 /* 2 gives 1 and 1 gives 2, but 0 gives 0. */
77 int pad = ((modulusLen&1)<<1) + ((modulusLen&2)>>1);
79 *flen = 4*(len + pad)/3;
80 if (!(res = (char*) malloc(*flen + 1))) /* and one for the NULL */
83 for (byteNo=0; byteNo <= len-3; byteNo+=3)
85 unsigned char BYTE0 = bin[byteNo];
86 unsigned char BYTE1 = bin[byteNo+1];
87 unsigned char BYTE2 = bin[byteNo+2];
89 res[rc++] = b64[BYTE0 >> 2];
90 res[rc++] = b64[((0x3&BYTE0)<<4) + (BYTE1 >> 4)];
91 res[rc++] = b64[((0x0f&BYTE1)<<2) + (BYTE2>>6)];
92 res[rc++] = b64[0x3f&BYTE2];
97 res[rc++] = b64[bin[byteNo] >> 2];
98 res[rc++] = b64[(0x3&bin[byteNo])<<4];
104 res[rc++] = b64[bin[byteNo] >> 2];
105 res[rc++] = b64[((0x3&bin[byteNo])<<4) + (bin[byteNo+1] >> 4)];
106 res[rc++] = b64[(0x0f&bin[byteNo+1])<<2];
110 res[rc]=0; /* NULL TERMINATOR! ;) */
114 unsigned char* unbase64(const char* ascii, int len, int *flen)
118 const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
122 if (len < 2) /* 2 accesses below would be OOB (Out Of Bounds). */
124 /* catch empty string, return NULL as result. */
125 /* ERROR: You passed an invalid base64 string (too short).
126 * You get NULL back. */
131 if (safeAsciiPtr[len-1]=='=')
133 if (safeAsciiPtr[len-2]=='=')
136 *flen = 3*len/4 - pad;
137 if (!(bin = (unsigned char*)malloc(*flen)))
140 for (charNo=0; charNo <= len-4-pad; charNo+=4)
142 int A = unb64[safeAsciiPtr[charNo]];
143 int B = unb64[safeAsciiPtr[charNo+1]];
144 int C = unb64[safeAsciiPtr[charNo+2]];
145 int D = unb64[safeAsciiPtr[charNo+3]];
147 bin[cb++] = (A<<2) | (B>>4);
148 bin[cb++] = (B<<4) | (C>>2);
149 bin[cb++] = (C<<6) | (D);
154 int A = unb64[safeAsciiPtr[charNo]];
155 int B = unb64[safeAsciiPtr[charNo+1]];
156 int C = unb64[safeAsciiPtr[charNo+2]];
158 bin[cb++] = (A<<2) | (B>>4);
159 bin[cb++] = (B<<4) | (C>>2);
163 int A = unb64[safeAsciiPtr[charNo]];
164 int B = unb64[safeAsciiPtr[charNo+1]];
166 bin[cb++] = (A<<2) | (B>>4);