2 base64.cpp and base64.h
4 Copyright (C) 2004-2008 René Nyffenegger
6 This source code is provided 'as-is', without any express or implied
7 warranty. In no event will the author be held liable for any damages
8 arising from the use of this software.
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
14 1. The origin of this source code must not be misrepresented; you must not
15 claim that you wrote the original source code. If you use this source code
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
19 2. Altered source versions must be plainly marked as such, and must not be
20 misrepresented as being the original source code.
22 3. This notice may not be removed or altered from any source distribution.
24 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
31 static const std::string base64_chars =
32 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33 "abcdefghijklmnopqrstuvwxyz"
36 static const std::string base64_chars_padding_1 = "AEIMQUYcgkosw048";
37 static const std::string base64_chars_padding_2 = "AQgw";
39 static inline bool is_base64(unsigned char c)
41 return (c >= '0' && c <= '9')
42 || (c >= 'A' && c <= 'Z')
43 || (c >= 'a' && c <= 'z')
44 || c == '+' || c == '/';
47 bool base64_is_valid(std::string const& s)
50 for (; i < s.size(); ++i)
53 unsigned char padding = 3 - ((i + 3) % 4);
54 if ((padding == 1 && base64_chars_padding_1.find(s[i - 1]) == std::string::npos)
55 || (padding == 2 && base64_chars_padding_2.find(s[i - 1]) == std::string::npos)
58 int actual_padding = s.size() - i;
59 // omission of padding characters is allowed
60 if (actual_padding == 0)
63 // remaining characters (max. 2) may only be padding
64 for (; i < s.size(); ++i)
67 // number of padding characters needs to match
68 return padding == actual_padding;
71 std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
75 unsigned char char_array_3[3];
76 unsigned char char_array_4[4];
79 char_array_3[i++] = *(bytes_to_encode++);
81 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
82 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
83 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
84 char_array_4[3] = char_array_3[2] & 0x3f;
86 for(i = 0; (i <4) ; i++)
87 ret += base64_chars[char_array_4[i]];
94 for(j = i; j < 3; j++)
95 char_array_3[j] = '\0';
97 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
98 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
99 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
100 char_array_4[3] = char_array_3[2] & 0x3f;
102 for (j = 0; (j < i + 1); j++)
103 ret += base64_chars[char_array_4[j]];
105 // Don't pad it with =
115 std::string base64_decode(std::string const& encoded_string) {
116 int in_len = encoded_string.size();
120 unsigned char char_array_4[4], char_array_3[3];
123 while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
124 char_array_4[i++] = encoded_string[in_]; in_++;
126 for (i = 0; i <4; i++)
127 char_array_4[i] = base64_chars.find(char_array_4[i]);
129 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
130 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
131 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
133 for (i = 0; (i < 3); i++)
134 ret += char_array_3[i];
140 for (j = i; j <4; j++)
143 for (j = 0; j <4; j++)
144 char_array_4[j] = base64_chars.find(char_array_4[j]);
146 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
147 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
148 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
150 for (j = 0; (j < i - 1); j++) ret += char_array_3[j];