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

时间:2016-03-30 20:58:19

标签: java hex base64

我正在尝试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==

2 个答案:

答案 0 :(得分:5)

这不符合您的预期:

hexString.getBytes(StandardCharsets.UTF_8)

这只是将十六进制字符串编码为UTF-8 - 您希望解析十六进制字符串,以便每对十六进制数字最终作为单个字节。 base64结果不同的事实只是因为你是base64编码的字节不同。

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

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

答案 1 :(得分:3)

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

如果您说您的数据被编码为"十六进制字符串",那么该数据就会被制作成#34;非常可打印"。事实上,"十六进制编码"如果要打印它,对于任何二进制数据都是最简单的事情。使用十六进制编码,没有二进制数据是不可打印的(在我们知道的计算机系统上)!

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

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

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

正如您所看到的,这两者是两回事。您希望对由数组{97, 57}表示的字节进行base64编码,但最终会得到由数组{-87}表示的base64编码字节。

相关问题