-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
233 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
package com.alibaba.fastjson.util; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* | ||
* @version 2.2 | ||
* @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 | ||
* @deprecated internal api, don't use. | ||
*/ | ||
public class Base64 { | ||
|
||
public static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); | ||
public 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; | ||
} | ||
|
||
/** | ||
* Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as | ||
* fast as #decode(char[]). The preconditions are:<br> | ||
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br> | ||
* + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within | ||
* the encoded string<br> | ||
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> | ||
* | ||
* @param chars The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. | ||
* @return The decoded array of bytes. May be of length 0. | ||
*/ | ||
public static byte[] decodeFast(char[] chars, int offset, int charsLen) { | ||
// Check special case | ||
if (charsLen == 0) { | ||
return new byte[0]; | ||
} | ||
|
||
int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. | ||
|
||
// Trim illegal chars from start | ||
while (sIx < eIx && IA[chars[sIx]] < 0) | ||
sIx++; | ||
|
||
// Trim illegal chars from end | ||
while (eIx > 0 && IA[chars[eIx]] < 0) | ||
eIx--; | ||
|
||
// get the padding count (=) (0, 1 or 2) | ||
int pad = chars[eIx] == '=' ? (chars[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. | ||
int cCnt = eIx - sIx + 1; // Content count including possible separators | ||
int sepCnt = charsLen > 76 ? (chars[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; | ||
|
||
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes | ||
byte[] bytes = 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[chars[sIx++]] << 18 | IA[chars[sIx++]] << 12 | IA[chars[sIx++]] << 6 | IA[chars[sIx++]]; | ||
|
||
// Add the bytes | ||
bytes[d++] = (byte) (i >> 16); | ||
bytes[d++] = (byte) (i >> 8); | ||
bytes[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[chars[sIx++]] << (18 - j * 6); | ||
|
||
for (int r = 16; d < len; r -= 8) | ||
bytes[d++] = (byte) (i >> r); | ||
} | ||
|
||
return bytes; | ||
} | ||
|
||
public static byte[] decodeFast(String chars, int offset, int charsLen) { | ||
// Check special case | ||
if (charsLen == 0) { | ||
return new byte[0]; | ||
} | ||
|
||
int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. | ||
|
||
// Trim illegal chars from start | ||
while (sIx < eIx && IA[chars.charAt(sIx)] < 0) | ||
sIx++; | ||
|
||
// Trim illegal chars from end | ||
while (eIx > 0 && IA[chars.charAt(eIx)] < 0) | ||
eIx--; | ||
|
||
// get the padding count (=) (0, 1 or 2) | ||
int pad = chars.charAt(eIx) == '=' ? (chars.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. | ||
int cCnt = eIx - sIx + 1; // Content count including possible separators | ||
int sepCnt = charsLen > 76 ? (chars.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; | ||
|
||
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes | ||
byte[] bytes = 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[chars.charAt(sIx++)] << 18 | IA[chars.charAt(sIx++)] << 12 | IA[chars.charAt(sIx++)] << 6 | IA[chars.charAt(sIx++)]; | ||
|
||
// Add the bytes | ||
bytes[d++] = (byte) (i >> 16); | ||
bytes[d++] = (byte) (i >> 8); | ||
bytes[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[chars.charAt(sIx++)] << (18 - j * 6); | ||
|
||
for (int r = 16; d < len; r -= 8) | ||
bytes[d++] = (byte) (i >> r); | ||
} | ||
|
||
return bytes; | ||
} | ||
|
||
/** | ||
* Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as fast | ||
* as decode(String). The preconditions are:<br> | ||
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br> | ||
* + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within | ||
* the encoded string<br> | ||
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> | ||
* | ||
* @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception. | ||
* @return The decoded array of bytes. May be of length 0. | ||
*/ | ||
public static byte[] decodeFast(String s) { | ||
// Check special case | ||
int sLen = s.length(); | ||
if (sLen == 0) { | ||
return new byte[0]; | ||
} | ||
|
||
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. | ||
|
||
// Trim illegal chars from start | ||
while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) | ||
sIx++; | ||
|
||
// Trim illegal chars from end | ||
while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) | ||
eIx--; | ||
|
||
// get the padding count (=) (0, 1 or 2) | ||
int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. | ||
int cCnt = eIx - sIx + 1; // Content count including possible separators | ||
int sepCnt = sLen > 76 ? (s.charAt(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[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | ||
| IA[s.charAt(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[s.charAt(sIx++)] << (18 - j * 6); | ||
|
||
for (int r = 16; d < len; r -= 8) | ||
dArr[d++] = (byte) (i >> r); | ||
} | ||
|
||
return dArr; | ||
} | ||
} |