我目前正在编写一个与 Chrome 扩展程序通信的 Java 程序。我需要实现 Chrome 原生消息传递协议才能进行通信。谷歌浏览器文档说:
...每条消息都使用 JSON、UTF-8 编码进行序列化,并以原生字节顺序的 32 位消息长度开头。(来源)
我尝试在 Java 中实现这一点,但是当我的消息有一定长度时我会遇到问题,即使我的实现应该是正确的。这是我当前的实现,基于早期的 SO-答案和问题(例如这里):
// read the message size from Chrome. This part works correctly.
public static int getInt(char[] bytes) {
return (bytes[3]<<24) & 0xff000000|
(bytes[2]<<16) & 0x00ff0000|
(bytes[1]<< 8) & 0x0000ff00|
(bytes[0]<< 0) & 0x000000ff;
}
// transform the length into the 32-bit message length.
// This part works for small numbers, but does not work for length 2269 for example.
public static String getBytes(int length) {
return String.format("%c%c%c%c",
(char) ( length & 0xFF),
(char) ((length>>8) & 0xFF),
(char) ((length>>16) & 0xFF),
(char) ((length>>24) & 0xFF));
}
似乎问题在于java实现字符的方式。我希望像在 C 中那样使用普通字符。在实践中,Java 似乎有时会将这些字符转换为 unicode 字符(或者至少,到目前为止,这是我的怀疑)。这反映在长度为 2269 的 java 程序的以下输出(通过管道传输到 xxd 以显示实际字节)中:
0000000: c39d 0800 00 .....
然而,预期的输出(使用python):
import struct
struct.pack('I', 2269)
# outputs in interactive mode: '\xdd\x08\x00\x00'
这里到底发生了什么?为什么 Java 会将我的“0xDD”转换为“0xC39D”,如何让我的getBytes
函数代表 Chrome 原生消息传递的预期输入?使用另一种语言不是一种选择。