]> git.lizzy.rs Git - minetest.git/blob - src/util/base64.cpp
Fix typos and en_US/en_GB inconsistency in various files (#12902)
[minetest.git] / src / util / base64.cpp
1 /*
2 base64.cpp and base64.h
3
4 Copyright (C) 2004-2008 RenĂ© Nyffenegger
5
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.
9
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:
13
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.
18
19 2. Altered source versions must be plainly marked as such, and must not be
20    misrepresented as being the original source code.
21
22 3. This notice may not be removed or altered from any source distribution.
23
24 RenĂ© Nyffenegger rene.nyffenegger@adp-gmbh.ch
25
26 */
27
28 #include "base64.h"
29 #include <iostream>
30
31 static const std::string base64_chars =
32                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33                 "abcdefghijklmnopqrstuvwxyz"
34                 "0123456789+/";
35
36 static const std::string base64_chars_padding_1 = "AEIMQUYcgkosw048";
37 static const std::string base64_chars_padding_2 = "AQgw";
38
39 static inline bool is_base64(unsigned char c)
40 {
41         return (c >= '0' && c <= '9')
42                         || (c >= 'A' && c <= 'Z')
43                         || (c >= 'a' && c <= 'z')
44                         || c == '+' || c == '/';
45 }
46
47 bool base64_is_valid(std::string const& s)
48 {
49         size_t i = 0;
50         for (; i < s.size(); ++i)
51                 if (!is_base64(s[i]))
52                         break;
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)
56                         || padding == 3)
57                 return false;
58         int actual_padding = s.size() - i;
59         // omission of padding characters is allowed
60         if (actual_padding == 0)
61                 return true;
62
63         // remaining characters (max. 2) may only be padding
64         for (; i < s.size(); ++i)
65                 if (s[i] != '=')
66                         return false;
67         // number of padding characters needs to match
68         return padding == actual_padding;
69 }
70
71 std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
72         std::string ret;
73         int i = 0;
74         int j = 0;
75         unsigned char char_array_3[3];
76         unsigned char char_array_4[4];
77
78         while (in_len--) {
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] = ((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;
85
86                         for(i = 0; (i <4) ; i++)
87                                 ret += base64_chars[char_array_4[i]];
88                         i = 0;
89                 }
90         }
91
92         if (i)
93         {
94                 for(j = i; j < 3; j++)
95                         char_array_3[j] = '\0';
96
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;
101
102                 for (j = 0; (j < i + 1); j++)
103                         ret += base64_chars[char_array_4[j]];
104
105         // Don't pad it with =
106                 /*while((i++ < 3))
107                         ret += '=';*/
108
109         }
110
111         return ret;
112
113 }
114
115 std::string base64_decode(std::string const& encoded_string) {
116         int in_len = encoded_string.size();
117         int i = 0;
118         int j = 0;
119         int in_ = 0;
120         unsigned char char_array_4[4], char_array_3[3];
121         std::string ret;
122
123         while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
124                 char_array_4[i++] = encoded_string[in_]; in_++;
125                 if (i ==4) {
126                         for (i = 0; i <4; i++)
127                                 char_array_4[i] = base64_chars.find(char_array_4[i]);
128
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];
132
133                         for (i = 0; (i < 3); i++)
134                                 ret += char_array_3[i];
135                         i = 0;
136                 }
137         }
138
139         if (i) {
140                 for (j = i; j <4; j++)
141                         char_array_4[j] = 0;
142
143                 for (j = 0; j <4; j++)
144                         char_array_4[j] = base64_chars.find(char_array_4[j]);
145
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];
149
150                 for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
151         }
152
153         return ret;
154 }