如何对十六进制字符串进行base-64编码

How to base-64 encode a hex string

我正在尝试对十六进制字符串进行 base-64 编码(复制在下方),但我从 Java8 调用中获得的编码为 base64 的值与我在不同的在线转换器上获得的值不匹配。我想弄清楚我遗漏了哪些步骤(或我正在采取的错误步骤):

//hexString is 07050600030102
Base64.getEncoder().encodeToString(hexString.getBytes(StandardCharsets.UTF_8));

//output I am getting from Java8 ic copied below:
MDcwNTA2MDAwMzAxMDI=

//online converters:
BwUGAAMBAg==

这不符合您的预期:

hexString.getBytes(StandardCharsets.UTF_8)

这只是将十六进制字符串编码为 UTF-8 - 您想要 解析 十六进制字符串,以便每对十六进制数字最终成为一个字节。 base64 结果不同的事实只是因为您使用 base64 编码的字节不同。

要将十六进制字符串解析为字节,您可以使用 Guava(在其他库中)

byte[] bytes = BaseEncoding.base16().decode(hexString);
String base64 = BaseEncoding.base64().encode(bytes);

Jon 的回答是正确的,但我想我会尝试以不同的方式解释它。我认为 encoding/decoding 有时会让人有些困惑。

当您说您的数据被编码为 "hex string" 时,该数据被编码为 "pretty printable"。事实上,如果要打印,"hex encoding" 是您可以对任何二进制数据执行的最简单的操作。使用十六进制编码,没有二进制数据是不可打印的(在我们知道的计算机系统上)!

为了更清楚,假设有人给你一个 "hex encoded" 字符串 a9(这个想法与你的 07050600030102 相同)。这意味着当将某个字节流解释为十六进制字符时,它变成 a9。由于每个十六进制字符:[0-9][a-f] 可以编码为半字节 00001111,您可以将实际位解码为:1010 1001(为简洁起见,使用空白) .所以,十六进制编码为 a9 的实际上是一个字节 10101001

所以,如果你现在 "base64-encode" 它,你应该使用 10101001 作为输入!就字节数组而言,这将是:{-87} 因为 -87 是 Java.[=38 中整数值的二进制补码表示中位序列 10101001 的十进制值=]

当您执行以下操作时:hexString.getBytes(StandardCharsets.UTF_8)hexString.getBytes()(如果您计算机上的默认字符集为 UTF-8),那么您将获得 hexString 根据 UTF-8 编码进行解释,并且由于该编码向后兼容 ASCII 编码,您将得到一个 2 字节数组,其第一个字节是十进制 97 (或二进制01100001)表示字符'a',第二个字节为十进制57,(或二进制00111001)表示字符'9'(十进制的9)。因此,您将从 getBytes() 调用中获得的字节数组是:{97, 57}.

如您所见,这两者是两个不同的东西。您想要对数组 {-87} 表示的字节进行 base64 编码,但最终得到数组 {97, 57}.

表示的 base64 编码字节