Fields Summary |
---|
private static final char[] | intToBase64This array is a lookup table that translates 6-bit positive integer
index values into their "Base64 Alphabet" equivalents as specified
in Table 1 of RFC 2045. |
private static final char[] | intToAltBase64This array is a lookup table that translates 6-bit positive integer
index values into their "Alternate Base64 Alphabet" equivalents.
This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
This alternate alphabet does not use the capital letters. It is
designed for use in environments where "case folding" occurs. |
private static final byte[] | base64ToIntThis array is a lookup table that translates unicode characters
drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
into their 6-bit positive integer equivalents. Characters that
are not in the Base64 alphabet but fall within the bounds of the
array are translated to -1. |
private static final byte[] | altBase64ToIntThis array is the analogue of base64ToInt, but for the nonstandard
variant that avoids the use of uppercase alphabetic characters. |
Methods Summary |
---|
static byte[] | altBase64ToByteArray(java.lang.String s)Translates the specified "alternate representation" Base64 string
into a byte array.
return base64ToByteArray(s, true);
|
static byte[] | base64ToByteArray(java.lang.String s)Translates the specified Base64 string (as per Preferences.get(byte[]))
into a byte array.
return base64ToByteArray(s, false);
|
private static byte[] | base64ToByteArray(java.lang.String s, boolean alternate)
byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
int sLen = s.length();
int numGroups = sLen/4;
if (4*numGroups != sLen)
throw new IllegalArgumentException(
"String length must be a multiple of four.");
int missingBytesInLastGroup = 0;
int numFullGroups = numGroups;
if (sLen != 0) {
if (s.charAt(sLen-1) == '=") {
missingBytesInLastGroup++;
numFullGroups--;
}
if (s.charAt(sLen-2) == '=")
missingBytesInLastGroup++;
}
byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
// Translate all full groups from base64 to byte array elements
int inCursor = 0, outCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
result[outCursor++] = (byte) ((ch2 << 6) | ch3);
}
// Translate partial group, if present
if (missingBytesInLastGroup != 0) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
if (missingBytesInLastGroup == 1) {
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
}
}
// assert inCursor == s.length()-missingBytesInLastGroup;
// assert outCursor == result.length;
return result;
|
private static int | base64toInt(char c, byte[] alphaToInt)Translates the specified character, which is assumed to be in the
"Base 64 Alphabet" into its equivalent 6-bit positive integer.
int result = alphaToInt[c];
if (result < 0)
throw new IllegalArgumentException("Illegal character " + c);
return result;
|
static java.lang.String | byteArrayToAltBase64(byte[] a)Translates the specified byte array into an "alternate representation"
Base64 string. This non-standard variant uses an alphabet that does
not contain the uppercase alphabetic characters, which makes it
suitable for use in situations where case-folding occurs.
return byteArrayToBase64(a, true);
|
static java.lang.String | byteArrayToBase64(byte[] a)Translates the specified byte array into a Base64 string as per
Preferences.put(byte[]).
return byteArrayToBase64(a, false);
|
private static java.lang.String | byteArrayToBase64(byte[] a, boolean alternate)
int aLen = a.length;
int numFullGroups = aLen/3;
int numBytesInPartialGroup = aLen - 3*numFullGroups;
int resultLen = 4*((aLen + 2)/3);
StringBuffer result = new StringBuffer(resultLen);
char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64);
// Translate all full groups from byte array elements to Base64
int inCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int byte0 = a[inCursor++] & 0xff;
int byte1 = a[inCursor++] & 0xff;
int byte2 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
result.append(intToAlpha[byte2 & 0x3f]);
}
// Translate partial group if present
if (numBytesInPartialGroup != 0) {
int byte0 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
if (numBytesInPartialGroup == 1) {
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
result.append("==");
} else {
// assert numBytesInPartialGroup == 2;
int byte1 = a[inCursor++] & 0xff;
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f]);
result.append('=");
}
}
// assert inCursor == a.length;
// assert result.length() == resultLen;
return result.toString();
|
public static void | main(java.lang.String[] args)
int numRuns = Integer.parseInt(args[0]);
int numBytes = Integer.parseInt(args[1]);
java.util.Random rnd = new java.util.Random();
for (int i=0; i<numRuns; i++) {
for (int j=0; j<numBytes; j++) {
byte[] arr = new byte[j];
for (int k=0; k<j; k++)
arr[k] = (byte)rnd.nextInt();
String s = byteArrayToBase64(arr);
byte [] b = base64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Dismal failure!");
s = byteArrayToAltBase64(arr);
b = altBase64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Alternate dismal failure!");
}
}
|