com.alibaba.fastjson.util.Base64 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fastjson Show documentation
Show all versions of fastjson Show documentation
Fastjson is a JSON processor (JSON parser + JSON generator) written in Java
package com.alibaba.fastjson.util;
import java.util.Arrays;
/**
* @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11
* @version 2.2
* @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, j = CA.length; i < j; 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:
* + The array must have a line length of 76 chars OR no line separators at all (one line).
* + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within
* the encoded string
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
*
* @param chars The source array. Length 0 will return an empty array. null
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 + 1]] << 12
| IA[chars[sIx + 2]] << 6
| IA[chars[sIx + 3]];
sIx += 4;
// Add the bytes
bytes[d] = (byte) (i >> 16);
bytes[d + 1] = (byte) (i >> 8);
bytes[d + 2] = (byte) i;
d += 3;
// 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 + 1)] << 12
| IA[chars.charAt(sIx + 2)] << 6
| IA[chars.charAt(sIx + 3)];
sIx += 4;
// Add the bytes
bytes[d] = (byte) (i >> 16);
bytes[d + 1] = (byte) (i >> 8);
bytes[d + 2] = (byte) i;
d += 3;
// 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:
* + The array must have a line length of 76 chars OR no line separators at all (one line).
* + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within
* the encoded string
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
*
* @param s The source string. Length 0 will return an empty array. null
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 + 1)] << 12
| IA[s.charAt(sIx + 2)] << 6
| IA[s.charAt(sIx + 3)];
sIx += 4;
// Add the bytes
dArr[d] = (byte) (i >> 16);
dArr[d + 1] = (byte) (i >> 8);
dArr[d + 2] = (byte) i;
d += 3;
// 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;
}
}