2017-05-14 44 views
0

我需要從perl移植代碼packs byte string。在Perl中,它看起來像下面這樣:python的perl pack/unpack(B *)函數的模擬嗎?

pack 'B*', '0100001000111110010100101101000010010001' 

我沒有看到python struct moduleB*格式的模擬。也許有解決方案不要發明自行車?

老實說,description is not clear for me, so i even can't imagine how it works由自己實現它:

同樣,B和B格式打包一個字符串,它也是許多位 長。每種這樣的格式都會生成1位結果。這些是 ,通常後跟像B8或B64一樣的重複計數。

每個結果位 都基於相應輸入 字符的最低有效位,即在ord($ char)%2上。特別是,字符「0」和 「1」與字符「\ 000」和「\ 001」一樣產生位0和1。

從輸入字符串的開頭開始,每個 字符的8元組被轉換爲1個字符的輸出。

使用格式b,8元組的第一個字符 決定了一個字符的最低有效位 ;與格式B,它決定了一個字符的最高有效位 。

如果輸入字符串的長度不能整除 8,則其餘部分被打包,就好像輸入字符串在末尾填充了 空字符一樣。同樣在拆包過程中,「額外」位 被忽略。

如果輸入的字符串比所需的長,則會忽略其餘的 字符。

A *爲重複計數使用輸入字段的所有字符 。在解包時,位被轉換爲0和0的字符串。

因此,字符串被分成8個符號塊。如果最後一個塊少於8個符號,則最後填充空字符爲8個符號。然後,每個塊變成一個字節。

但我不明白,結果是什麼?這裏B8和B64下的含義是什麼?

回答

1

我不知道確切的Perl的語義,但這裏是我猜測他們:

def pack_bit_string(bs): 
    ret = b'' 
    while bs: 
     chunk, bs = bs[:8], bs[8:] 
     # convert to an integer so we can pack it 
     i = int(chunk, 2) 
     # Handle trailing chunks that are not 8 bits 
     # Note this as an augmented assignment, perhaps also read as 
     # i = i << (8 - len(chunk)) 
     i <<= 8 - len(chunk) 
     ret += struct.pack('B', i) 
    return ret 

評論是內聯。如果你知道的東西,如「輸入少於64位」可以避開環路及使用Q爲struct.pack

2

int -object有to_bytes - 方法:

binary = '0100001000111110010100101101000010010001' 
number = int(binary, 2) 
print(number.to_bytes((number.bit_length()+7)//8, 'big')) 
# b'B>R\xd0\x91'