TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
base64_encoding.cpp
1
14#include <cassert>
15#include <cstdint>
16#include <iostream>
17
22namespace ciphers {
28namespace base64_encoding {
29// chars denoting the format for encoding and decoding array.
30// This array is already decided by
31// [RFC4648](https://tools.ietf.org/html/rfc4648#section-4) standard
32const std::string chars =
33 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
40std::string base64_encode(const std::string &input) {
41 std::string base64_string;
42 // base64 deals with 6-bit chars encoded as per chars, so
43 // we will always filter 6-bits from input.
44 for (uint32_t i = 0; i < input.size(); i += 3) {
45 char first_byte = input[i];
46 // Take first six bits of first character.
47 // Encode the first six bits with character defined in string `chars`
48 base64_string.push_back(chars[first_byte >> 2]);
49
50 if (i + 1 < input.size()) {
51 char second_byte = input[i + 1];
52 // Take remaining two bits of first character, and four first bits
53 // from second character Combine two numbers as 6-bit digits and
54 // encode by array chars (first two bits of first byte and next four
55 // of second byte)
56 base64_string.push_back(
57 chars[(((first_byte & 3) << 4) | ((second_byte & 0xF0) >> 4))]);
58
59 if (i + 2 < input.size()) {
60 char third_byte = input[i + 2];
61 // Take remaining four bits of second character, and first two
62 // bits from third character Combine two numbers as 6-bit digits
63 // and encode by array chars (remaining four bits of second byte
64 // and first two of third byte)
65 base64_string.push_back(chars[((third_byte & 0xC0) >> 6) |
66 ((second_byte & 0x0F) << 2)]);
67 // Encode remaining 6-bit of third byte by array chars
68 base64_string.push_back(chars[(third_byte & 0x3F)]);
69 } else {
70 // Take remaining four bits of second character as 6-bit number
71 base64_string.push_back(chars[((second_byte & 0x0F) << 2)]);
72 base64_string.push_back('='); // padding characters
73 }
74 } else {
75 // Take remaining two bits of first character as 6-bit number
76 base64_string.push_back(chars[((first_byte & 3) << 4)]);
77 base64_string.push_back('='); // padding characters
78 base64_string.push_back('='); // padding characters
79 }
80 }
81 return base64_string;
82}
90uint8_t find_idx(const char c) {
91 if (c >= 'A' && c <= 'Z') {
92 return c - 'A';
93 } else if (c >= 'a' && c <= 'z') {
94 return c - 'a' + 26;
95 } else if (c >= '0' && c <= '9') {
96 return c - '0' + 52;
97 } else if (c == '+') {
98 return 62;
99 } else if (c == '/') {
100 return 63;
101 }
102 return -1;
103}
110std::string base64_decode(const std::string &base64_str) {
111 std::string
112 base64_decoded;
113 for (uint32_t i = 0; i < base64_str.size(); i += 4) {
115 char first_byte = base64_str[i];
117 char second_byte = base64_str[i + 1];
118 // Actual str characters are of 8 bits (or 1 byte):
119 // :: 8 bits are decode by taking 6 bits from 1st byte of base64 string
120 // and first 2 bits from 2nd byte of base64 string.
121 char first_actual_byte = static_cast<char>(
122 (find_idx(first_byte) << 2) | ((find_idx(second_byte)) >> 4));
123 base64_decoded.push_back(first_actual_byte);
124 if (i + 2 < base64_str.size() && base64_str[i + 2] != '=') {
126 char third_byte = base64_str[i + 2];
127 // :: Next 8 bits are decode by taking remaining 4 bits from 2nd
128 // byte of base64 string and first 4 bits from 3rd byte of base64
129 // string.
130 char second_actual_byte =
131 static_cast<char>(((find_idx(second_byte) & 0x0F) << 4) |
132 (find_idx(third_byte) >> 2));
133 base64_decoded.push_back(second_actual_byte);
134
135 if (i + 3 < base64_str.size() && base64_str[i + 3] != '=') {
137 char fourth_byte = base64_str[i + 3];
138 // :: Taking remaining 2 bits from 3rd byte of base64 string
139 // and all 6 bits from 4th byte of base64 string.
140 char third_actual_byte =
141 static_cast<char>(((find_idx(third_byte) & 0x03) << 6) |
142 find_idx(fourth_byte));
143 base64_decoded.push_back(third_actual_byte);
144 }
145 }
146 }
147 return base64_decoded;
148}
149} // namespace base64_encoding
150} // namespace ciphers
151
156static void test() {
157 // 1st Test
158 std::string str =
159 "To err is human, but to really foul things up you need a computer.";
160 std::string base64_str = ciphers::base64_encoding::base64_encode(str);
161 std::string verify =
162 "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZW"
163 "VkIGEgY29tcHV0ZXIu";
164 // verify encoding
165 assert(base64_str == verify);
166 std::string original_str =
167 ciphers::base64_encoding::base64_decode(base64_str);
168 // verify decoding
169 assert(original_str == str);
170
171 // 2nd Test from [Wikipedia](https://en.wikipedia.org/wiki/Base64)
172 str =
173 "Man is distinguished, not only by his reason, but by this singular "
174 "passion from other animals, which is a lust of the mind, that by a "
175 "perseverance of delight in the continued and indefatigable generation "
176 "of knowledge, exceeds the short vehemence of any carnal pleasure.";
177
178 base64_str = ciphers::base64_encoding::base64_encode(str);
179 verify =
180 "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
181 "B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBh"
182 "IGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodC"
183 "BpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25v"
184 "d2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbG"
185 "Vhc3VyZS4=";
186 // verify encoding
187 assert(base64_str == verify);
188 original_str = ciphers::base64_encoding::base64_decode(base64_str);
189 // verify decoding
190 assert(original_str == str);
191}
192
197int main() {
198 test(); // run self-test implementations
199 return 0;
200}
static void test()
Self-test implementations.
int main()
Main function.
Functions for Base64 Encoding and Decoding implementation.
Algorithms for encryption and decryption.