FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
java/src/main/java/com/jsoniter/extra/Base64.java at master · iCodeIN/java · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
iCodeIN
/
java
Public
forked from
json-iterator/java
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
java
/
src
/
main
/
java
/
com
/
jsoniter
/
extra
/
Base64.java
Copy path
More file actions
More file actions
Latest commit
History
History
History
257 lines (223 loc) · 10.7 KB
Breadcrumbs
java
/
src
/
main
/
java
/
com
/
jsoniter
/
extra
/
Base64.java
Copy path
File metadata and controls
257 lines (223 loc) · 10.7 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
package
com
.
jsoniter
.
extra
;
import
com
.
jsoniter
.
JsonIterator
;
import
com
.
jsoniter
.
spi
.
Slice
;
import
com
.
jsoniter
.
output
.
JsonStream
;
import
java
.
io
.
IOException
;
import
java
.
util
.
Arrays
;
/** A very fast and memory efficient class to encode and decode to and from BASE64 in full accordance
* with RFC 2045.<br><br>
* On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is about 10 times faster
* on small arrays (10 - 1000 bytes) and 2-3 times as fast on larger arrays (10000 - 1000000 bytes)
* compared to <code>sun.misc.Encoder()/Decoder()</code>.<br><br>
*
* On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 Codec for encode and
* about 50% faster for decoding large arrays. This implementation is about twice as fast on very small
* arrays (< 30 bytes). If source/destination is a <code>String</code> this
* version is about three times as fast due to the fact that the Commons Codec result has to be recoded
* to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br><br>
*
* This encode/decode algorithm doesn't create any temporary arrays as many other codecs do, it only
* allocates the resulting array. This produces less garbage and it is possible to handle arrays twice
* as large as algorithms that create a temporary array. (E.g. Jakarta Commons Codec). It is unknown
* whether Sun's <code>sun.misc.Encoder()/Decoder()</code> produce temporary arrays but since performance
* is quite low it probably does.<br><br>
*
* The encoder produces the same output as the Sun one except that the Sun's encoder appends
* a trailing line separator if the last character isn't a pad. Unclear why but it only adds to the
* length and is probably a side effect. Both are in conformance with RFC 2045 though.<br>
* Commons codec seem to always att a trailing line separator.<br><br>
*
* <b>Note!</b>
* The encode/decode method pairs (types) come in three versions with the <b>exact</b> same algorithm and
* thus a lot of code redundancy. This is to not create any temporary arrays for transcoding to/from different
* format types. The methods not used can simply be commented out.<br><br>
*
* There is also a "fast" version of all decode methods that works the same way as the normal ones, but
* har a few demands on the decoded input. Normally though, these fast verions should be used if the source if
* the input is known and it hasn't bee tampered with.<br><br>
*
* If you find the code useful or you find a bug, please send me a note at base64 @ miginfocom . com.
*
* Licence (BSD):
* ==============
*
* Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (base64 @ miginfocom . com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* Neither the name of the MiG InfoCom AB nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* @version 2.2
* @author Mikael Grev
* Date: 2004-aug-02
* Time: 11:31:11
*/
abstract
class
Base64
{
private
static
final
char
[]
CA
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.
toCharArray
();
static
final
byte
[]
BA
;
static
final
int
[]
IA
=
new
int
[
256
];
static
{
Arrays
.
fill
(
IA
, -
1
);
for
(
int
i
=
0
,
iS
=
CA
.
length
;
i
<
iS
;
i
++) {
IA
[
CA
[
i
]] =
i
;
}
IA
[
'='
] =
0
;
BA
=
new
byte
[
CA
.
length
];
for
(
int
i
=
0
;
i
<
CA
.
length
;
i
++) {
BA
[
i
] = (
byte
)
CA
[
i
];
}
}
static
int
encodeToChar
(
byte
[]
sArr
,
char
[]
dArr
,
final
int
start
) {
final
int
sLen
=
sArr
.
length
;
final
int
eLen
= (
sLen
/
3
) *
3
;
// Length of even 24-bits.
final
int
dLen
= ((
sLen
-
1
) /
3
+
1
) <<
2
;
// Returned character count
// Encode even 24-bits
for
(
int
s
=
0
,
d
=
start
;
s
<
eLen
;) {
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
int
i
= (
sArr
[
s
++] &
0xff
) <<
16
| (
sArr
[
s
++] &
0xff
) <<
8
| (
sArr
[
s
++] &
0xff
);
// Encode the int into four chars
dArr
[
d
++] =
CA
[(
i
>>>
18
) &
0x3f
];
dArr
[
d
++] =
CA
[(
i
>>>
12
) &
0x3f
];
dArr
[
d
++] =
CA
[(
i
>>>
6
) &
0x3f
];
dArr
[
d
++] =
CA
[
i
&
0x3f
];
}
// Pad and encode last bits if source isn't even 24 bits.
int
left
=
sLen
-
eLen
;
// 0 - 2.
if
(
left
>
0
) {
// Prepare the int
int
i
= ((
sArr
[
eLen
] &
0xff
) <<
10
) | (
left
==
2
? ((
sArr
[
sLen
-
1
] &
0xff
) <<
2
) :
0
);
// Set last four chars
dArr
[
start
+
dLen
-
4
] =
CA
[
i
>>
12
];
dArr
[
start
+
dLen
-
3
] =
CA
[(
i
>>>
6
) &
0x3f
];
dArr
[
start
+
dLen
-
2
] =
left
==
2
?
CA
[
i
&
0x3f
] :
'='
;
dArr
[
start
+
dLen
-
1
] =
'='
;
}
return
dLen
;
}
static
int
encodeToBytes
(
byte
[]
sArr
,
JsonStream
stream
)
throws
IOException
{
final
int
sLen
=
sArr
.
length
;
final
int
eLen
= (
sLen
/
3
) *
3
;
// Length of even 24-bits.
final
int
dLen
= ((
sLen
-
1
) /
3
+
1
) <<
2
;
// Returned character count
// Encode even 24-bits
for
(
int
s
=
0
;
s
<
eLen
;) {
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
int
i
= (
sArr
[
s
++] &
0xff
) <<
16
| (
sArr
[
s
++] &
0xff
) <<
8
| (
sArr
[
s
++] &
0xff
);
// Encode the int into four chars
stream
.
write
(
BA
[(
i
>>>
18
) &
0x3f
],
BA
[(
i
>>>
12
) &
0x3f
],
BA
[(
i
>>>
6
) &
0x3f
],
BA
[
i
&
0x3f
]);
}
// Pad and encode last bits if source isn't even 24 bits.
int
left
=
sLen
-
eLen
;
// 0 - 2.
if
(
left
>
0
) {
// Prepare the int
int
i
= ((
sArr
[
eLen
] &
0xff
) <<
10
) | (
left
==
2
? ((
sArr
[
sLen
-
1
] &
0xff
) <<
2
) :
0
);
// Set last four chars
stream
.
write
(
BA
[
i
>>
12
],
BA
[(
i
>>>
6
) &
0x3f
],
left
==
2
?
BA
[
i
&
0x3f
] : (
byte
)
'='
, (
byte
)
'='
);
}
return
dLen
;
}
static
void
encodeLongBits
(
long
bits
,
JsonStream
stream
)
throws
IOException
{
int
i
= (
int
)
bits
;
byte
b1
=
BA
[(
i
>>>
18
) &
0x3f
];
byte
b2
=
BA
[(
i
>>>
12
) &
0x3f
];
byte
b3
=
BA
[(
i
>>>
6
) &
0x3f
];
byte
b4
=
BA
[
i
&
0x3f
];
stream
.
write
((
byte
)
'"'
,
b1
,
b2
,
b3
,
b4
);
bits
=
bits
>>>
24
;
i
= (
int
)
bits
;
b1
=
BA
[(
i
>>>
18
) &
0x3f
];
b2
=
BA
[(
i
>>>
12
) &
0x3f
];
b3
=
BA
[(
i
>>>
6
) &
0x3f
];
b4
=
BA
[
i
&
0x3f
];
stream
.
write
(
b1
,
b2
,
b3
,
b4
);
bits
= (
bits
>>>
24
) <<
2
;
i
= (
int
)
bits
;
b1
=
BA
[
i
>>
12
];
b2
=
BA
[(
i
>>>
6
) &
0x3f
];
b3
=
BA
[
i
&
0x3f
];
stream
.
write
(
b1
,
b2
,
b3
, (
byte
)
'"'
);
}
static
long
decodeLongBits
(
JsonIterator
iter
)
throws
IOException
{
Slice
slice
=
iter
.
readStringAsSlice
();
if
(
slice
.
len
() !=
11
) {
throw
iter
.
reportError
(
"decodeLongBits"
,
"must be 11 bytes for long bits encoded double"
);
}
byte
[]
encoded
=
slice
.
data
();
int
sIx
=
slice
.
head
();
long
i
=
IA
[
encoded
[
sIx
++]] <<
18
|
IA
[
encoded
[
sIx
++]] <<
12
|
IA
[
encoded
[
sIx
++]] <<
6
|
IA
[
encoded
[
sIx
++]];
long
bits
=
i
;
i
=
IA
[
encoded
[
sIx
++]] <<
18
|
IA
[
encoded
[
sIx
++]] <<
12
|
IA
[
encoded
[
sIx
++]] <<
6
|
IA
[
encoded
[
sIx
++]];
bits
=
i
<<
24
|
bits
;
i
=
IA
[
encoded
[
sIx
++]] <<
12
|
IA
[
encoded
[
sIx
++]] <<
6
|
IA
[
encoded
[
sIx
]];
bits
=
i
<<
46
|
bits
;
return
bits
;
}
static
int
findEnd
(
final
byte
[]
sArr
,
final
int
start
) {
for
(
int
i
=
start
;
i
<
sArr
.
length
;
i
++)
if
(
IA
[
sArr
[
i
] &
0xff
] <
0
)
return
i
;
return
sArr
.
length
;
}
private
final
static
byte
[]
EMPTY_ARRAY
=
new
byte
[
0
];
static
byte
[]
decodeFast
(
final
byte
[]
sArr
,
final
int
start
,
final
int
end
) {
// Check special case
int
sLen
=
end
-
start
;
if
(
sLen
==
0
)
return
EMPTY_ARRAY
;
int
sIx
=
start
,
eIx
=
end
-
1
;
// Start and end index after trimming.
// Trim illegal chars from start
while
(
sIx
<
eIx
&&
IA
[
sArr
[
sIx
] &
0xff
] <
0
)
sIx
++;
// Trim illegal chars from end
while
(
eIx
>
0
&&
IA
[
sArr
[
eIx
] &
0xff
] <
0
)
eIx
--;
// get the padding count (=) (0, 1 or 2)
int
pad
=
sArr
[
eIx
] ==
'='
? (
sArr
[
eIx
-
1
] ==
'='
?
2
:
1
) :
0
;
// Count '=' at end.
int
cCnt
=
eIx
-
sIx
+
1
;
// Content count including possible separators
int
sepCnt
=
sLen
>
76
? (
sArr
[
76
] ==
'\r'
?
cCnt
/
78
:
0
) <<
1
:
0
;
int
len
= ((
cCnt
-
sepCnt
) *
6
>>
3
) -
pad
;
// The number of decoded bytes
byte
[]
dArr
=
new
byte
[
len
];
// Preallocate byte[] of exact length
// Decode all but the last 0 - 2 bytes.
int
d
=
0
;
for
(
int
cc
=
0
,
eLen
= (
len
/
3
) *
3
;
d
<
eLen
;) {
// Assemble three bytes into an int from four "valid" characters.
int
i
=
IA
[
sArr
[
sIx
++]] <<
18
|
IA
[
sArr
[
sIx
++]] <<
12
|
IA
[
sArr
[
sIx
++]] <<
6
|
IA
[
sArr
[
sIx
++]];
// Add the bytes
dArr
[
d
++] = (
byte
) (
i
>>
16
);
dArr
[
d
++] = (
byte
) (
i
>>
8
);
dArr
[
d
++] = (
byte
)
i
;
// If line separator, jump over it.
if
(
sepCnt
>
0
&& ++
cc
==
19
) {
sIx
+=
2
;
cc
=
0
;
}
}
if
(
d
<
len
) {
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
int
i
=
0
;
for
(
int
j
=
0
;
sIx
<=
eIx
-
pad
;
j
++)
i
|=
IA
[
sArr
[
sIx
++]] << (
18
-
j
*
6
);
for
(
int
r
=
16
;
d
<
len
;
r
-=
8
)
dArr
[
d
++] = (
byte
) (
i
>>
r
);
}
return
dArr
;
}
}
Back
|
FazBrowse Home
|
New Git URL