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