1212 freely, subject to the following restrictions:
1313
1414 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.
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.
1818
1919 2. Altered source versions must be plainly marked as such, and must not be
20- misrepresented as being the original source code.
20+ misrepresented as being the original source code.
2121
2222 3. This notice may not be removed or altered from any source distribution.
2323
@@ -33,114 +33,129 @@ using namespace dev;
3333
3434static inline bool is_base64 (byte c)
3535{
36- return (isalnum (c) || (c == ' +' ) || (c == ' /' ));
36+ return (isalnum (c) || (c == ' +' ) || (c == ' /' ));
3737}
3838
3939static inline byte find_base64_char_index (byte c)
4040{
41- if (' A' <= c && c <= ' Z' ) return c - ' A' ;
42- else if (' a' <= c && c <= ' z' ) return c - ' a' + 1 + find_base64_char_index (' Z' );
43- else if (' 0' <= c && c <= ' 9' ) return c - ' 0' + 1 + find_base64_char_index (' z' );
44- else if (c == ' +' ) return 1 + find_base64_char_index (' 9' );
45- else if (c == ' /' ) return 1 + find_base64_char_index (' +' );
46- else return 1 + find_base64_char_index (' /' );
41+ if (' A' <= c && c <= ' Z' ) return c - ' A' ;
42+ else if (' a' <= c && c <= ' z' ) return c - ' a' + 1 + find_base64_char_index (' Z' );
43+ else if (' 0' <= c && c <= ' 9' ) return c - ' 0' + 1 + find_base64_char_index (' z' );
44+ else if (c == ' +' ) return 1 + find_base64_char_index (' 9' );
45+ else if (c == ' /' ) return 1 + find_base64_char_index (' +' );
46+ else return 1 + find_base64_char_index (' /' );
47+ }
48+
49+ string toBase64Encoding (bytesConstRef _in, char const * _base64_chars, bool _pad)
50+ {
51+ string ret;
52+ int i = 0 ;
53+ int j = 0 ;
54+ byte char_array_3[3 ];
55+ byte char_array_4[4 ];
56+
57+ auto buf = _in.data ();
58+ auto bufLen = _in.size ();
59+
60+ while (bufLen--)
61+ {
62+ char_array_3[i++] = *(buf++);
63+ if (i == 3 )
64+ {
65+ char_array_4[0 ] = (char_array_3[0 ] & 0xfc ) >> 2 ;
66+ char_array_4[1 ] = ((char_array_3[0 ] & 0x03 ) << 4 ) + ((char_array_3[1 ] & 0xf0 ) >> 4 );
67+ char_array_4[2 ] = ((char_array_3[1 ] & 0x0f ) << 2 ) + ((char_array_3[2 ] & 0xc0 ) >> 6 );
68+ char_array_4[3 ] = char_array_3[2 ] & 0x3f ;
69+
70+ for (i = 0 ; i < 4 ; i++)
71+ ret += _base64_chars[char_array_4[i]];
72+ i = 0 ;
73+ }
74+ }
75+
76+ if (i)
77+ {
78+ for (j = i; j < 3 ; j++)
79+ char_array_3[j] = ' \0 ' ;
80+
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 (j = 0 ; j < i + 1 ; j++)
87+ ret += _base64_chars[char_array_4[j]];
88+
89+ while (i++ < 3 && _pad)
90+ ret += ' =' ;
91+ }
92+
93+ return ret;
4794}
4895
4996string dev::toBase64 (bytesConstRef _in)
5097{
51- static const char base64_chars[] =
52- " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
53- " abcdefghijklmnopqrstuvwxyz"
54- " 0123456789+/" ;
55-
56- string ret;
57- int i = 0 ;
58- int j = 0 ;
59- byte char_array_3[3 ];
60- byte char_array_4[4 ];
61-
62- auto buf = _in.data ();
63- auto bufLen = _in.size ();
64-
65- while (bufLen--)
66- {
67- char_array_3[i++] = *(buf++);
68- if (i == 3 )
69- {
70- char_array_4[0 ] = (char_array_3[0 ] & 0xfc ) >> 2 ;
71- char_array_4[1 ] = ((char_array_3[0 ] & 0x03 ) << 4 ) + ((char_array_3[1 ] & 0xf0 ) >> 4 );
72- char_array_4[2 ] = ((char_array_3[1 ] & 0x0f ) << 2 ) + ((char_array_3[2 ] & 0xc0 ) >> 6 );
73- char_array_4[3 ] = char_array_3[2 ] & 0x3f ;
74-
75- for (i = 0 ; i < 4 ; i++)
76- ret += base64_chars[char_array_4[i]];
77- i = 0 ;
78- }
79- }
80-
81- if (i)
82- {
83- for (j = i; j < 3 ; j++)
84- char_array_3[j] = ' \0 ' ;
85-
86- char_array_4[0 ] = (char_array_3[0 ] & 0xfc ) >> 2 ;
87- char_array_4[1 ] = ((char_array_3[0 ] & 0x03 ) << 4 ) + ((char_array_3[1 ] & 0xf0 ) >> 4 );
88- char_array_4[2 ] = ((char_array_3[1 ] & 0x0f ) << 2 ) + ((char_array_3[2 ] & 0xc0 ) >> 6 );
89- char_array_4[3 ] = char_array_3[2 ] & 0x3f ;
90-
91- for (j = 0 ; j < i + 1 ; j++)
92- ret += base64_chars[char_array_4[j]];
93-
94- while (i++ < 3 )
95- ret += ' =' ;
96- }
97-
98- return ret;
98+ static char const c_base64_chars[] =
99+ " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
100+ " abcdefghijklmnopqrstuvwxyz"
101+ " 0123456789+/" ;
102+ bool const pad = true ;
103+ return toBase64Encoding (_in, c_base64_chars, pad);
104+ }
105+
106+ string dev::toBase64URLSafe (bytesConstRef _in)
107+ {
108+ static char const c_base64_chars[] =
109+ " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
110+ " abcdefghijklmnopqrstuvwxyz"
111+ " 0123456789-_" ;
112+ bool const pad = false ;
113+ return toBase64Encoding (_in, c_base64_chars, pad);
99114}
100115
101116bytes dev::fromBase64 (string const & encoded_string)
102117{
103- auto in_len = encoded_string.size ();
104- int i = 0 ;
105- int j = 0 ;
106- int in_ = 0 ;
107- byte char_array_3[3 ];
108- byte char_array_4[4 ];
109- bytes ret;
110-
111- while (in_len-- && encoded_string[in_] != ' =' && is_base64 (encoded_string[in_]))
112- {
113- char_array_4[i++] = encoded_string[in_]; in_++;
114- if (i == 4 )
115- {
116- for (i = 0 ; i < 4 ; i++)
117- char_array_4[i] = find_base64_char_index (char_array_4[i]);
118-
119- char_array_3[0 ] = (char_array_4[0 ] << 2 ) + ((char_array_4[1 ] & 0x30 ) >> 4 );
120- char_array_3[1 ] = ((char_array_4[1 ] & 0xf ) << 4 ) + ((char_array_4[2 ] & 0x3c ) >> 2 );
121- char_array_3[2 ] = ((char_array_4[2 ] & 0x3 ) << 6 ) + char_array_4[3 ];
122-
123- for (i = 0 ; (i < 3 ); i++)
124- ret.push_back (char_array_3[i]);
125- i = 0 ;
126- }
127- }
128-
129- if (i)
130- {
131- for (j = i; j < 4 ; j++)
132- char_array_4[j] = 0 ;
133-
134- for (j = 0 ; j < 4 ; j++)
135- char_array_4[j] = find_base64_char_index (char_array_4[j]);
136-
137- char_array_3[0 ] = (char_array_4[0 ] << 2 ) + ((char_array_4[1 ] & 0x30 ) >> 4 );
138- char_array_3[1 ] = ((char_array_4[1 ] & 0xf ) << 4 ) + ((char_array_4[2 ] & 0x3c ) >> 2 );
139- char_array_3[2 ] = ((char_array_4[2 ] & 0x3 ) << 6 ) + char_array_4[3 ];
140-
141- for (j = 0 ; j < i - 1 ; j++)
142- ret.push_back (char_array_3[j]);
143- }
144-
145- return ret;
118+ auto in_len = encoded_string.size ();
119+ int i = 0 ;
120+ int j = 0 ;
121+ int in_ = 0 ;
122+ byte char_array_3[3 ];
123+ byte char_array_4[4 ];
124+ bytes ret;
125+
126+ while (in_len-- && encoded_string[in_] != ' =' && is_base64 (encoded_string[in_]))
127+ {
128+ char_array_4[i++] = encoded_string[in_]; in_++;
129+ if (i == 4 )
130+ {
131+ for (i = 0 ; i < 4 ; i++)
132+ char_array_4[i] = find_base64_char_index (char_array_4[i]);
133+
134+ char_array_3[0 ] = (char_array_4[0 ] << 2 ) + ((char_array_4[1 ] & 0x30 ) >> 4 );
135+ char_array_3[1 ] = ((char_array_4[1 ] & 0xf ) << 4 ) + ((char_array_4[2 ] & 0x3c ) >> 2 );
136+ char_array_3[2 ] = ((char_array_4[2 ] & 0x3 ) << 6 ) + char_array_4[3 ];
137+
138+ for (i = 0 ; (i < 3 ); i++)
139+ ret.push_back (char_array_3[i]);
140+ i = 0 ;
141+ }
142+ }
143+
144+ if (i)
145+ {
146+ for (j = i; j < 4 ; j++)
147+ char_array_4[j] = 0 ;
148+
149+ for (j = 0 ; j < 4 ; j++)
150+ char_array_4[j] = find_base64_char_index (char_array_4[j]);
151+
152+ char_array_3[0 ] = (char_array_4[0 ] << 2 ) + ((char_array_4[1 ] & 0x30 ) >> 4 );
153+ char_array_3[1 ] = ((char_array_4[1 ] & 0xf ) << 4 ) + ((char_array_4[2 ] & 0x3c ) >> 2 );
154+ char_array_3[2 ] = ((char_array_4[2 ] & 0x3 ) << 6 ) + char_array_4[3 ];
155+
156+ for (j = 0 ; j < i - 1 ; j++)
157+ ret.push_back (char_array_3[j]);
158+ }
159+
160+ return ret;
146161}
0 commit comments