1

我正在爲JavaScript類(特別是Typescript)類項目編寫客戶端Python字節碼解釋器。解析字節碼會很好,直到我嘗試了一個負數。將負面的Python元帥int整理成Javascript數字

在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來讀取一個小尾數符號long(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?) - 這是正確的方式想想這個?
+0

BrowserFS代碼的真正縮減版本適用於負值。你可以發佈四次調用'readUInt8'的輸出來驗證你正在讀取期望的序列'FE FF FF FF'嗎? – 2014-10-26 18:50:16

+0

這是問題的很大一部分 - 我沒有得到預期的順序。相反,對於-2,我得到:ef bf bd ef – k8si 2014-10-26 18:55:52

+0

好像你剛剛讀取流中錯誤的部分,或者Python沒有使用你認爲它的數字格式。我不認爲有任何合理的按位操作順序會將'EF BF BD EF'變成'-2'。 – 2014-10-26 18:59:30

回答

0

序列號ef bf bdis the UTF-8 sequence for the "Unicode replacement character",Unicode編碼器用於表示無效的編碼。

這聽起來像是你用來下載數據的任何方法都是意外地通過UTF-8解碼器運行並破壞了原始數據流。請確保您使用的是blob而不是text,或者您使用的方式與下載字節碼的方式相同。

由於正值在UTF-8的正常映射空間內,所以只會得到負值,因此得到的結果只會因爲原始字節流1:1翻譯而變差。

+0

哇,我絕對應該先檢查一下,在上面的嚴重程度之前。謝謝。 – k8si 2014-10-26 19:36:32

+0

如果您恰好將您的代碼發佈到GitHub或其他地方,您是否可以在此處發表評論?我在TypeScript團隊中,我們一直在尋找更大/有趣的代碼庫來用於分析和迴歸測試。 – 2014-10-27 03:40:26

+0

我會問我的教授,如果我可以公開知識庫並讓你知道 – k8si 2014-10-28 04:05:08