在JavaScript中将值转换为字节数组
我正在写一个基于WebSocket网络的应用,使用的是二进制帧。我想把值从Python服务器发送到JavaScript客户端,然后再返回。
根据我的了解,打包超过8位的值时,解包和打包的方式会受到字节序(endian)的影响。可惜的是,浏览器似乎总是以小端字节序(little-endian)发送数据,而网络使用的是大端字节序(big-endian)。所以我了解到,最好的办法是把所有值打包成字节数组,这样字节序就不成问题了。
我为JavaScript写了这个函数:
valueToByteArray: function(value, bytes_length) {
var bytes_array = [];
for (var i=bytes_length - 1; i>=0; --i) {
conjunction_val = 0xFF << i*8;
shift = i*8;
bytes_array.push((value & conjunction_val) >> shift);
}
return bytes_array;
}
我也为它写了测试:
test("Pack value to Byte array", function() {
equal(
BufferUtility.valueToByteArray(-2000000, 4),
[255, 225, 123, 128],
"Value packed OK"
); // fail returns [-1, 225, 123, 128], same function in python returns [255L, 225, 123, 128]
equal(
BufferUtility.valueToByteArray(4000000, 4),
[0, 61, 9, 0],
"Value packed OK"
); // pass
equal(
BufferUtility.valueToByteArray(0, 2),
[0, 0],
"Value packed OK"
); // pass
equal(
BufferUtility.valueToByteArray(-1, 2),
[128, 1],
"Value packed OK"
); // fail returns [255, 255]
});
不过只有第二个和第三个测试通过,似乎对带符号的值不太管用。我还在Python上检查了这些值,发现struct.pack('>h', -1)
的结果是\xFF\xFF
。老实说,我不太明白这个。因为最高位是符号位,所以我认为短整型-1的二进制应该是1000000000000001
。
我哪里做错了?有没有更好的方法来解决字节序的问题?
1 个回答
1
我在Freenode的#javascript频道找到了这段代码,没想到它竟然能正常工作,虽然它的做法和之前的代码完全不同 :|
function valueToByteArray(value, bytes_length) {
var bytes_array = [];
while (bytes_length > 0){
var byte = value & 0xFF;
value >>= 8;
bytes_length--;
bytes_array.push(byte);
}
return bytes_array.reverse();
}
console.log(valueToByteArray(-2000000, 4));
<< [255, 225, 123, 128]