ByteArray 在 kotlin 问题中使用 UTF-8 字符集转换为字符串
ByteArray convert to String with UTF-8 charset in kotlin problem
有点迷茫
// 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 范围内的字节只能出现在某些 well-defined combinations. (这有几个非常有用的特性:它可以让您以很高的概率识别 UTF-8;它还避免了同步、搜索、排序等方面的问题)
在这种情况下,问题中的序列(无符号十六进制的 4E 17 29 33 E0 2A
)不是有效的 UTF-8。
因此,当您尝试使用默认编码 (UTF-8) 将其转换为字符串时,JVM 会替换 replacement character — 值 U+FFFD,如下所示:�
— 代替每个无效字符。
然后,当你将那个转换回UTF-8时,你得到替换字符的UTF-8编码,即EF BF BD
。如果您将其解释为带符号的字节,您将得到 -17 -65 -67
— 如问题中所述。
所以 Kotlin/JVM 正在尽其所能处理无效输入。
有点迷茫
// 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 范围内的字节只能出现在某些 well-defined combinations. (这有几个非常有用的特性:它可以让您以很高的概率识别 UTF-8;它还避免了同步、搜索、排序等方面的问题)
在这种情况下,问题中的序列(无符号十六进制的 4E 17 29 33 E0 2A
)不是有效的 UTF-8。
因此,当您尝试使用默认编码 (UTF-8) 将其转换为字符串时,JVM 会替换 replacement character — 值 U+FFFD,如下所示:�
— 代替每个无效字符。
然后,当你将那个转换回UTF-8时,你得到替换字符的UTF-8编码,即EF BF BD
。如果您将其解释为带符号的字节,您将得到 -17 -65 -67
— 如问题中所述。
所以 Kotlin/JVM 正在尽其所能处理无效输入。