将范围为 -128 到 127 的字节数组转换为字符串数组
Posted
技术标签:
【中文标题】将范围为 -128 到 127 的字节数组转换为字符串数组【英文标题】:Converting a byte array with range of -128 to 127 to String array 【发布时间】:2022-01-21 16:23:23 【问题描述】:我有一个散列密码的函数,它返回一个字节[],其中条目使用从-128 到 127 的整个字节数据类型。我尝试使用new String(byte_array, StandardCharsets.UTF_8);
将字节[] 转换为字符串。这确实返回了一个字符串——但是它不能正确地编码负数——因此它将它们编码为一个“�”字符。当使用 new String(new byte[]-1, StandardCharsets.UTF_8).equals(new String(new byte[]-2, StandardCharsets.UTF_8))
比较其中两个字符时,结果表明所有负数的字符串表示形式都相等,因为上面的表达式返回 true。虽然这并没有完全破坏我的哈希功能,因为相同表达式的哈希仍然会产生相同的结果,但这显然不是我想要的,因为它增加了两个不同输入产生相同输出的机会。
是否有一些简单的解决方法或任何替代想法如何将字节 [] 转换为字符串?对于上下文,我想使用字符串稍后将其写入文件以将其存储在文件中,然后再次读取以将其与其他哈希进行比较。
编辑:在尝试了一些来自 cmets 的提示后,我的解决方案是将 byte[] 转换为 char[] 并将 128 添加到每个值。然后可以轻松地将 char 数组转换为 String 或直接写入文件(byteHash 是 byte[]):
char[] charHash = new char[byteHash.length];
for(int i = 0; i < byteHash.length; i++)
charHash[i] = (char) (byteHash[i]+128);
return new String(charHash);
我不太喜欢这个解决方案,但它确实有效。
【问题讨论】:
哈希的字节不代表 any 编码的字符,更不用说 UTF-8 了。试图将它们显示为字符或将它们视为字符串没有任何意义。如果你想让它变得可读,通常要做的事情是构建一个字符串,其中每个字节都被视为 0 到 255 之间的无符号值,并使用基数 16 转换为两个字符。 请参阅docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/…,了解将字节数组转换为十六进制字符串的简单方法,反之亦然。 @Shawn 如何将范围从 -128/127 移动到 0/255。除了在 c++ 中,我认为 java 不支持无符号数据类型。我不一定要寻找人类可读的字符串,而是寻找可以写入和读取文件以稍后将其与新哈希进行比较的东西。 您可以使用 OutputStream 和 InputStream 方法写入和读取字节数组(但不能使用 Writer/Reader,因为您使用的是二进制数据,而不是文本)。 @BillMüller - 如何将每个字节值 b 的范围从 -128/127 移动到 0/255,该值为((int)b) & 255
。
【参考方案1】:
对此的适当解决方案是使用十六进制 (https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/HexFormat.html) 或 Base64 (https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html) 之类的编码将任意字节序列可逆地转换为字符串。
【讨论】:
以上是关于将范围为 -128 到 127 的字节数组转换为字符串数组的主要内容,如果未能解决你的问题,请参考以下文章