<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          namedstruct二進(jìn)制結(jié)構(gòu)體解析庫(kù)

          聯(lián)合創(chuàng)作 · 2023-09-28 12:27

          namedstruct 是一個(gè)解析二進(jìn)制結(jié)構(gòu)體的專(zhuān)用庫(kù),它不僅可以解析簡(jiǎn)單的 C 結(jié)構(gòu)體,還可以支持變長(zhǎng)結(jié)構(gòu)體、可擴(kuò)展的結(jié)構(gòu)體之類(lèi)復(fù)雜的情況。它被用來(lái)在 VLCP 中解析 OpenFlow(SDN 專(zhuān)用的二進(jìn)制協(xié)議)。

          使用這個(gè)庫(kù),你會(huì)發(fā)現(xiàn),即便是像 OpenFlow 這樣復(fù)雜的協(xié)議,實(shí)際上只需要將對(duì)應(yīng)的 C 程序的頭文件(比如openflow.h)按照相應(yīng)的規(guī)則進(jìn)行修改,添加一些簡(jiǎn)單的參數(shù)說(shuō)明結(jié)構(gòu)體之間的關(guān)系,就可以用一行代碼將它完整解析出來(lái),或者用一行代碼生成出相應(yīng)的結(jié)構(gòu)體。

          可以使用pip安裝:

          pip install nstruct

          示例

          ###### BASIC STRUCT #####
          
          from namedstruct import *
          mytype = nstruct((uint16, 'myshort'),  # unsigned short int
                          (uint8, 'mybyte'),       # unsigned char
                          (uint8,),               # a padding byte of unsigned char
                          (char[5], 'mystr'),   # a 16-byte bytes string
                          (uint8,),
                          (uint16[5], 'myarray'),    # 
                          name = 'mytype',
                          padding = 1)
          # Create an object
          obj0 = mytype()
          # Access a field
          s = obj0.myshort
          obj0.myshort = 12
          # Create an object with the specified fields initialized
          obj1 = mytype(myshort = 2, mystr = b'123', myarray = [1,2,3,4,5]) 
          # Unpack an object from stream, return the object and bytes size used
          obj2,size = mytype.parse(b'\x00\x02\x01\x00123\x00\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05')
          # Unpack an object from packed bytes
          obj3 = mytype.create(b'\x00\x02\x01\x00123\x00\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05')
          # Estimate the struct size
          size = len(obj0)
          # Estimate the struct size excludes automatic padding bytes
          size2 = obj0._realsize()
          # Pack the object
          b = obj0._tobytes()
          b2 = mytype.tobytes(obj0)
          
          # Use the type in other structs
          
          mytype2 = nstruct((mytype, 'mydata'),
                          (mytype[4], 'mystructarray'),
                          name = 'mytype2',
                          padding = 1)
          
          obj4 = mytype2()
          obj4.mydata.myshort = 12
          obj4.mystructarray[0].mybyte = 7
          b3 = obj4._tobytes()
          
          ###### VARIABLE LENGTH TYPES #####
          
          my_unsize_struct = nstruct((uint16, 'length'),
                                  (raw, 'data'),
                                  padding = 1,
                                  name = 'my_unsize_struct')
          
          """
          >>> my_unsize_struct.create(b'\x00\x07abcde').data
          b'abcde'
          >>> my_unsize_struct.parse(b'\x00\x07abcde')[0].data
          b''
          """
          
          my_size_struct = nstruct((uint16, 'length'),
                                  (raw, 'data'),
                                  padding = 1,
                                  name = 'my_size_struct',
                                  prepack = packrealsize('length'),
                                  size = lambda x: x.length)
          """
          packrealsize('length') is equivalent to:
          
              def _packsize(x):
                  x.length = x._realsize()
          """
          
          """
          >>> my_unsize_struct(data = b'abcde')._tobytes()
          b'\x00\x07abcde'
          >>> my_unsize_struct.parse(b'\x00\x07abcde')[0].data
          b'abcde'
          """
          
          ##### EXTENDING #####
          
          my_base = nstruct((uint16, 'length'),
                           (uint8, 'type'),
                           (uint8, 'basedata'),
                           name = 'my_base',
                           size = lambda x: x.length,
                           prepack = packrealsize('length'),
                           padding = 4)
          
          my_child1 = nstruct((uint16, 'data1'),
                              (uint8, 'data2'),
                              name = 'my_child1',
                              base = my_base,
                              criteria = lambda x: x.type == 1,
                              init = packvalue(1, 'type'))
          
          my_child2 = nstruct((uint32, 'data3'),
                             name = 'my_child2',
                             base = my_base,
                             criteria = lambda x: x.type == 2,
                             init = packvalue(2, 'type'))
          
          """
          Fields and most base class options are inherited, e.g. size, prepack, padding
          >>> my_child1(basedata = 1, data1 = 2, data2 = 3)._tobytes()
          b'\x00\x07\x01\x01\x00\x02\x03\x00'
          >>> my_child2(basedata = 1, data3 = 4)._tobytes()
          b'\x00\x08\x02\x01\x00\x00\x00\x04'
          """
          
          # Fields in child classes are automatically parsed when the type is determined
          obj1, _ = my_base.parse(b'\x00\x07\x01\x01\x00\x02\x03\x00')
          """
          >>> obj1.basedata
          1
          >>> obj1.data1
          2
          >>> obj1.data2
          3
          >>> obj1._gettype()
          my_child1
          """
          
          # Base type can be used in fields or arrays of other structs
          
          my_base_array = nstruct((uint16, 'total_len'),
                                 (my_base[0], 'array'),
                                 name = 'my_base_array',
                                 padding = 1,
                                 size = lambda x: x.total_len,
                                 prepack = packrealsize('total_len'))
          
          obj2 = my_base_array()
          obj2.array.append(my_child1(data1 = 1, data2 = 2, basedata = 3))
          obj2.array.append(my_child2(data3 = 4, basedata = 5))
          """
          >>> obj2._tobytes()
          b'\x00\x12\x00\x07\x01\x03\x00\x01\x02\x00\x00\x08\x02\x05\x00\x00\x00\x04'
          """
          obj3, _ = my_base_array.parse(b'\x00\x12\x00\x07\x01\x03\x00\x01\x02\x00\x00\x08\x02\x05\x00\x00\x00\x04')
          """
          >>> obj3.array[0].data2
          2
          """

           

          瀏覽 8
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91色视| 天天插,天天狠,天天透 | 大香蕉午夜福利 | 蜜桃视频网址 | 超碰人妻免费 |