2013-02-20 84 views
2

我正在使用二进制框架基于WebSocket网络编写应用程序。我想从Python服务器发送值到JS客户端并返回。在javascript中将值转换为bytearray

据我所知,在打包和打包时,包装在8位以上的值取决于endian。 不幸的是,浏览器似乎正在将所有内容发送到little-endian,而网络则是big-endian。所以我读到最好的想法是把所有的值打包成字节数组,所以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。老实说我不明白。由于MSb是一个符号位,因此shortint -1二进制应该是imo 1000000000000001

我在做什么错误,也许有更好的方法来解决endian的问题?

+1

这是两个人的夸奖。 http://en.wikipedia.org/wiki/Two%27s_complement – 2013-02-20 15:03:42

+0

好吧,我现在得到它是如何计算的,但为什么在python中第一次测试时javascript返回'[-1,225,123,128]'返回'[255L,225,123,128]'?我想js记得这个值是有符号的,并且显示-1,但我怎样才能将它转换为无符号值? – 2013-02-20 15:12:08

+0

或者,也许我只是不应该在乎它显示,因为二进制是相同的。但我需要事先知道它的单位测试。 – 2013-02-20 15:24:58

回答

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]