cbbase64.java
来自「JAVA开源LDAP浏览器jxplorer的源码!」· Java 代码 · 共 626 行 · 第 1/2 页
JAVA
626 行
public static byte[] decode(byte[] rawData)
{
try
{
int resultLength = (int) (rawData.length * .75); // set upper limit for binary array
byte result[] = new byte[resultLength];
int noBytesWritten = 0;
int validCharacters = 0;
byte c;
byte quad[] = new byte[4]; // temp store for a quad of base64 byte characters
int bytes; // temp store for a triplet of bytes
int numfound = 0; // number of chars found for quad
// iterate through, finding valid quads, and converting to byte triplets
for (int i = 0; i < rawData.length; i++)
{
c = rawData[i];
if ((c >= (byte) 'A' && c <= (byte) 'Z') || (c >= (byte) 'a' && c <= (byte) 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == (byte) '/') || (c == (byte) '='))
{
quad[numfound++] = c;
validCharacters++;
}
else if (" \r\n\t\f".indexOf((char) c) == -1)
{
//CBUtility.log("error... bad character (" + (char)c + ") read from base64 encoded string", 6);
return null;
}
// write the quad; paying special attention to possible 'filler'
// characters '=' or '==' at the end of the string (see rfc).
if (numfound == 4)
{
bytes = convertQuad(quad);
result[noBytesWritten++] = (byte) ((bytes & 0xFF0000) >> 16);
if (c != '=')
{
result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8);
result[noBytesWritten++] = (byte) (bytes & 0xFF);
}
else if (rawData[i - 1] != '=')
{
result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8);
if ((bytes & 0xFF) > 0)
{
//CBUtility.log("Warning: Corrupt base64 Encoded File - contains trailing bits after file end.", 6);
return null;
}
}
else if ((bytes & 0xFF00) > 0)
{
//CBUtility.log("Warning: Corrupt base64 Encoded File - contains trailing bits after file end.", 6);
return null;
}
numfound = 0;
}
}
// check that the number of real characters is correct - must be cleanly
// divisible by 4...
if (validCharacters % 4 != 0)
{
//CBUtility.log("Warning: Corrupt base64 Encoded File - Length (" + validCharacters + ") of valid characters not divisible by 4.", 6);
return null;
}
byte finalResult[] = new byte[noBytesWritten];
System.arraycopy(result, 0, finalResult, 0, noBytesWritten);
return finalResult;
}
catch (Exception e)
{
//CBUtility.log("unable to create final decoded byte array from base64 bytes: " + e, 6);
return null;
}
}
/**
* Decodes a byte array containing base64 encoded data.
*
* @param chars a String, each character of which is a seven-bit ASCII value.
* @return the raw binary data, each byte of which may have any value from
* 0 - 255. This value will be null if a decoding error occurred.
*/
public static byte[] decode(String chars)
throws CBBase64EncodingException
{
if (chars == null) return null;
byte rawData[];
try
{
rawData = chars.getBytes("US-ASCII");
}
catch (UnsupportedEncodingException e)
{
throw new CBBase64EncodingException("unable to convert base64 encoded data to bytes using US-ASCII encoding", e);
}
int resultLength = (int) (rawData.length * .75); // set upper limit for binary array
byte result[] = new byte[resultLength];
int noBytesWritten = 0;
int validCharacters = 0;
byte c;
byte quad[] = new byte[4]; // temp store for a quad of base64 byte characters
int bytes; // temp store for a triplet of bytes
int numfound = 0; // number of chars found for quad
// iterate through, finding valid quads, and converting to byte triplets
for (int i = 0; i < rawData.length; i++)
{
c = rawData[i];
if ((c >= (byte) 'A' && c <= (byte) 'Z') || (c >= (byte) 'a' && c <= (byte) 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == (byte) '/') || (c == (byte) '='))
{
quad[numfound++] = c;
validCharacters++;
}
else if (" \r\n\t\f".indexOf((char) c) == -1)
{
throw new CBBase64EncodingException("error... bad character (" + (char) c + ") read from base64 encoded string");
}
// write the quad; paying special attention to possible 'filler'
// characters '=' or '==' at the end of the string (see rfc).
if (numfound == 4)
{
bytes = convertQuad(quad);
result[noBytesWritten++] = (byte) ((bytes & 0xFF0000) >> 16);
if (c != '=')
{
result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8);
result[noBytesWritten++] = (byte) (bytes & 0xFF);
}
else if (rawData[i - 1] != '=')
{
result[noBytesWritten++] = (byte) ((bytes & 0xFF00) >> 8);
if ((bytes & 0xFF) > 0)
{
throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded Data - contains trailing bits after end of base 64 data.");
}
}
else if ((bytes & 0xFF00) > 0)
{
throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded File - contains trailing bits after end of base64 data.");
}
numfound = 0;
}
}
// check that the number of real characters is correct - must be cleanly
// divisible by 4...
if (validCharacters % 4 != 0)
{
throw new CBBase64EncodingException("Warning: Corrupt base64 Encoded Data - Length (" + validCharacters + ") of valid characters not divisible by 4.");
}
byte finalResult[] = new byte[noBytesWritten];
System.arraycopy(result, 0, finalResult, 0, noBytesWritten);
return finalResult;
}
/**
* Converts three bytes to 4 base 64 values...
* a half hearted attempt has been made to make it go fast...
*
* @param a the first byte to convert
* @param b the second byte to convert
* @param c the third byte to convert
* @param Num the Number of 'real' bytes to convert - i.e. 1 (just a),
* 2 (a and b), or 3 (a,b and c).
* @param buff the result buffer to put the final values in.
* @param buffpos the position to start filling the result buffer from.
*/
private static void convertTriplet(byte a, byte b, byte c, int Num, byte[] buff, int buffpos)
throws CBBase64EncodingException
{
byte w, x, y, z; // the four 6 bit values extracted.
int trip = (a << 16) | ((b << 8) & 0xFF00) | (c & 0xFF);
w = (byte) ((trip & 0xFC0000) >> 18);
x = (byte) ((trip & 0x03F000) >> 12);
y = (byte) ((trip & 0x000FC0) >> 6);
z = (byte) (trip & 0x00003F);
buff[buffpos] = convertFrom6Bit(w);
buff[buffpos + 1] = convertFrom6Bit(x);
if (Num == 1)
{
buff[buffpos + 2] = (byte) '=';
buff[buffpos + 3] = (byte) '=';
}
else
{
buff[buffpos + 2] = convertFrom6Bit(y);
if (Num == 2)
{
buff[buffpos + 3] = (byte) '=';
}
else
{
buff[buffpos + 3] = convertFrom6Bit(z);
}
}
}
/**
* Use rfc 1521 specified character conversions
* (I wonder if a preset array would be faster?)
*
* @param b the 6 significant bit byte to be converted
* @return the converted base64 character
*/
// this might be sped up using an array index as provided above...
private static byte convertFrom6Bit(byte b)
throws CBBase64EncodingException
{
byte c;
if (b < 26)
return (byte) ('A' + b); // 'A' -> 'Z'
else if (b < 52)
return (byte) (('a' - 26) + b); // 'a' -> 'z'
else if (b < 62)
return (byte) (('0' - 52) + b); // '0' -> '9'
else if (b == 62)
return ((byte) '+');
else if (b == 63)
return ((byte) '/');
else // error - should never happen
{
throw new CBBase64EncodingException("erroroneous value " + (char) b + " passed in convertFrom6bit");
}
}
/**
* Use rfc 1521 specified character conversions
* (I wonder if a preset array would be faster?)
*
* @param c a byte representing a single base64 encoded character
* @return the corresponding raw 6 bit 'true' value.
*/
private static byte convertTo6Bit(byte c)
throws CBBase64EncodingException
{
if (c == (byte) '+')
return 62;
else if (c == (byte) '/')
return 63;
else if (c == (byte) '=') // this result not actually used by calling program...
return 0;
else if (c <= (byte) '9')
return (byte) (c - (byte) '0' + 52);
else if (c <= (byte) 'Z')
return (byte) (c - (byte) 'A');
else if (c <= (byte) 'z')
return (byte) (c - (byte) 'a' + 26);
else // error - should never happen
{
throw new CBBase64EncodingException("erroroneous value " + (char) c + " passed in convertTo6bit");
}
}
/**
* Takes a triplet of base64 encoded characters, and returns
* a triplet of appropriate bytes
*
* @param quad four base 64 encoded characters
* @return the corresponding 'true' 24 bit value, as an int.
*/
private static int convertQuad(byte[] quad)
throws CBBase64EncodingException
{
byte a = convertTo6Bit(quad[0]);
byte b = convertTo6Bit(quad[1]);
byte c = convertTo6Bit(quad[2]);
byte d = convertTo6Bit(quad[3]);
int ret = (a << 18) + (b << 12) + (c << 6) + d;
return ret;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?