位屏蔽和移位逻辑(Java)
我试图重建一个UTF-16LE编码的字节数组回到字符,而不使用Java API,因为当我尝试执行霍夫曼编码时,我将需要手动执行它。 我给出的代码示例实际上是在Kotlin中,但它的99%的java,所以你不应该有麻烦理解它正在试图完成 – 在这种情况下val是char类型。
这应该是相当简单的,但我相信我的逻辑存在一个缺陷,并希望找到我的想法出错的地方。
忽略任何不在Unicode基本多语言平面中的UNICODE字符,我有以下代码行:
val c = ((((stringBytes[i].toInt()) shl 8) and 0x000000FF) or (stringBytes[i - 1].toInt() and 0x000000FF)).toChar()
它工作,但是我不确定它是否正确,因为直觉上我想用下面的方式来写(注意唯一的变化是第一个掩码)
val c = ((((stringBytes[i].toInt()) shl 8) and 0x0000FF00) or (stringBytes[i - 1].toInt() and 0x000000FF)).toChar()
然而,这出来不正确(例如显示中文字符),而第一行代码的作品。
我脑海中将BMP中字符的字节组合起来的步骤是:
- 将第一个(最重要的)字节向左移8
- 并用0x0 … FF..00来清除所有不必要的位。
- 和LSB与0x0 … FF来清除LSB以外的所有不必要的位
- 最后,把这些值合起来产生一个2字节的char值。
编辑:只是意识到第一行的代码只工作,因为只有英文字符在BMP内使用和第一个字节通常是十六进制0x00。 这意味着一个完全清零的字节将始终产生正确的结果。
最后我的问题是:第二个例子中的逻辑出错了,为什么会产生中文字符?
如果有人能告诉我,我的思维错误的地方,我怎么能纠正它,这将不胜感激。 谢谢!