在kotlin问题中,ByteArray使用UTF-8字符集转换为字符串

我有点困惑

// default charset utf8
val bytes = byteArrayOf(78, 23, 41, 51, -32, 42)
val str = String(bytes)
// there i got array [78, 23, 41, 51, -17, -65, -67, 42]
val weird = str.toByteArray()

由于某种原因,我将随机值放入字节属性中。为什么不一致???

回答

这里的问题是您的字节不是有效的UTF-8序列。

例如,任何字节序列都可以解释为有效的ISO Latin-1。(具有值 0-31 的字节可能存在问题,但这些通常不会停止存储和处理字符。)类似适用于大多数其他 8 位字符集。

但 UTF-8 并非如此。虽然 1-127 范围内的所有字节序列都是有效的 UTF-8(并与它们在 ASCII 和大多数 8 位编码中的解释相同),但 128-255 范围内的字节只能出现在某些明确定义的组合中. (这有几个非常有用的特性:它可以让您以非常高的概率识别 UTF-8;它还避免了同步、搜索、排序等问题。)

在这种情况下,问题中的序列(4E 17 29 33 E0 2A无符号十六进制)不是有效的 UTF-8。

因此,当您尝试使用默认编码 (UTF-8) 将其转换为字符串时,JVM 会替换替换字符— 值 U+FFFD,如下所示:?— 代替每个无效字符。

然后,当您将转换回 UTF-8 时,您将获得替换字符的 UTF-8 编码,即EF BF BD. 如果您将其解释为有符号字节,您会得到-17 -65 -67- 就像问题中一样。

因此,Kotlin/JVM 正在尽其所能处理无效输入。


以上是在kotlin问题中,ByteArray使用UTF-8字符集转换为字符串的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>