python3 bytes解析为数字 struct unpack

本文介绍如何使用Python的struct库解析二进制数据,包括不同字节序和数字类型的处理方法。通过实例演示了如何将二进制流转换为UINT8、UINT16、UINT32和UINT64等数字类型。
部署运行你感兴趣的模型镜像

主要分为解析为 UINT8、UINT16、UINT32、UINT64等数字类型,即分别对应将每1、2、4、8个字节放一起解释为一个数字,这其中对于多于一个字节的情况又分大小端处理
推荐使用自带的struct库解析,方法比较通用
用法
strcut.unpack(fmt, byte) 返回值是一个list,从二进制流类型,变为int型
其中fmt为格式化字符串,分为两部分,开头控制大小端,后面通过字符控制数字类型,常用如下

fmt 含义
! 大端序,和>相同

大端序
< 小端序
B uint8类型
b int8类型
H uint16类型
h int16类型
I uint32类型
i int32类型
L uint64类型
l int64类型
s ascii码,s前带数字表示个数

更多详细fmt的用法可用help(strcut)
例子

import struct

m = b'\x01\x01\x02\x01\x02\x03\x04' #7个字节
a=struct.unpack('!BHI', m) 

for i in a:
    print(hex(i)) # 0x1 0x102 0x1020304

在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think>我们专注于使用Pythonstruct模块解析bytes数据。根据引用内容,struct模块的核心功能是处理二进制数据与Python数据类型的转换,支持打包(pack)和解包(unpack)操作。下面详细介绍解析方法: ### 1. **基本使用步骤** - **导入模块**:`import struct` - **定义格式字符串(fmt)**:指定二进制数据的结构(如数据类型、字节序等)。 - **解包操作**:使用 `struct.unpack(fmt, bytes_data)` 将bytes解析为元组。 ### 2. **格式字符串(fmt)的组成** 格式字符串由两部分组成: - **字节序与对齐控制(可选)**:放在开头,如 `@`(默认,本机顺序)、`<`(小端)、`>`(大端)、`!`(网络序,大端)。 - **数据类型标识**:指定每个字段的类型和长度,例如: - `i`:4字节整数(int) - `f`:4字节浮点数(float) - `s`:字节串(需指定长度,如 `4s` 表示4字节字符串) - 其他常见类型:`b`(有符号字节)、`B`(无符号字节)、`h`(短整数)、`d`(双精度浮点数)等。 示例格式字符串: - `&#39;<i4s f&#39;`:小端模式,依次为整数(4字节)、4字节字符串、浮点数(4字节)。 - `&#39;!2H&#39;`:网络序,两个无符号短整数(各2字节)。 ### 3. **解包操作示例** 根据引用[1]和[2]的示例,解包步骤如下: ```python import struct # 示例1:解析整数和字符串(引用[1]) bytes_data = b&#39;\xe9\x03\x00\x00Lisi\x9a\x99\xd9?&#39; # 原始bytes # 格式:&#39;i4sf&#39; → 整数(4字节) + 4字节字符串 + 浮点数(4字节) unpacked_data = struct.unpack(&#39;i4sf&#39;, bytes_data) # 返回元组 (1001, b&#39;Lisi&#39;, 1.7) # 处理字符串:将bytes子串解码 user_id = unpacked_data[0] user_name = unpacked_data[1].decode(&#39;utf-8&#39;) # 解码为字符串 height = unpacked_data[2] print(f"ID: {user_id}, Name: {user_name}, Height: {height}") # 示例2:解析两个整数(引用[2]) bytes_data2 = b&#39;\x14\x00\x00\x00\x11\x00\x00\x00&#39; # 两个整数: 20, 17 a, b = struct.unpack(&#39;ii&#39;, bytes_data2) # 两个整数 print(f"a={a}, b={b}") # 输出: a=20, b=17 ``` ### 4. **处理字节序(Endianness)** 根据引用[4],字节序影响多字节数据的解释: - **小端(Little-endian)**:低位字节在前,格式前缀 `<`(如 `&#39;<i&#39;`)。 - **大端(Big-endian)**:高位字节在前,格式前缀 `>` 或 `!`(网络序)。 示例: ```python # 假设bytes_data = b&#39;\x00\x00\x00\x01&#39;(大端表示整数1,小端表示16777216) big_endian_int = struct.unpack(&#39;>i&#39;, b&#39;\x00\x00\x00\x01&#39;)[0] # 输出: 1 little_endian_int = struct.unpack(&#39;<i&#39;, b&#39;\x00\x00\x00\x01&#39;)[0] # 输出: 16777216 ``` ### 5. **解析数字类型(UINT8, UINT16等)** 根据引用[4]: - **单字节**:`B`(无符号)、`b`(有符号)。 - **多字节**:指定字节序和类型: - 2字节:`H`(无符号短整数)、`h`(有符号短整数)。 - 4字节:`I`(无符号整数)、`i`(有符号整数)。 - 8字节:`Q`(无符号长整数)、`q`(有符号长整数)。 示例: ```python # 解析大端序的UINT16(2字节) uint16_data = struct.unpack(&#39;>H&#39;, b&#39;\x01\x02&#39;)[0] # 0x0102 = 258 ``` ### 6. **注意事项** - **数据长度匹配**:格式字符串的长度需与bytes数据总长度一致,否则抛出 `struct.error`。 - **字符串处理**:`s` 类型返回bytes子串,需手动解码。 - **性能**:对大型数据,使用 `struct.iter_unpack()` 流式解析。 ### 完整示例:解析自定义协议 假设协议格式:`[2字节小端长度n][n字节字符串][4字节大端整数]` ```python bytes_data = b&#39;\x05\x00Hello\x00\x00\x00\x0A&#39; # 长度5 + "Hello" + 整数10 # 步骤1:解析长度(小端2字节) length = struct.unpack(&#39;<H&#39;, bytes_data[:2])[0] # 0x0005=5 # 步骤2:解析字符串(5字节) start_index = 2 end_index = start_index + length string_part = bytes_data[start_index:end_index].decode(&#39;utf-8&#39;) # "Hello" # 步骤3解析整数(大端4字节) int_part = struct.unpack(&#39;>I&#39;, bytes_data[end_index:end_index+4])[0] # 10 ``` ### 常见问题解决 - **错误处理**:使用 `try-except` 捕获 `struct.error`。 - **动态格式**:根据数据内容构建格式字符串(如循环解析数组)。 通过struct模块,可高效解析各类二进制数据,适用于网络协议、文件格式处理等场景[^1][^2][^3][^4]。 §§相关问题§§ 1. 如何将Python整数、浮点数等数据打包为bytes? 2. struct模块支持哪些数据类型标识符? 3. 解析网络数据时,如何处理可变长度的字段? 4. Python中还有哪些处理二进制数据的模块或方法? </think> ## Python使用struct模块解析bytes类型不同格式数据的方法 struct模块是Python处理二进制数据的核心工具,用于在二进制数据(bytes)和Python数据类型之间进行转换。以下是详细解析方法: ### 一、基本使用步骤 1. **导入模块** ```python import struct ``` 2. **定义格式字符串(fmt)** - 格式字符串指定数据类型和字节顺序 - 示例:`&#39;<i4sf&#39;` 表示小端序的整数(4B)+4字符字符串+浮点数(4B) 3. **解包操作** ```python data = b&#39;\xe9\x03\x00\x00Lisi\x9a\x99\xd9?&#39; # 示例bytes数据 unpacked = struct.unpack(&#39;<i4sf&#39;, data) # 解包 ``` ### 二、格式字符串详解(引用[1][2][3][4]) #### 1. 字节序控制(首字符) | 符号 | 含义 | 说明 | |------|---------------|--------------------| | `@` | 本机顺序 | 默认值 | | `=` | 本机标准 | 按原始字节序 | | `<` | 小端序(Little) | 最低有效字节在前 | | `>` | 大端序(Big) | 最高有效字节在前 | | `!` | 网络序 | 等同于大端序 | #### 2. 数据类型格式符 | 格式 | C类型 | Python类型 | 字节数 | 示例 | |------|--------------|-------------|--------|--------------| | `x` | 填充字节 | 无 | 1 | 跳过字节 | | `b` | signed char | int | 1 | 有符号字节 | | `B` | unsigned char| int | 1 | 无符号字节 | | `h` | short | int | 2 | 短整数 | | `H` | unsigned short| int | 2 | 无符号短整数 | | `i` | int | int | 4 | 整数 | | `I` | unsigned int | int | 4 | 无符号整数 | | `q` | long long | int | 8 | 长整数 | | `f` | float | float | 4 | 单精度浮点数 | | `d` | double | float | 8 | 双精度浮点数 | | `s` | char[] | bytes | 1+ | 字符串(需长度)| | `c` | char | bytes | 1 | 单个字符 | #### 3. 数字类型前缀 - 格式符前加数字表示数量:`3B` = 3个字节,`2H` = 2个短整数 ### 三、完整解析示例 #### 示例1:基本数据类型解析 ```python import struct # 打包数据(小端序:整数+4字符+浮点数) packed = struct.pack(&#39;<i4sf&#39;, 1001, b&#39;Lisi&#39;, 1.7) print("打包结果:", packed) # b&#39;\xe9\x03\x00\x00Lisi\x9a\x99\xd9?&#39; # 解包数据 id_num, name, height = struct.unpack(&#39;<i4sf&#39;, packed) print(f"ID: {id_num}, Name: {name.decode()}, Height: {height:.2f}") # 输出: ID: 1001, Name: Lisi, Height: 1.70 ``` #### 示例2:处理字节序(引用[4]) ```python # 大端序数据 big_endian_data = b&#39;\x00\x00\x03\xe9&#39; value = struct.unpack(&#39;>I&#39;, big_endian_data)[0] # 解析大端无符号整数 print("大端值:", value) # 1001 # 小端序数据 little_endian_data = b&#39;\xe9\x03\x00\x00&#39; value = struct.unpack(&#39;<I&#39;, little_endian_data)[0] # 解析小端无符号整数 print("小端值:", value) # 1001 ``` #### 示例3解析混合数据类型 ```python # 数据格式:网络序(2字节长度 + 字符串 + 双精度浮点数) data = b&#39;\x00\x05Hello\x3f\xf1\x99\x99\x99\x99\x99\x9a&#39; str_len = struct.unpack(&#39;!H&#39;, data[:2])[0] # 解析长度 string = data[2:2+str_len].decode() # 提取字符串 float_val, = struct.unpack(&#39;!d&#39;, data[2+str_len:]) # 解析浮点数 print(f"字符串: {string}, 浮点数: {float_val}") # 输出: 字符串: Hello, 浮点数: 1.1 ``` ### 四、高级技巧 1. **批量解析**:使用`iter_unpack`处理重复结构 ```python data = b&#39;\x01\x00\x02\x00\x03\x00&#39; # 3个短整数 for val in struct.iter_unpack(&#39;<H&#39;, data): print(val[0]) # 依次输出1, 2, 3 ``` 2. **动态格式字符串** ```python def parse_data(fmt, data): return struct.unpack(fmt, data) # 根据协议版本选择不同格式 result = parse_data(&#39;>I f&#39;, version1_data) if version == 1 else parse_data(&#39;<d&#39;, version2_data) ``` 3. **计算数据大小** ```python fmt = &#39;<i4sf&#39; size = struct.calcsize(fmt) # 计算该格式的字节数 print(f"格式&#39;{fmt}&#39;需要{size}字节") # 输出: 12字节 ``` ### 五、常见错误处理 1. **数据长度不匹配**: ```python try: struct.unpack(&#39;<i&#39;, b&#39;\x01&#39;) # 需要4字节但只有1字节 except struct.error as e: print("错误:", e) # unpack requires a buffer of 4 bytes ``` 2. **处理填充字节**: ```python # 跳过中间填充字节:格式&#39;i x x x f&#39;表示整数后跳过3字节再读浮点数 data = struct.pack(&#39;i3xf&#39;, 10, 3.14) ``` ### 六、使用场景建议 1. 网络协议解析(TCP/UDP数据包) 2. 文件格式处理(二进制文件头解析3. 硬件通信(串口/I2C数据解析) 4. 跨语言数据交换(C/C++与Python通信)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值