11

我有一个用于 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 公共问题,我将不胜感激。:^)

4

3 回答 3

11

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

编辑

如果您以 API8 为目标,只需从 API8 中获取 Base64 实现的源代码(它是android/util/Base64.java)并复制到您的项目中。

于 2012-11-25T23:40:48.023 回答
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();   
}
于 2012-11-25T23:41:19.783 回答
0

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

import com.fasterxml.jackson.core.Base64Variants;

public class Foo {
    String encodeBase64(byte[] string) {
        return Base64Variants.getDefaultVariant().encode(string.getBytes());
    }
}
于 2015-09-22T16:36:32.510 回答