Integer Array to Base64 String

String.fromCharArray is going to create a UTF-8 encoded string, which will alter the bytes in the stream. For example, 242 will be encoded as two bytes instead of one. Any value outside 0-127 will be encoded as multiple bytes when using this function, including all negative integers. Since we can't really work with binary data directly in Apex Code, just store the base-64 encoded value directly in a string or some persistent storage (e.g. a custom setting).


public class Base64 {
    static String[] codes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('');

    // Encodes integers 0-255 into base 64 string
    public static String encode(Integer[] source) {
        // Preallocate memory for speed
        String[] result = new String[(source.size()+2)/3];
        // Every three bytes input becomes four bytes output
        for(Integer index = 0, size = source.size()/3; index < size; index++) {
            // Combine three bytes in to one single integer
            Integer temp = (source[index]<<16|source[index+1]<<8)|source[index+2];
            // Extract four values from 0-63, and use the code from the base 64 index
            result[index]=codes[temp>>18]+(codes[(temp>>12)&63])+(codes[(temp>>6)&63])+codes[temp&63];
        }
        if(Math.mod(source.size(),3)==1) {
            // One byte left over, need two bytes padding
            Integer temp = (source[source.size()-1]<<16);
            result[result.size()-1] = codes[temp>>18]+(codes[(temp>>12)&63])+codes[64]+codes[64];
        } else if(Math.mod(source.size(),3)==2) {
            // Two bytes left over, need one byte padding
            Integer temp = (source[source.size()-2]<<16)|(source[source.size()-1]<<8);
            result[result.size()-1] = codes[temp>>18]+(codes[(temp>>12)&63])+(codes[(temp>>6)&63])+codes[64];
        }
        // Join into a single string
        return String.join(result, '');
    }
}