Base64 编码/解码问题:解码后的字符串为“?”

发布于 2024-11-17 08:46:45 字数 554 浏览 2 评论 0 原文

我正在尝试读取图像并使用 Base64 编码将其转换为字节数组,然后转换为字符串以通过网络发送。问题是,当我尝试解码 Base64 编码的字符串时,我得到的数据不正确。

例如。我面临以下特殊字符的问题。

我使用以下代码进行编码:

byte[] b = Base64.encodeBase64(IOUtils.toByteArray(loInputStream));
String ab = new String(b);

IOUtilsorg.apache.commons.io.IOUtils

和 loInput

Code 用于解码:

byte[] c = Base64.decodeBase64(ab.getBytes());
String ca = new String(c);
System.out.println(ca);

它打印 ? 来解码字符串。

任何人都可以让我知道这个问题。

I am trying to read an image and use Base64 encoding to convert it into byte array and then to string to send it over network. The problem is that when I try to decode the Base64 encoded string, I am getting incorrect data.

For eg. I am facing issue with below special character.

I am using following code for encoding:

byte[] b = Base64.encodeBase64(IOUtils.toByteArray(loInputStream));
String ab = new String(b);

IOUtils is org.apache.commons.io.IOUtils.

and loInput

Code for decoding:

byte[] c = Base64.decodeBase64(ab.getBytes());
String ca = new String(c);
System.out.println(ca);

It prints ? for decoded String.

Can anyone please let me know the issue.

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

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

发布评论

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

评论(2

荒人说梦 2024-11-24 08:46:45

如果您的输入是图像,则将其编码为 base64 是有意义的 - base64 是文本,可以用字符串表示。

再次解码,您会得到原始图像。图像通常是二进制格式;尝试将其转换为字符串是没有意义的 - 它不是文本。

也就是说,最后两行:

   String ca = new String(c);
   System.out.println(ca);

这样做根本没有意义。

如果您想检查解码是否产生与原始输入相同的输出,请执行以下操作

  System.out.println("Original and decoded are the same: " + Arrays.equals(b,c));

(或将字节数组保存到文件并在图像查看器中查看图像)

If your input is an image, it makes sense to encode it as base64 - base64 is text, and can be represented by a String.

Decoding it again though, you get the original image. An image is usually a binary format; it does not make sense to try to convert that to a string - it is not text.

That is, the last 2 lines:

   String ca = new String(c);
   System.out.println(ca);

Simply does not make sense to do.

If you want to check that the decoding produces the same output as the original input, do e.g.

  System.out.println("Original and decoded are the same: " + Arrays.equals(b,c));

(Or save the byte array to a file and view the image in an image viewer)

少钕鈤記 2024-11-24 08:46:45

正如我在其他地方所说的 ,在Java中,String用于文本,byte[]用于二进制数据。

字符串≠字节[]

文本≠二进制数据

图像是二进制数据。 Base64 是一种允许通过 US_ASCII 兼容文本通道传输二进制数据的编码(对于 ASCII 文本的超集有类似的编码:Quoted Printable)。

因此,它就像:

图像(二进制数据)→图像(文本,Base64编码的二进制数据)→图像(二进制数据)

,您将在其中使用StringencodeBase64String(byte[]) code> 进行编码,byte[]decode(String) 进行解码。这些是 Base64 唯一合理的 API,byte[]encodeBase64(byte[]) 具有误导性,结果是 US_ASCII 兼容的文本(因此,一个 String不是字节[])。

现在,文本具有字符集和编码,String 在内部使用固定的 Unicode/UTF-16 字符集/编码组合,并且在将某些内容从 时必须指定字符集/编码>String,显式或隐式使用平台的默认编码(这是 PrintStream.println() 的作用)。 Base64 文本是纯 US_ASCII,因此您需要使用它,或者 US_ASCII 的超集。 org.apache.commons.codec.binary.Base64 使用 UTF8,它是 US_ASCII 的超集,所以一切都很好。 (OTOH,内部 java.util.prefs.Base64 使用平台的默认编码,所以我想如果您使用 UTF-16 编码启动 JVM,它会中断)。

回到主题:您尝试将解码的图像(二进制数据)打印为文本,这显然不起作用。 PrintStreamwrite() 方法可以写入二进制数据,因此您可以使用这些方法,并且您会得到与您相同的垃圾写了原始图像。使用 FileOutputStream 会更好,并将结果文件与原始图像文件进行比较。

As I've said elsewhere, in Java, String is for text, and byte[] is for binary data.

String ≠ byte[]

Text ≠ Binary Data

An image is binary data. Base64 is an encoding which allows transmission of binary data over US_ASCII compatible text channels (there is a similar encoding for supersets of ASCII text: Quoted Printable).

So, it goes like:

Image (binary data) → Image (text, Base64 encoded binary data) → Image (binary data)

where you would use String encodeBase64String(byte[]) to encode, and byte[] decode(String) to decode. These are the only sane API's for Base64, byte[] encodeBase64(byte[]) is misleading, the result is US_ASCII-compatible text (so, a String, not byte[]).

Now, text has a charset and an encoding, String uses a fixed Unicode/UTF-16 charset/encoding combination internally, and you have to specify a charset/encoding when converting something from/to a String, either explicitly, or implicitly, using the platform's default encoding (which is what PrintStream.println() does). Base64 text is pure US_ASCII, so you need to use that, or a superset of US_ASCII. org.apache.commons.codec.binary.Base64 uses UTF8, which is a superset of US_ASCII, so all is well. (OTOH, the internal java.util.prefs.Base64 uses the platform's default encoding, so I guess it would break if you start your JVM with, say, an UTF-16 encoding).

Back on topic: you've tried to print the decoded image (binary data) as text, which obviously hasn't worked. PrintStream has write() methods that can write binary data, so you could use those, and you would get the same garbage as if you wrote the original image. It would be much better to use a FileOutputStream, and compare the resulting file with the original image file.

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