将负面的Python marshal int重新组合成Javascript数字

时间:2014-10-26 18:35:08

标签: javascript python typescript bit-manipulation number-formatting

我在Javascript(特别是Typescript)中为类项目编写客户端Python字节码解释器。解析字节码一直没问题,直到我尝试了一个负数。

在Python中,marshal.dumps(2)提供'i\x02\x00\x00\x00'marshal.dumps(-2)提供'i\xfe\xff\xff\xff'。这是有道理的,因为Python使用具有至少32位精度的两个补码表示整数。

在我的Typescript代码中,我使用相当于Node.js的Buffer类(通过名为BrowserFS的库,而不是ArrayBuffers等)来读取数据。当我看到角色' i' (即buffer.readUInt8(offset) == 105,表示下一个是int),然后我在下一个偏移量上调用readInt32LE来读取一个小端符号长(4个字节)。这适用于正数但不适用于负数:对于1我得到' 1'但是对于' -1'我得到像' -272777233'。

我猜Javascript代表64位数字(浮点数?)。所以,似乎以下应该有效:

var longval = buffer.readInt32LE(offset); // reads a 4-byte long, gives -272777233 
var low32Bits = longval & 0xffff0000; //take the little endian 'most significant' 32 bits
var newval = ~low32Bits + 1; //invert the bits and add 1 to negate the original value
//but now newval = 272826368 instead of -2

我尝试过很多不同的事情,而且我已经坚持了好几天。我无法弄清楚如何使用Javascript / Typescript从二进制编组字符串中恢复Python整数的原始值。另外我想我深深误解了比特是如何工作的。任何想法都会在这里受到赞赏。

一些更具体的问题可能是:

  • 为什么buffer.readInt32LE适用于积极的投注而非负投资?
  • 我是否使用正确的方法来获得最重要的'或者“最低”' 32位(即& 0xffff0000是如何工作的?)
  • 分开但相关:在一个实际的长期'数字(即长于' -2'),我认为有一个符号位和一个幅度,我认为这些信息存储在最高的'数字的2位(即number & 0x000000ff?) - 这是正确的思考方式吗?

1 个答案:

答案 0 :(得分:0)

序列ef bf bd is the UTF-8 sequence for the "Unicode replacement character",Unicode编码器用它来表示无效编码。

听起来,您用于下载数据的任何方法都会意外地通过UTF-8解码器运行并破坏原始数据流。请确保您使用的是blob而不是text,或者等同于您下载字节码的方式。

这只是因为负值而搞砸了,因为正值在UTF-8的法线贴图空间内,因此从原始字节流中翻译成1:1。