-
Notifications
You must be signed in to change notification settings - Fork 625
/
base64.c
126 lines (106 loc) · 2.19 KB
/
base64.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
Tomato Firmware
Copyright (C) 2006-2009 Jonathan Zarate
*/
#include <stdio.h>
#include <string.h>
/*
111111 110000 000011 111111
0 1 2
echo -n "aaa" | uuencode -m -
begin-base64 644 -
YWFh
echo -n "a" | uuencode -m -
begin-base64 644 -
YQ==
echo -n "aa" | uuencode -m -
begin-base64 644 -
YWE=
*/
static const char base64_xlat[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_encode(const unsigned char *in, char *out, int inlen)
{
char *o;
o = out;
while (inlen >= 3) {
*out++ = base64_xlat[*in >> 2];
*out++ = base64_xlat[((*in << 4) & 0x3F) | (*(in + 1) >> 4)];
++in; // note: gcc complains if *(++in)
*out++ = base64_xlat[((*in << 2) & 0x3F) | (*(in + 1) >> 6)];
++in;
*out++ = base64_xlat[*in++ & 0x3F];
inlen -= 3;
}
if (inlen > 0) {
*out++ = base64_xlat[*in >> 2];
if (inlen == 2) {
*out++ = base64_xlat[((*in << 4) & 0x3F) | (*(in + 1) >> 4)];
++in;
*out++ = base64_xlat[((*in << 2) & 0x3F)];
}
else {
*out++ = base64_xlat[(*in << 4) & 0x3F];
*out++ = '=';
}
*out++ = '=';
}
return out - o;
}
int base64_decode(const char *in, unsigned char *out, int inlen)
{
char *p;
int n;
unsigned long x;
unsigned char *o;
char c;
o = out;
n = 0;
x = 0;
while (inlen-- > 0) {
if (*in == '=') break;
if ((p = strchr(base64_xlat, c = *in++)) == NULL) {
// printf("ignored - %x %c\n", c, c);
continue; // note: invalid characters are just ignored
}
x = (x << 6) | (p - base64_xlat);
if (++n == 4) {
*out++ = x >> 16;
*out++ = (x >> 8) & 0xFF;
*out++ = x & 0xFF;
n = 0;
x = 0;
}
}
if (n == 3) {
*out++ = x >> 10;
*out++ = (x >> 2) & 0xFF;
}
else if (n == 2) {
*out++ = x >> 4;
}
return out - o;
}
int base64_encoded_len(int len)
{
return ((len + 2) / 3) * 4;
}
int base64_decoded_len(int len)
{
return ((len + 3) / 4) * 3;
}
/*
int main(int argc, char **argv)
{
char *test = "a";
char buf[128];
char buf2[128];
const char *in;
int len;
memset(buf, 0, sizeof(buf));
base64_encode(test, buf, strlen(test));
printf("buf=%s\n", buf);
memset(buf2, 0, sizeof(buf2));
base64_decode(buf, buf2, base64_encoded_len(strlen(test)));
printf("buf2=%s\n", buf2);
}
*/