qq jcestruct 结构 python 解析

jcestruct就是类似于protobuff的序列化结构,qq主要就是使用的这个序列化结构,网上的资料比较少,都是Java的,我就写个python的解析吧。

格式内容:

ttlv结构,即tag,type,length,value三个内容。

jcestruct的结构都是一个head,接一个内容。

head结构

通常head为一个字节,既包含type,还包含一个tag表示序号。

一个head的低四位即为type类型,高四位位tag,若tag等于0xf,则head包含两个字节,第二个字节为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的格式列表如下:

类型
0byte 或 bool
1Short
2Int
3Long
4Float
5Double
6,7String   6字符串比较短,1个字节代表长度,7字符串比较长,1个int表示长度
8Map  后面第一个int表示长度
9List
10STRUCT_BEGIN 继承了JceStruct类的开始
11STRUCT_END 继承了JceStruct类的结束
12ZERO_TAG
13TYPE_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()

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在 Python解析 JSON 可以使用内置的 json 模块。下面是一个示例代码,演示如何将 JSON 字符串解析Python 中的对象: ```python import json # 定义一个 JSON 字符串 json_str = '{"name": "Alice", "age": 25, "city": "New York"}' # 解析 JSON 字符串为 Python 对象 data = json.loads(json_str) # 打印输出 Python 对象 print(data) ``` 输出结果如下: ``` {'name': 'Alice', 'age': 25, 'city': 'New York'} ``` 在上面的代码中,使用 json.loads() 方法将 JSON 字符串解析Python 对象。如果你需要将 Python 对象转换为 JSON 字符串,可以使用 json.dumps() 方法。 ### 回答2: Python是一种非常流行的编程语言,它在解析和处理JSON数据方面非常强大和方便。 要使用Python解析JSON,首先需要导入`json`模块。通过使用`json`模块中的`loads`函数,我们可以将JSON格式的字符串转换成Python对象。例如: ```python import json json_str = '{"name": "John", "age": 30, "city": "New York"}' data = json.loads(json_str) print(data["name"]) # 输出John print(data["age"]) # 输出30 print(data["city"]) # 输出New York ``` 上述代码将一个JSON字符串转换为一个Python字典,我们可以通过访问相应的键来获取对应的值。 如果要将一个Python对象转换为JSON字符串,可以使用`json`模块中的`dumps`函数。例如: ```python import json data = { "name": "John", "age": 30, "city": "New York" } json_str = json.dumps(data) print(json_str) # 输出{"name": "John", "age": 30, "city": "New York"} ``` 上述代码将一个Python字典转换为JSON字符串。 此外,如果要将JSON数据写入文件或从文件中读取JSON数据,可以使用`json`模块中的`dump`和`load`函数。例如: ```python import json data = { "name": "John", "age": 30, "city": "New York" } # 将JSON数据写入文件 with open("data.json", "w") as file: json.dump(data, file) # 从文件中读取JSON数据 with open("data.json", "r") as file: data = json.load(file) print(data["name"]) # 输出John print(data["age"]) # 输出30 print(data["city"]) # 输出New York ``` 上述代码将JSON数据写入名为`data.json`的文件,并从该文件中读取JSON数据。 以上就是使用Python解析JSON的方法。Python的json模块提供了非常简单和方便的API来解析和处理JSON数据。通过将JSON数据转换为Python对象,我们可以轻松地访问和操作其中的数据。 ### 回答3: Python解析JSON非常简单。Python内置了json模块,可以用于处理JSON数据。 要使用json模块,首先需要导入它: ```python import json ``` 假设有一个名为data的JSON字符串,我们可以使用json模块将其解析Python字典或列表: ```python data = '{"name": "John", "age": 30, "city": "New York"}' parsed_data = json.loads(data) ``` 现在,parsed_data将会是一个包含"name"、"age"和"city"键值对的字典。 我们也可以将Python字典或列表转换为JSON格式: ```python data = {"name": "John", "age": 30, "city": "New York"} json_data = json.dumps(data) ``` json_data将会是一个包含"name"、"age"和"city"键值对的JSON字符串。 如果我们要将JSON数据保存到文件中,可以使用下面的方法: ```python data = {"name": "John", "age": 30, "city": "New York"} with open("data.json", "w") as json_file: json.dump(data, json_file) ``` 这将会将JSON数据写入名为"data.json"的文件中。 如果我们要从JSON文件中加载数据,可以使用下面的方法: ```python with open("data.json", "r") as json_file: data = json.load(json_file) ``` 这将会将"data.json"文件中的JSON数据加载为一个字典或列表,并赋值给变量data。 总之,Python解析JSON非常简单,只需导入json模块,并使用其中的方法来处理JSON数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值