FileDocCategorySizeDatePackage
Base64.javaAPI DocJava SE 6 API10036Tue Jun 10 00:26:00 BST 2008java.util.prefs

Base64

public class Base64 extends Object
Static methods for translating Base64 encoded strings to byte arrays and vice-versa.
author
Josh Bloch
version
1.7, 11/17/05
see
Preferences
since
1.4

Fields Summary
private static final char[]
intToBase64
This 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[]
intToAltBase64
This 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[]
base64ToInt
This 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[]
altBase64ToInt
This array is the analogue of base64ToInt, but for the nonstandard variant that avoids the use of uppercase alphabetic characters.
Constructors Summary
Methods Summary
static byte[]altBase64ToByteArray(java.lang.String s)
Translates the specified "alternate representation" Base64 string into a byte array.

throw
IllegalArgumentException or ArrayOutOfBoundsException if s is not a valid alternate representation Base64 string.

        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.

throw
IllegalArgumentException if s is not a valid Base64 string.


                                       
        
        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 intbase64toInt(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.

throw
IllegalArgumentException or ArrayOutOfBoundsException if c is not in the Base64 Alphabet.

        int result = alphaToInt[c];
        if (result < 0)
            throw new IllegalArgumentException("Illegal character " + c);
        return result;
    
static java.lang.StringbyteArrayToAltBase64(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.StringbyteArrayToBase64(byte[] a)
Translates the specified byte array into a Base64 string as per Preferences.put(byte[]).

        return byteArrayToBase64(a, false);
    
private static java.lang.StringbyteArrayToBase64(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 voidmain(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!");
            }
        }