是否有与Android和Java兼容的Base64库

时间:2012-11-25 23:38:34

标签: java android base64

我有一个用于Java和Android项目的公共库,它需要base64编码器/解码器。问题是,Apache commons库不适用于Android,至少不是我能够成功实现 - 由于Android已经实现和早期版本,因此在我尝试编码或解码时在运行时导致错误:

Base64.decodeBase64

返回错误:

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

如果有人知道一个兼容Java和Android的base64库,或者可以向我解释如何解决Apache commons问题,我将非常感激。 :^)

3 个答案:

答案 0 :(得分:10)

只有“base64”。它是如此微不足道,你可以google任何“java base64”并使用任何实现。

修改

如果你定位API8之前,只需从API8中获取Base64实现的源代码(它是android/util/Base64.java)并复制到你的项目中。

答案 1 :(得分:2)

自己动手。

这是解码:

      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;
}

这是编码:

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();   
}

答案 2 :(得分:0)

在我的应用程序中,我使用jackson并提供base64编码器/解码器,如果你的应用程序也使用Jackson,你可以使用它。

import com.fasterxml.jackson.core.Base64Variants;

public class Foo {
    String encodeBase64(byte[] string) {
        return Base64Variants.getDefaultVariant().encode(string.getBytes());
    }
}