]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/base64.c
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * AUTHOR: Markus Moeller
12 * Encoders adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments.
22 static void base64_init(void);
24 static int base64_initialized
= 0;
25 #define BASE64_VALUE_SZ 256
26 #define BASE64_RESULT_SZ 8192
27 int base64_value
[BASE64_VALUE_SZ
];
28 const char base64_code
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
35 for (i
= 0; i
< BASE64_VALUE_SZ
; i
++)
38 for (i
= 0; i
< 64; i
++)
39 base64_value
[(int) base64_code
[i
]] = i
;
40 base64_value
['='] = 0;
42 base64_initialized
= 1;
46 base64_decode_len(const char *data
)
51 int terminatorLen
= 0;
52 int dataLen
= strlen(data
);
55 for (i
= dataLen
- 1; i
>= 0; i
--) {
61 return dataLen
/ 4 * 3 - terminatorLen
;
65 base64_decode(char *result
, unsigned int result_size
, const char *p
)
70 if (!p
|| !result
|| result_size
== 0)
72 if (!base64_initialized
)
76 unsigned int k
= ((unsigned char) *p
) % BASE64_VALUE_SZ
;
77 if (base64_value
[k
] < 0)
80 val
+= base64_value
[k
];
83 /* One quantum of four encoding characters/24 bit */
84 if (j
+4 <= result_size
) {
85 // Speed optimization: plenty of space, avoid some per-byte checks.
86 result
[j
++] = (val
>> 16) & 0xff; /* High 8 bits */
87 result
[j
++] = (val
>> 8) & 0xff; /* Mid 8 bits */
88 result
[j
++] = val
& 0xff; /* Low 8 bits */
90 // part-quantum goes a bit slower with per-byte checks
91 result
[j
++] = (val
>> 16) & 0xff; /* High 8 bits */
94 result
[j
++] = (val
>> 8) & 0xff; /* Mid 8 bits */
97 result
[j
++] = val
& 0xff; /* Low 8 bits */
107 base64_encode_len(int len
)
109 // NP: some magic numbers + potential nil-terminator
110 return ((len
+ 2) / 3 * 4) + 1;
114 old_base64_encode(const char *decoded_str
)
116 static char result
[BASE64_RESULT_SZ
];
117 base64_encode_str(result
, sizeof(result
), decoded_str
, strlen(decoded_str
));
122 base64_encode_bin(const char *decoded_str
, int len
)
124 static char result
[BASE64_RESULT_SZ
];
125 base64_encode_str(result
, sizeof(result
), decoded_str
, len
);
130 base64_encode_str(char *result
, int result_max_size
, const char *data
, int data_size
)
132 if (result_max_size
< 1)
135 int used
= base64_encode(result
, result_max_size
, data
, data_size
);
137 if (used
>= result_max_size
) {
138 result
[result_max_size
- 1] = '\0';
139 return result_max_size
;
141 result
[used
++] = '\0';
146 /* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
148 base64_encode(char *result
, int result_size
, const char *data
, int data_size
)
154 if (!data
|| !*data
|| !result
|| result_size
< 1 || data_size
< 1)
157 if (!base64_initialized
)
160 while (data_size
--) {
161 int c
= (unsigned char) *data
++;
164 if (char_count
== 3) {
165 if (out_cnt
>= result_size
)
167 if (out_cnt
+4 <= result_size
) {
168 result
[out_cnt
++] = base64_code
[bits
>> 18];
169 result
[out_cnt
++] = base64_code
[(bits
>> 12) & 0x3f];
170 result
[out_cnt
++] = base64_code
[(bits
>> 6) & 0x3f];
171 result
[out_cnt
++] = base64_code
[bits
& 0x3f];
173 // part-quantum goes a bit slower with per-byte checks
174 result
[out_cnt
++] = base64_code
[bits
>> 18];
175 if (out_cnt
>= result_size
)
177 result
[out_cnt
++] = base64_code
[(bits
>> 12) & 0x3f];
178 if (out_cnt
>= result_size
)
180 result
[out_cnt
++] = base64_code
[(bits
>> 6) & 0x3f];
181 if (out_cnt
>= result_size
)
183 result
[out_cnt
++] = base64_code
[bits
& 0x3f];
191 if (char_count
!= 0) {
192 bits
<<= 16 - (8 * char_count
);
193 if (out_cnt
>= result_size
)
195 result
[out_cnt
++] = base64_code
[bits
>> 18];
196 if (out_cnt
>= result_size
)
198 result
[out_cnt
++] = base64_code
[(bits
>> 12) & 0x3f];
199 if (char_count
== 1) {
200 if (out_cnt
>= result_size
)
202 result
[out_cnt
++] = '=';
203 if (out_cnt
>= result_size
)
205 result
[out_cnt
++] = '=';
207 if (out_cnt
>= result_size
)
209 result
[out_cnt
++] = base64_code
[(bits
>> 6) & 0x3f];
210 if (out_cnt
>= result_size
)
212 result
[out_cnt
++] = '=';
215 return (out_cnt
>= result_size
?result_size
:out_cnt
);