public static byte[] decodeBase64(String source) {
        // Clean string
        source = source.replaceAll("[^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/_-]+", "");
        int decodedLength = ((source.length() / 4) * 3) + (source.length() % 4 > 0 ? ((source.length() % 4) - 1) : 0);
        byte[] decoded = new byte[decodedLength];

        byte assembledByte = 0;
        int targetIndex = 0;
        for(int i = 0; i < source.length(); i++) {
            int c = ((String) source).charAt(i) & 0xFF;
            int b = (BASE_64_DECODING_TABLE[c - 43] & 0xFF);

            int status = i % 4;

            //  ( 6 | 2) (4 | 4) (2 | 6)
            switch (status) {

            case 0:
                assembledByte = (byte) (b << 2);
                break;

            case 1:
                assembledByte = (byte) (assembledByte | (b >>> 4));
                decoded[targetIndex] = assembledByte;
                targetIndex++;
                assembledByte = (byte) (b << 4);
                break;
            case 2:
                assembledByte = (byte) (assembledByte | (b >>> 2));
                decoded[targetIndex] = assembledByte;
                targetIndex++;
                assembledByte = (byte) (b << 6);
                break;
            case 3:
                assembledByte = (byte) (assembledByte | b);
                decoded[targetIndex] = assembledByte;
                targetIndex++;
                assembledByte = 0;
                break;
            }
        }
        return decoded;
    }