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

发布于 2024-11-13 22:23:24 字数 778 浏览 3 评论 0原文

我需要使用 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) 该类无法按预期工作。

因此,非常感谢任何帮助;提前致谢。

I need to convert some strings using Base64 encoding, and was delighted to see that I didn't have to roll my own converter--Java provides one with javax.xml.bind.DataConverter. However, it has some problems. Here's the output of my time with a 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'

As you can see, it doesn't handle non-alphanumeric characters at all, and also frequently--but not always--truncates the string by two characters.

I guess it might be time to just write my own class, but now I'm bothered that either a) I'm failing at reading the javadoc or something b) The class doesn't work as expected.

So any help is much appreciated; thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

彻夜缠绵 2024-11-20 22:23:24

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

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

hello is not a base64 String, so the parsing fails. You must convert the string into a byte array (try String(text).getBytes('UTF-8')) and then call DC.printBase64Binary() on the byte array to get the data in Base64.

DC.parseBase64Binary() will then convert this Base64 encoded data back into the byte array (which you can then convert back into a string).

花心好男孩 2024-11-20 22:23:24

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

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

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

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

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

A few findings after spending time resolving a similar problem on a GAE platform (Base64 decoder eats last (two) characters when decoding a base64-string from facebook)

If the encoded string is not of a 4*n length then the method DatatypeConverter.parseBase64Binary might drop some trailing characters (rendering the JSON payload syntactically wrong).
My solution was to add the following code:

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

With regards to the code example in the question, I would suggest a change where the test string gets first encoded and then decoded, ie:

return DC.parseBase64Binary(DC.printBase64Binary(String(text).getBytes()))
兮颜 2024-11-20 22:23:24

您没有为其提供完整的base64(包括最终填充)等。如果你给它一个完整的base64字符串,它应该没问题。

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

如果您实际上不是从 Base64 数据开始,则不清楚您真正想要做什么。你谈到“转换一些字符串”——它们是不是base64?

You're not giving it complete base64 (including final padding) etc to start with. If you give it a complete base64 string, it should be fine.

You should only try to interpret data as if it's base64 if it really is base64 to start with. Doing it with arbitrary character sequences is a bad idea.

It's unclear what you're really trying to do, if you're not actually starting with base64 data. You talk about "converting some strings" - are they base64 or not?

脱离于你 2024-11-20 22:23:24

我认为 javax.xml.bind.DatatypeConverter 类可能期望使用 XML 数据或 XSD 类型,如 JavaDoc 方法所述 参数

包含 xsd:base64Binary 的词法表示形式的字符串

就我个人而言,我不太愿意使用面向 XML 转换的类/库来完成类似的事情。

看一下 commons-codec 库,它有 一个易于使用的 Base64

I think that the javax.xml.bind.DatatypeConverter class may expect to work with XML data or XSD types, as the JavaDoc method states for the parameter:

A string containing lexical representation of xsd:base64Binary

Personally I wouldn't feel comfortable using a class/library oriented towards XML transformations for something like this.

Take a look at the commons-codec library, which has an easy-to-use Base64 class.

情归归情 2024-11-20 22:23:24
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);
 }
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);
 }
以可爱出名 2024-11-20 22:23:24

我正在接收 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;
}

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

I'm receiving the data in Deflater zip technique. So, a little function to be decompressed is:

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

Then you can convert the byte to a new String or anything else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文