Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Base64 library that is compatible with both Android and Java

I have a common library that I use for both Java and Android projects and it requires a base64 encoder/decoder. The trouble is, the Apache commons library does not work with Android, at least not that I have been able to successfully implement - due to Android already implementing and earlier version and thus causing an error at run time whenever I attempt to encode or decode:

Base64.decodeBase64

Returns the error:

AndroidRuntime(1420): java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.decodeBase64

If anyone knows of a base64 library that is compatible with both Java and Android, or can explain to me how to get around the Apache commons issue, I would be very grateful. :^)

like image 954
Roy Hinkley Avatar asked Nov 25 '12 23:11

Roy Hinkley


People also ask

What is Base64 encoding in Android?

Sometimes need to encode/decode some data. A simple way to do it is to use Base64 Encoder , which is available in Android SDK since API 8. This class contains methods for encoding and decoding the Base64 representation of binary data. We can use the following code to encode/decode any String value. import android.

What is Base64 string in Java?

What is Base64? Base64 is a binary-to-text encoding scheme that represents binary data in a printable ASCII string format by translating it into a radix-64 representation. Each Base64 digit represents exactly 6 bits of binary data.

How do you encode a decode string in Java Base64 encoding?

Encoder using getEncoder() and then get the encoded string by passing the byte value of actualString in encodeToString() method as parameter. byte[] actualByte= Base64. getDecoder(). decode(encodedString);

How do you decode a string in Java?

Encoding and Decoding String into Base64 Java encodeBase64(byte[]) which encodes byte array as per the base64 encoding algorithm and returns an encoded byte array, which can be converted into String. Later half, we will decode the String by calling Base64. decodeBase64(byte[]) method.


2 Answers

There's just "base64". It so trivial that you can google for any "java base64" and use any implementation.

EDIT

If you target pre API8, simply grab the source from Base64 implementation from API8 (it is android/util/Base64.java) and copy into your project.

like image 168
Marcin Orlowski Avatar answered Oct 06 '22 08:10

Marcin Orlowski


Roll your own.

Here's decoding:

      static private int FromBase64Char(int c)
{
    if(c >= 'A' && c <= 'Z')
        return c - 'A';
    else if(c >= 'a' && c <= 'z')
        return c - 'a' + 26;
    else if(c >= '0' && c <= '9')
        return c - '0' + 52;
    else if(c == '+')
        return 62;
    else if(c == '/')
        return 63;
    else
        throw new IllegalArgumentException(); //Depends on how do you want to handle invalid characters
}


static public byte[] FromBase64(String s) throws IllegalArgumentException
{
    if(s == null)
        return null;

    int l = s.length();
    if(l == 0)
        return new byte[0];

    if(l % 4 != 0)
        throw new IllegalArgumentException();

    boolean Padded = (s.charAt(l-1) == '=');
    boolean Padded2 = (s.charAt(l-2) == '=');
    int ll = (Padded ? l-4 : l);
    int triad;

    byte [] b = new byte[(ll*3)/4 + (Padded ? (Padded2 ? 1 : 2) : 0)];

    int i, j = 0;
    for(i=0; i<ll; i+=4)
    {
        triad = 
            (FromBase64Char(s.charAt(i)) << 18) |
            (FromBase64Char(s.charAt(i+1)) << 12) |
            (FromBase64Char(s.charAt(i+2)) << 6) |
            FromBase64Char(s.charAt(i+3));

        b[j++] = (byte)((triad >> 16) & 0xff); 
        b[j++] = (byte)((triad >> 8) & 0xff);
        b[j++] = (byte)(triad & 0xff);
    }
    //The final chunk
    if(Padded)
    {
        if(Padded2) //Padded with two ='s
        {
            triad = (FromBase64Char(s.charAt(ll)) <<2 ) | (FromBase64Char(s.charAt(ll+1)) >> 4);
            b[j++] = (byte)triad;
        }
        else //Padded with one =
        {
            triad =
                (FromBase64Char(s.charAt(ll)) << 10) |
                (FromBase64Char(s.charAt(ll+1)) << 4) |
                (FromBase64Char(s.charAt(ll+2)) >> 2);  
            b[j++] = (byte)((triad >> 8) & 0xff);
            b[j++] = (byte)(triad & 0xff);
        }
    }
    return b;
}

And here's encoding:

private final static String BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        PAD1 = "=", PAD2 = "==";

static public String ToBase64(final byte [] a)
{
    int l = a.length;
    StringBuilder sb = new StringBuilder((l+3)*4/3);
    int i;
    int mod = l % 3;
    int ll = l - mod;
    int triad;
    for(i=0;i<ll;i+=3)
    {
        triad = (a[i]<<16) | (a[i+1]<<8) | a[i+2];
        sb.append(BASE64_ALPHABET.charAt((triad >> 18) & 0x3f));
        sb.append(BASE64_ALPHABET.charAt((triad >> 12) & 0x3f));
        sb.append(BASE64_ALPHABET.charAt((triad >> 6) & 0x3f));
        sb.append(BASE64_ALPHABET.charAt(triad & 0x3f));
    }
    if(mod == 1)
    {
        sb.append(BASE64_ALPHABET.charAt((a[i] >> 2) & 0x3f));
        sb.append(BASE64_ALPHABET.charAt((a[i] << 4) & 0x3f));
        sb.append(PAD2);
    }
    if(mod == 2)
    {
        triad = (a[i]<<8) | a[i+1];
        sb.append(BASE64_ALPHABET.charAt((triad >> 10) & 0x3ff));
        sb.append(BASE64_ALPHABET.charAt((triad >> 4) & 0x3f));
        sb.append(BASE64_ALPHABET.charAt((triad << 2) & 0x3f));
        sb.append(PAD1);        
    }
    return sb.toString();   
}
like image 25
Seva Alekseyev Avatar answered Oct 06 '22 08:10

Seva Alekseyev