位屏蔽和移位逻辑(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。 这意味着一个完全清零的字节将始终产生正确的结果。

最后我的问题是:第二个例子中的逻辑出错了,为什么会产生中文字符?

如果有人能告诉我,我的思维错误的地方,我怎么能纠正它,这将不胜感激。 谢谢!

Interesting Posts