qq jcesstruct構造python解析
6058 ワード
jcesstructはprotobuffのようなシーケンス化構造で、qqは主にこのシーケンス化構造を使用しています.ネット上の資料は少なく、Javaですから、pythonの解析を書きましょう.
フォーマットの内容:
ttlv構造、すなわちtag,type,length,valueの3つの内容.
jcestructの構造はすべてheadで、次の内容です.
head構造
通常headは1バイトで、typeも含まれ、tagはシーケンス番号を表す.
1つのheadの下位4ビットはtypeタイプであり、上位4ビットはtagであり、tagが0 xfに等しい場合、headは2バイトを含み、2番目のバイトはtag値である.
headを取得するコードは次のとおりです.
typeのフォーマットリストは次のとおりです.
値
を選択します.
0
byteまたはbool
1
Short
2
Int
3
Long
4
Float
5
Double
6,7
String 6文字列が短い、1バイトが長さ、7文字列が長い、1 intが長さ
8
Map 後の最初のintは長さを表す
9
List
10
STRUCT_BEGINはJceStructクラスの開始を継承しています
11
STRUCT_ENDはJceStructクラスの終わりを受け継いだ
12
ZERO_TAG
13
TYPE_SIMPLE_LISTが後に加えた構造はbytes配列で、なぜこの構造があるのか分からないが、まずbyteが長さタイプを表し、
フォーマットの内容:
ttlv構造、すなわちtag,type,length,valueの3つの内容.
jcestructの構造はすべてheadで、次の内容です.
head構造
通常headは1バイトで、typeも含まれ、tagはシーケンス番号を表す.
1つのheadの下位4ビットはtypeタイプであり、上位4ビットはtagであり、tagが0 xfに等しい場合、headは2バイトを含み、2番目のバイトはtag値である.
headを取得するコードは次のとおりです.
def readHead():
head = jcestruct.read(1)
headdata = struct.unpack('b',head)
for i in headdata:
#print(i)
print("headData:",end='')
print(hex(i))
headtag = ((i)& 0xF0)>>4
headtype = i&0xF
if 0xF == headtag:
headtag = jcestruct.read(1)
print("headtap:",end='')
print(headtag)
print("headtype:",end='')
print(headtype)
return headtag,headtype
typeのフォーマットリストは次のとおりです.
値
を選択します.
0
byteまたはbool
1
Short
2
Int
3
Long
4
Float
5
Double
6,7
String 6文字列が短い、1バイトが長さ、7文字列が長い、1 intが長さ
8
Map 後の最初のintは長さを表す
9
List
10
STRUCT_BEGINはJceStructクラスの開始を継承しています
11
STRUCT_ENDはJceStructクラスの終わりを受け継いだ
12
ZERO_TAG
13
TYPE_SIMPLE_LISTが後に加えた構造はbytes配列で、なぜこの構造があるのか分からないが、まずbyteが長さタイプを表し、
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 7 16:49:39 2020
@author: lth
"""
import struct
TYPE_BYTE = 0;
TYPE_SHORT = 1
TYPE_INT = 2
TYPE_LONG = 3
TYPE_FLOAT = 4
TYPE_DOUBLE = 5
TYPE_STRING1 = 6
TYPE_STRING4 = 7
TYPE_MAP = 8
TYPE_LIST = 9
# 0A*******0B
TYPE_STRUCT_BEGIN = 10
TYPE_STRUCT_END = 11
TYPE_ZERO_TAG = 12
TYPE_SIMPLE_LIST = 13
def readHead():
head = jcestruct.read(1)
if b'' == head:
print('complete!')
return 0,12
print(head)
headdata = struct.unpack('b',head)
for i in headdata:
headtag = ((i)& 0xF0)>>4
headtype = i&0xF
if 0xF == headtag:
headtag = jcestruct.read(1)
'''
print("headData:",end='')
print(hex(i))
print("headtap:",end='')
print(headtag)
print("headtype:",end='')
print(headtype)
'''
return headtag,headtype
def switchType(typ):
if TYPE_BYTE == typ:
print("tag:byte")
jceData = jcestruct.read(1)
print(int.from_bytes(jceData,'little'))
return int.from_bytes(jceData,'little')
elif TYPE_SHORT == typ: ##short
print("tag:short")
jceData = jcestruct.read(2)
print(jceData)
elif TYPE_INT == typ: ##int
print("tag:int")
jceData = jcestruct.read(4)
print(jceData)
elif TYPE_LONG == typ: ##long
print("tag:long")
jceData = jcestruct.read(8)
print(jceData)
elif TYPE_FLOAT == typ: ##float
print("tag:float")
jceData = jcestruct.read(8)
print(jceData)
elif TYPE_DOUBLE == typ: ###double
print("tag:double")
jceData = jcestruct.read(8)
print(jceData)
elif TYPE_STRING1 == typ: ##sting
print("tag:string")
jceDatalen = jcestruct.read(1)
jceDatalen = int().from_bytes(jceDatalen,byteorder='big', signed=False)
#print(int().from_bytes(jceDatalen,byteorder='little', signed=False))
jceData = jcestruct.read(jceDatalen)
print(jceData)
elif TYPE_STRING4 == typ: ##long string
print("tag:long")
jceDatalen = jcestruct.read(4)
jceData = jcestruct.read(int(jceDatalen))
print(jceData)
elif TYPE_MAP == typ: ##map
print("tag:map",end='')
jceDatalen = jcestruct.read(2) ## map
jceDatalen = int.from_bytes(jceDatalen,'big')
print(jceDatalen)
print('[')
for i in range(0,jceDatalen):
a,b = readHead()
print("key is:",end='')
switchType(b)
a,b = readHead()
print("value is:",end='')
switchType(b)
elif TYPE_LIST == typ: ##list
print("tag:list")
jceDatalen = jcestruct.read(2) ## map
jceDatalen = int.from_bytes(jceDatalen,'big')
print(jceDatalen)
for i in range(0,jceDatalen):
tag,typ = readHead()
switchType(typ)
jceData = jcestruct.read(jceDatalen)
print(jceData)
elif TYPE_STRUCT_BEGIN == typ: ##0a begin 0b end
print("tag:begin")
tag,typ = readHead()
#print(typ)
switchType(typ)
# print(jceData)
elif TYPE_STRUCT_END == typ:
print("tag:end")
jceData = jcestruct.read(1)
print(jceData)
elif TYPE_ZERO_TAG == typ: ##zero
print("tag:deadline")
return
elif TYPE_SIMPLE_LIST == typ: ##simple list
jcestruct.read(1)
tag,typ = readHead()
if typ == TYPE_SHORT:
jceDatalen = jcestruct.read(2)
jceDatalen = int().from_bytes(jceDatalen,byteorder='big', signed=False)
jceData = jcestruct.read(jceDatalen)
print(jceData)
elif typ == TYPE_BYTE:
jceDatalen = jcestruct.read(1)
jceDatalen = int().from_bytes(jceDatalen,byteorder='big', signed=False)
jceData = jcestruct.read(jceDatalen)
print(jceData)
#print(headtag)
if __name__ == '__main__':
jcestruct = open('test.bin','rb') #output
tag1,type1 = readHead()
while(TYPE_ZERO_TAG != type1):
switchType(type1)
tag1,type1 = readHead()
jcestruct.close()