【问题标题】:Decoding and Encoding issue. Different implementations of Base64 Class in android.util.* and java.util.*?解码和编码问题。 android.util.*和java.util.*中Base64类的不同实现?
【发布时间】:2014-05-06 22:17:30
【问题描述】:

我正在编写一个应用程序,它使用给定的字符串 str 执行以下操作:

encode(encrypt(encode(stringToBytearray(str))));

Server收到Base64编码的String,然后解码->解密->解码,得到App发送的String str。

不幸的是,它不适用于所有字符串,长字符串导致长 Base64 字符串,我的服务器抛出以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 5b
 at java.util.Base64$Decoder.decode0(Base64.java:714)
 at java.util.Base64$Decoder.decode(Base64.java:526)
 at Main.decode(Main.java:113)
 at Main.main(ain.java:33)

字符串的格式为“[string, string, ..., string]”,不带“s”。

就像我上面提到的,对于不太长的字符串(抱歉我还不能量化长度),这是可行的。所以我认为我实现它是正确的。

奇怪的是,如果我不发送它,而是 decode(decrypt(decode(stringToBytearray(str))));设备本身的字符串,一切正常。

我的设置: JDK 7、eclipse(adt-bundle、android开发)(Windows 7)

JDK 8,eclipse('普通'java)(Linux(xubuntu))

是因为两个类(Base64)的实现方式不同吗?如果是这样,我怎样才能让它工作?

这里是编码/解码方法:

编码(设备:Windows 7,adt-bundle,Android-Dev,jdk 7):

import android.util.Base64

public byte[] encode(byte[] bytearrayToEncode){
   return Base64.encode(bytearrayToEncode, Base64.NO_WRAP|Base64.URL_SAFE);
}

解码(服务器:Linux,jdk 8):

import java.util.Base64

public byte[] decode(byte[] bytearrayToEncode){
   return Base64.getUrlDecoder().decode(bytearrayToDecode);
}

所有字符串都使用相同的字符集 (utf-8) 进行解码/编码! 编码/解码:Base64

加密:AES

如果您需要更多信息,尽管问,但我想我提供了所有必要的信息。

编辑:

public String bytearrayToString(byte[] bytearray){
    String str = null;
    try {
        str = new String(bytearray, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return str;
}

public byte[] stringToBytearray(String str){
    byte[] bytearray = null;
    try {
        bytearray = str.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return bytearray;
}

【问题讨论】:

  • 0x5b 是 [,正如我所说的字符串格式是 [string, ..., string]。但是,当字符串太长时,为什么所有编码/解码都在设备上工作,而不是在服务器上工作。 (我比较了两个长字符串,它们是相等的)
  • 当长度太大时,您的服务器是否会修剪查询参数?只需尝试回显收到的 base-64 消息并检查它们是否完全相等。因为截断的字符串可能不再是有效的 Base-64 加密消息。
  • 我刚刚发现,第二次调用编码并不适用(即使我认为我已经检查过了)。到目前为止,感谢所有建议!我会试着弄清楚为什么它没有。
  • 我在使用 java.util.Base64 中的不同编码器时遇到了一些困难。您是否尝试过 Base64.getDecoder() 而不是 Base64.getUrlDecoder()?

标签: java android encoding base64 decoding


【解决方案1】:

您必须使用 JSONObjects 将 Base64 字符串发送到服务器。如果是这样,那么 JSONObject 将在字符串中添加“\”转义字符,这些字符是非法的 Base64 字符。你需要做的就是

String rectifiedString = Base64String.replace("\\","");

在服务器端使用获取的字符串之前。

可选

也在服务器端使用

import javax.xml.bind.DatatypeConverter;

String result = DatatypeConverter.printBase64Binary(bytearrayToDecode);

byte[] result = DatatypeConverter.parseBase64Binary(str);

改为。

它不仅可以完成工作,而且编码/解码速度更快 (as benchmarked here)。

【讨论】:

  • 在我看来 printBase64Binary 会为您去除反斜杠。感谢您的洞察力。我和 OP 有同样的问题。
【解决方案2】:

如果您的编码字符串中有空格,这是 base64 中的非法字符。如果您删除它,它仍然会在您链接到的转换器中生成相同的图像/数据,并且现在也可以由您的代码解码。

更新: 一些解码器(如您链接的解码器,或 Java 中的 Base64.getMimeDecoder())忽略非法字符,其他解码器(如 Base64.getDecoder())不允许它们。

【讨论】:

    【解决方案3】:

    用于编码:

    Base64.getEncoder().encodeToString(yourString.getBytes("UTF-8"));
    

    并解码:

    byte[] decodedBytes = Base64.getDecoder().decode(yourString);
    String stringDecode = new String(decodedBytes, "UTF-8");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-21
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多