SNode.C
Loading...
Searching...
No Matches
base64.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - A Slim Toolkit for Network Communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * MIT License
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42#ifndef DOXYGEN_SHOULD_SKIP_THIS
43
44#include "utils/base64.h"
45
46#include "utils/sha1.h"
47
48#include <cctype>
49#include <string>
50#include <vector>
51
52#endif /* DOXYGEN_SHOULD_SKIP_THIS */
53
54namespace base64 {
55
56 std::string serverWebSocketKey(const std::string& clientWebSocketKey) {
57 const std::string GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
58
59 const std::string serverWebSocketKey(clientWebSocketKey + GUID);
60 std::vector<unsigned char> digest = utils::sha1(serverWebSocketKey);
61
62 return base64_encode(digest.data(), digest.size());
63 }
64
65 static bool is_base64(char c) {
66 return ((isalnum(c) != 0) || (c == '+') || (c == '/'));
67 }
68
69 std::string base64_encode(const unsigned char* bytes_to_encode, std::size_t length) {
70 static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
71 "abcdefghijklmnopqrstuvwxyz"
72 "0123456789+/";
73 std::string ret;
74 int i = 0;
75 unsigned char char_array_3[3];
76 unsigned char char_array_4[4];
77
78 while (length-- > 0) {
79 char_array_3[i++] = *(bytes_to_encode++);
80 if (i == 3) {
81 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
82 char_array_4[1] = static_cast<unsigned char>(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4));
83 char_array_4[2] = static_cast<unsigned char>(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6));
84 char_array_4[3] = char_array_3[2] & 0x3f;
85
86 for (i = 0; i < 4; i++) {
87 ret += base64_chars[char_array_4[i]];
88 }
89 i = 0;
90 }
91 }
92
93 if (i != 0) {
94 for (int j = i; j < 3; j++) {
95 char_array_3[j] = '\0';
96 }
97
98 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
99 char_array_4[1] = static_cast<unsigned char>(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4));
100 char_array_4[2] = static_cast<unsigned char>(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6));
101 char_array_4[3] = char_array_3[2] & 0x3f;
102
103 for (int j = 0; j < i + 1; j++) {
104 ret += base64_chars[char_array_4[j]];
105 }
106
107 while (i++ < 3) {
108 ret += '=';
109 }
110 }
111
112 return ret;
113 }
114
115 std::string base64_decode(const std::string& encoded_string) {
116 static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
117 "abcdefghijklmnopqrstuvwxyz"
118 "0123456789+/";
119 std::string::size_type in_len = encoded_string.size();
120 std::string::size_type i = 0;
121 std::string::size_type in_ = 0;
122 char char_array_4[4];
123 char char_array_3[3];
124 std::string ret;
125
126 while (in_len-- > 0 && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
127 char_array_4[i++] = encoded_string[in_];
128 in_++;
129 if (i == 4) {
130 for (i = 0; i < 4; i++) {
131 char_array_4[i] = static_cast<char>(base64_chars.find(char_array_4[i]));
132 }
133
134 char_array_3[0] = static_cast<char>((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4));
135 char_array_3[1] = static_cast<char>(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2));
136 char_array_3[2] = static_cast<char>(((char_array_4[2] & 0x3) << 6) + char_array_4[3]);
137
138 for (i = 0; (i < 3); i++) {
139 ret += char_array_3[i];
140 }
141 i = 0;
142 }
143 }
144
145 if (i != 0) {
146 for (std::string::size_type j = i; j < 4; j++) {
147 char_array_4[j] = 0;
148 }
149
150 for (std::string::size_type j = 0; j < 4; j++) {
151 char_array_4[j] = static_cast<char>(base64_chars.find(char_array_4[j]));
152 }
153
154 char_array_3[0] = static_cast<char>((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4));
155 char_array_3[1] = static_cast<char>(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2));
156 char_array_3[2] = static_cast<char>(((char_array_4[2] & 0x3) << 6) + char_array_4[3]);
157
158 for (std::string::size_type j = 0; j < i - 1; j++) {
159 ret += char_array_3[j];
160 }
161 }
162
163 return ret;
164 }
165} // namespace base64
std::string base64_decode(const std::string &encoded_string)
Definition base64.cpp:115
std::string serverWebSocketKey(const std::string &clientWebSocketKey)
Definition base64.cpp:56
static bool is_base64(char c)
Definition base64.cpp:65
std::string base64_encode(const unsigned char *bytes_to_encode, std::size_t length)
Definition base64.cpp:69