2016-08-17 64 views
0

我有一些小endian編碼字節的文件,我想採取N字節,指定endianess並使用python(任何版本)將它們轉換成十進制數。如何正確地做到這一點?如何將blob轉換爲Python中的整數?

+0

您可以使用結構模塊。 'N'有多大? –

+0

[Python中整數的字節順序可能重複](http://stackoverflow.com/questions/1400012/endianness-of-integers-in-python) –

+0

'N'可以達到文件大小。 – warchantua

回答

4

在Python 3,你可以使用這樣的事情:

int.from_bytes(byte_string, byteorder='little') 
+0

Ooooo我不知道。 +1 –

+0

好的,我們有一個針對Python 3的解決方案。如何爲Python 2做到這一點? – warchantua

+0

使用'struct'作爲@ juanpa.arrivillaga已經提到 – dunder

0

使用Python 3(或2),你可以用struct庫實現這一目標。

with open('blob.dat', 'rb') as f: 
    data = f.read(n) 

現在,您使用合適的format specifier string進行解壓縮。例如,大端INT:

num = struct.unpack(">i",data) 
+0

'struct'也可以在Python2中使用,不是嗎? – VPfB

+0

@VPfB是的。請參閱[文檔](https://docs.python.org/2.7/library/struct.html#module-struct)。 –

2

作爲Harshad Mulmuley的回答顯示,這是很容易在Python 3,使用int.from_bytes方法。在Python 2中,這有點棘手。

struct模塊旨在處理標準C數據類型。它不會處理任意長度的整數(Python 2 long整數),因爲它們不是C本地的,但可以使用簡單的for循環來轉換它們。我預計這將比Python 3更慢,因爲Python for循環比C速度循環要慢,就像int.from_bytes(可能)那樣。

from binascii import hexlify 

def int_from_bytes_LE(s): 
    total = 0 
    for c in reversed(s): 
     total = (total << 8) + ord(c) 
    return total 

# Test 

data = (
    (b'\x01\x02\x03\x04', 0x04030201), 
    (b'\x01\x02\x03\x04\x05\x06\x07\x08', 0x0807060504030201), 
    (b'\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef', 
     0xefcdab8967452301efcdab8967452301), 
) 

for s, u in data: 
    print hexlify(s), u, int_from_bytes_LE(s) 
    #print(hexlify(s), u, int.from_bytes(s, 'little')) 

輸出

01020304 67305985 67305985 
0102030405060708 578437695752307201 578437695752307201 
abcdefabcdef 318753391026855559389420636404904698625 318753391026855559389420636404904698625 

(我把Python 3的打印通話在那裏,所以你可以很容易地驗證我的函數給出了相同的結果int.from_bytes)。

如果您的數據是真的和你不想浪費RAM你扭轉字節的字符串,你可以這樣來做:

def int_from_bytes_LE(s): 
    m = 1 
    total = 0 
    for c in s: 
     total += m * ord(c) 
     m <<= 8 
    return total 

當然,使用一些RAM爲m,但它不會像用於反轉輸入字符串的RAM那麼多。