Python bitstring模塊介紹


 

一、bitstring簡介

  A Python module to help you manage your bits。

  這是一個便於管理bit的Python模塊,其方便性在於借鑒Python中字符串和列表的特性來管理bit。

二、安裝方法

  直接 pip install bitstring。

三、常用類

  bitstring模塊有四個類,Bits、ConstBitStream、BitArray、BitStream,其中BitArray繼承自Bits,而BitStream繼承自ConstBitStream和BitArray,而ConstBitStream也是繼承自Bits。

四、使用方法

  

1
2
3
4
from  bitstring  import  BitArray, BitStream
 
=  BitArray( '0xff01' )
=  BitArray( '0b110' )

  

注意此處應傳入字符串,若直接傳入整型參數,則表示創建一個bit位數為該整型參數值的對象。

1
2
3
>>> s = BitArray( 3 )
>>> s
BitArray( '0b000' )

  

1
2
3
4
>>>  type (a)
< class  'bitstring.BitArray' >
>>>  type (b)
< class  'bitstring.BitArray' >

上述代碼實例化了兩個對象,a和b便可以調用BitArray的方法。

其他構造方法

1
2
3
4
5
6
7
8
9
10
# from a binary string
=  BitArray( '0b001' )
# from a hexadecimal string
=  BitArray( '0xff470001' )
# straight from a file
=  BitArray(filename = 'somefile.ext' )
# from an integer
=  BitArray( int = 540 , length = 11 )
# using a format string
=  BitArray( 'int:11=540' )

  

進制轉換

1
2
3
4
5
6
7
8
>>> a. bin
'1111111100000001'
>>> b. oct
'6'
>>> b. int
- 2
>>> a.bytes
b '\xff\x01'  

注意,轉換后的進制類型為字符串。

bit位增加與減少

此處的操作類似於字符串的疊加,注意+前后的變量順序會影響結果。

1
2
3
4
>>> (b  +  [ 0 ]). hex
'c'
>>> ([ 0 +  b). hex
'6'

  

1
2
3
4
5
6
>>> b + [ 0 ] * 3
BitArray( '0b110000' )
>>> b + [ 1 ] * 2
BitArray( '0b11011' )
>>> b + 5
BitArray( '0xc0' )

此處可用BitArray([0])、BitArray('0b0')、BitArray(bin='0')、'0b0'等方式代替[0],或者直接用整型,比如5,此時代表操作5個bit為0的字符串進行疊加。

以列表/字符串的方法按字符串進行操作

1
2
3
4
5
>>>  print (a[ 3 : 9 ])
0b111110
>>>  del  a[ - 6 :]
>>>  print (a)
0b1111111100  

 

1
2
3
>>> a.prepend( '0b01' )
>>> a.append( '0o7' )
>>> a  + =  '0x06'  

以字符串的方式進行查找和替換

1
2
3
>>> a  =  BitArray( '0xa9f' )
>>> a.find( '0x4f' )
( 3 ,) 

find方法返回所有符合條件的起始下標,此處的下標指的是bit的下標。

a按字符串進行拆分可以分成三個字符串的疊加。

1
2
>>> a  = =  '0b101, 0x4f, 0b1'
True

  

1
2
3
4
5
>>> a = BitArray( '0b110111100000110' )
>>> a.replace( '0b110' , '0b1' )
3
>>> a. bin
'111100001'  

replace方法則是將符合條件的進行替換。

構造bitstring 

使用pack方法進行構建,傳入格式和變量值,則會一一對應進行構造,注意此方法返回的是bitstream類型。

1
2
width, height  =  352 288
=  bitstring.pack( '0x000001b3, 2*uint:12' , width, height)

其中‘2*uint:12’表示構造兩個bit位為12的變量,對應的是width和height變量,‘0x000001b3’本身就是格式化后的變量值,因此不需要再傳入變量。

除了上述方法,還可以將格式和變量值作為變量傳入。

1
2
3
4
5
6
7
8
9
10
11
12
fmt  =  'sequence_header_code,
uint: 12 = horizontal_size_value,
uint: 12 = vertical_size_value,
uint: 4 = aspect_ratio_information'
 
=  { 'sequence_header_code' '0x000001b3' ,
'horizontal_size_value' 352 ,
'vertical_size_value' 288 ,
'aspect_ratio_information' 1
}
 
=  bitstring.pack(fmt,  * * d)

  

以上代碼s的結果為BitStream('0x000001b31601201'),若構造的參數無法轉換成十六進制,則會返回兩個字符串。

 

1
2
3
4
5
6
7
8
9
10
11
12
fmt  =  'sequence_header_code,
uint: 11 = horizontal_size_value,
uint: 12 = vertical_size_value,
uint: 4 = aspect_ratio_information'
 
=  { 'sequence_header_code' '0x000001b3' ,
'horizontal_size_value' 352 ,
'vertical_size_value' 288 ,
'aspect_ratio_information' 1
}
 
=  bitstring.pack(fmt,  * * d)

  

以上代碼s的結果為BitStream('0x000001b32c0240, 0b001')

除此之外還有另外一種構造方法。

1
2
3
4
5
6
7
8
format  =  'hex:32=start_code, uint:12=width, uint:12=height'
 
# 方法一
=  { 'start_code' '0x000001b3' 'width' 352 'height' 288 }
=  bitstring.pack( format * * d)
 
# 方法二
=  bitstring.pack( format , width = 352 , height = 288 , start_code = '0x000001b3' )

  

解析BitStream

BitStream繼承自BitArray,擁有BitArray的所有方法,同時又繼承自ConstBitStream,因此多了解析方法。

BitStream可根據下標pos來進行索引和讀取,默認從0開始。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> s
BitStream( '0x000001b31601201' )
 
>>> s.pos
0
>>> s.read( 24 )
BitStream( '0x000001' )
>>> s.pos
24
>>> s.read( 'hex:8' )
'b3'
>>> s.pos
32

  

read函數中直接填整型數字,則表示從pos位置開始切換該整型值,返回一個新的BitStream。

read函數還可以指定返回的類型,如s.read("hex:8"),表示從pos位置開始讀取8個bit,並以十六進制的方式進行返回,返回的是字符串。

s.read("int:8"),表示從pos位置開始讀取8個bit,並以十進制的方式進行返回,返回的是整型。

 

BitStream還能以列表的方式一次性返回多個解析值。

1
2
>>> s.readlist( '2*uint:12' )
[ 352 288 ]

 

通過格式化的形式解析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 十六進制數據消息
recv_data  =  "0200000002040000000C00000013093132372E302E302E31"
 
# 解析消息
bs  =  bitstring.BitStream( hex = recv_data)
 
fmt_head2  =  """
        hex:32=id_hex,
        hex:8=valueLen_hex,
    """
res_list  =  bs.readlist(fmt_head2)
 
id_hex  =  res_list[ 0 ]
valueLen_hex  =  res_list[ 1 ]
valueLen  =  int (valueLen_hex, base = 16 )
 
fmt_head3  =  """
        hex:valueLen_hex=value_hex,
    """
res_list  =  bs.readlist(fmt_head3, valueLen_hex = valueLen  *  8 )
value_hex  =  res_list[ 0 ]

  

 另外,BitStream提供了一種和readlist類似的方法unpack,可以按照一定的格式從頭開始解析。

1
2
>>> s.unpack( 'bytes:4, 2*uint:12, uint:4' )
[ '\x00\x00\x01\xb3' 352 288 1 ]

 

若中間有x個bit位不需要解析時,可在fmt中使用pad:x來占位,則返回的解析列表不會包含pad占位的內容。 

readlist和unpack的區別在於readlist是根據s.pos值來確定解析的起始位置,而unpack則是每次都是從頭開始解析。  

 大端模式與小端模式 

1
2
3
4
5
6
7
>>> big_endian  =  BitArray(uintbe = 1 , length = 16 )
>>> big_endian
BitArray( '0x0001' )
 
>>> little_endian  =  BitArray(uintle = 1 , length = 16 )
>>> little_endian
BitArray( '0x0100' )

  

 利用bitstring模塊解析JT808報文

JT808消息結構

 

 

JT808消息頭結構

 

 

JT808消息體結構

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM