📄 cbbase64.java
字号:
package com.ca.commons.cbutil;
import java.io.UnsupportedEncodingException;
/**
* Converts back and forth between binary and base 64 (rfc 1521). There are
* almost certainly java classes that already do this, but it will
* take longer to find them than to write this :-) <p>
* <p/>
* Not fully optimised for speed - might be made faster if necessary... <p>
* <p/>
* Maybe should rewrite sometime as a stream?
*
* @author Chris Betts
*/
public class CBBase64
{
/* if speeding up by using array, maybe mess around with this array...
static int binToChar[] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
};
*/
/**
* Purely static class; hence no one should be able to instantiate it...
*/
private CBBase64()
{
}
/**
* Takes a binary byte array and converts it to base64 mime
* encoded data.
*
* @param byteArray an array of 8 bit bytes to be converted
* @return the resultant encoded string
*/
public static String binaryToString(byte[] byteArray)
{
return binaryToString(byteArray, 0);
}
/**
* Takes a binary byte array and converts it to base64 mime
* encoded data.
*
* @param byteArray an array of 8 bit bytes to be converted
* @param offset The first line of the string may be offset by
* by this many characters for nice formatting (e.g. in
* an ldif file, the first line may include 'att value = ...'
* at the beginning of the base 64 encoded block).
* @return the resultant encoded string
*/
public static String binaryToString(byte[] byteArray, int offset)
{
if (byteArray == null) return null; // XXX correct behaviour?
int arraySize = byteArray.length;
int thirdSize = arraySize / 3;
byte[] base64Data = encode(byteArray);
if (base64Data == null) return null; // Exception occurred.
return format(base64Data, offset);
}
/**
* This returns a formatted string representing the base64 data.
*
* @param base64Data a byte array of base64 encoded data.
* @param offset the string is formatted to fit inside column 76.
* The offset number provides for the first line to be
* foreshortened (basically for pretty formatting in ldif
* files).
*/
// XXX this is unusually sucky, even for me. Better would be too format on the fly...
public static String format(byte[] base64Data, int offset)
{
String data;
try
{
data = new String(base64Data, "US-ASCII");
}
catch (Exception e)
{
data = new String(base64Data); // should be equivalent to above
}
// some magic to make the columns line up nicely, and everythin,
// including leading space, to fit under column 76...
StringBuffer buffer = new StringBuffer(data);
int i = 76 - offset;
while (i < base64Data.length)
{
buffer.insert(i, "\r\n ");
i += 78;
}
return buffer.toString();
}
/**
* Encodes an arbitrary byte array into an array of base64 encoded bytes
* (i.e. bytes that have values corresponding to the ascii values of base 64
* data, and can be type cast to those chars).
*
* @param byteArray the raw data to encode
* @return the base64 encoded bytes (the length of this is ~ 4/3 the length of
* the raw data).
*/
public static byte[] encode(byte[] byteArray)
{
try
{
int arraySize = byteArray.length;
int outputSize = (arraySize % 3 == 0) ? (arraySize / 3) * 4 : ((arraySize / 3) + 1) * 4;
byte[] output = new byte[outputSize];
// iterate through array, reading off byte triplets and converting to base64
int bufferLength = 0;
for (int i = 0; i <= (arraySize - 3); i += 3)
{
convertTriplet(byteArray[i], byteArray[i + 1], byteArray[i + 2], 3, output, bufferLength);
bufferLength += 4;
}
switch (arraySize % 3)
{
case 0:
break;
case 1:
convertTriplet(byteArray[arraySize - 1], (byte) 0, (byte) 0, 1, output, bufferLength);
break;
case 2:
convertTriplet(byteArray[arraySize - 2], byteArray[arraySize - 1], (byte) 0, 2, output, bufferLength);
break;
}
return output;
}
catch (CBBase64EncodingException e)
{
return null;
}
}
/**
* Encode an arbitrary byte array into an array of base64 encoded bytes.
* That is, bytes that have values corresponding to the ascii values of base 64
* data, and can be type cast to those chars.
*
* @param byteArray the raw data to encode
* @param start the number of padding spaces to have at the start (must be less than colSize)
* @param colSize the length of each line of text (i.e. the right hand margin). Must
* be a multiple of 4.
* @return the base64 encoded bytes (the length of this is ~ 4/3 the length of
* the raw data).
*/
public static byte[] encodeFormatted(byte[] byteArray, int start, int colSize)
throws CBBase64EncodingException
{
try
{
if (colSize % 4 != 0)
{
throw new CBBase64EncodingException("error in encodeFormatted - colSize not a multiple of 4.");
}
if (start >= colSize)
{
throw new CBBase64EncodingException("error in encodeFormatted - start is not less than colSize.");
}
int arraySize = byteArray.length;
int outputSize = start + ((arraySize % 3 == 0) ? (arraySize / 3) * 4 : ((arraySize / 3) + 1) * 4);
outputSize += (outputSize / colSize) + 1; // allow for new lines!
byte[] output = new byte[outputSize];
// iterate through array, reading off byte triplets and converting to base64
for (int i = 0; i < start; i++)
output[i] = (byte) ' '; // pad to 'start' with spaces.
int bufferLength = start;
for (int i = 0; i <= (arraySize - 3); i += 3)
{
convertTriplet(byteArray[i], byteArray[i + 1], byteArray[i + 2], 3, output, bufferLength);
bufferLength += 4;
if (bufferLength % (colSize + 1) == colSize) // check if we're at the end of a column
{
output[bufferLength++] = (byte) '\n';
}
}
switch (arraySize % 3)
{
case 0:
break;
case 1:
convertTriplet(byteArray[arraySize - 1], (byte) 0, (byte) 0, 1, output, bufferLength);
bufferLength += 4;
break;
case 2:
convertTriplet(byteArray[arraySize - 2], byteArray[arraySize - 1], (byte) 0, 2, output, bufferLength);
bufferLength += 4;
break;
}
// final '\n'
if (bufferLength < outputSize) // it should be exactly one less!
{
output[bufferLength++] = (byte) '\n';
}
else
{
System.err.println("wierdness in formatted base 64 : bufferlength (" + bufferLength + ") != 1 + outputsize (" + outputSize + ")");
}
return output;
}
catch (CBBase64EncodingException e)
{
// XXX shouldn't we do something here?
return null;
}
catch (Exception e2)
{
System.err.println("unexpected error in base 64 encoding");
e2.printStackTrace();
return null;
}
}
/**
* Takes a base 64 encoded string and converts it to a
* binary byte array.
*
* @param chars a string of base64 encoded characters to be converted
* @return the resultant binary array
*/
public static byte[] stringToBinary(String chars)
{
if (chars == null) return null;
byte charArray[];
try
{
charArray = chars.getBytes("US-ASCII");
}
catch (UnsupportedEncodingException e)
{
charArray = chars.getBytes();
}
return decode(charArray);
}
/**
* Decodes a byte array containing base64 encoded data.
*
* @param rawData a byte array, each byte 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.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -