javax.xml.bind的Base64编码器/解码器吃掉字符串的最后两个字符

时间:2011-06-07 13:28:52

标签: java encoding base64 decoding

我需要使用Base64编码转换一些字符串,并且很高兴看到我不必滚动我自己的转换器 - Java提供了一个javax.xml.bind.DataConverter。但是,它有一些问题。这是我使用Jython REPL的时间输出:

>>> import javax.xml.bind.DatatypeConverter as DC
>>> import java.lang.String as String
>>> def foo(text):
...   return DC.printBase64Binary(DC.parseBase64Binary(String(text)))
... 
>>> foo("hello")
'hell'
>>> foo("This, it's a punctuated sentence.")
'Thisitsapunctuatedsenten'
>>> foo("\"foo\" \"bar\"")
'foob'
>>> foo("\"foo\" \"bar\"12")
'foobar12'
>>> foo("\"foo\" \"bar\"1")
'foob'

正如您所看到的,它根本不处理非字母数字字符,并且经常 - 但不总是 - 将字符串截断两个字符。

我想这可能是时候编写我自己的类了,但是现在我很烦恼a)我没有阅读javadoc或其他东西b)该类没有按预期工作。

所以任何帮助都非常感谢;提前谢谢。

6 个答案:

答案 0 :(得分:12)

hello不是base64字符串,因此解析失败。您必须将字符串转换为字节数组(尝试String(text).getBytes('UTF-8')),然后在字节数组上调用DC.printBase64Binary()以获取Base64中的数据。

DC.parseBase64Binary()然后将此Base64编码数据转换回字节数组(然后您可以将其转换回字符串)。

答案 1 :(得分:6)

在GAE平台上花费时间解决类似问题后的一些发现(当从facebook解码base64字符串时,Base64解码器会吃掉最后两个字符)

如果编码的字符串长度不是4 * n,则方法DatatypeConverter.parseBase64Binary可能会删除一些尾随字符(使JSON有效负载在语法上错误)。 我的解决方案是添加以下代码:

while (payload.length() % 4 != 0) payload += "=";

关于问题中的代码示例,我建议更改测试字符串首先编码然后解码,即:

return DC.parseBase64Binary(DC.printBase64Binary(String(text).getBytes()))

答案 2 :(得分:1)

你没有给它完整的base64(包括final padding)等开始。如果你给它一个完整的 base64字符串,它应该没问题。

如果确实是 base64,那么你应该只尝试将数据解释为base64。使用任意字符序列进行操作是一个坏主意。

如果您实际上没有使用base64数据,那么目前还不清楚您真正要做的是什么。你谈到“转换一些字符串” - 它们是否是base64?

答案 3 :(得分:0)

我认为javax.xml.bind.DatatypeConverter类可能希望使用XML数据或XSD类型,因为JavaDoc方法声明了the parameter

  

包含xsd:base64Binary

的词汇表示的字符串

就我个人而言,使用面向XML转换的类/库我感到很自在。

查看the commons-codec libraryan easy-to-use Base64 class

答案 4 :(得分:0)

import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.lang.String ;
public class HttpBasicAuthenticationHeader {

 public static void main(String[] args) {
 DatatypeConverter dc;

 String str="ENCODE";

String s="";

try {
s=javax.xml.bind.DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
System.out.println(s);
 }

答案 5 :(得分:0)

我正在接收Deflater zip技术中的数据。因此,要解压缩的一点功能是:

public byte[] descomprimir() throws IOException, DataFormatException {
    final String wsData = "eNqzsa/IzVEoSy0qzszPs1Uy1DNQUkjNS85PycxLt1XyDPbXtbAwtdQ1VLK347JJTixJzMlPzy/Wt+MCAAU6ETY=";
    byte[] data = DatatypeConverter.parseBase64Binary(wsData);

    Inflater inflater = new Inflater();
    inflater.setInput(data);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
    byte[] buffer = new byte[1024];
    while (!inflater.finished()) {
        int count = inflater.inflate(buffer);
        outputStream.write(buffer, 0, count);
    }
    outputStream.close();
    byte[] output = outputStream.toByteArray();
    return output;
}

然后您可以将字节转换为新的String或其他任何内容。