我正在尝试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==
答案 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)
如果您说您的数据被编码为"十六进制字符串",那么该数据就会被制作成#34;非常可打印"。事实上,"十六进制编码"如果要打印它,对于任何二进制数据都是最简单的事情。使用十六进制编码,没有二进制数据是不可打印的(在我们知道的计算机系统上)!
为了更清楚,让我们说有人给你一个"十六进制编码"字符串a9
(这个想法与您的07050600030102
相同)。这意味着当将某个字节流解释为十六进制字符时,它变为a9
。由于每个十六进制字符[0-9][a-f]
都可以编码为半字节0000
到1111
,因此您可以将实际位解码为: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编码字节。