python unpack
unpack的作用就是把字符串或者byte类型数据按照你的格式转换,比如
import struct
ethernet_header = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd'
(source_mac, destination_mac, ethertype) = struct.unpack(b'!6s6sH', ethernet_header)
print(source_mac)
#b'\x00\x11"3DU'
print(destination_mac)
#b'fw\x88\x99\xaa\xbb'
print(ethertype)
#52445
b'!6s6sH'具体什么意思呢,可以参考官方文档:
| 字符 | 字节序 | 大小 | 对齐方式 |
|---|---|---|---|
| @ | 按原字节 | 按原字节 | 按原字节 |
| = | 按原字节 | 标准 | 无 |
| < | 小端 | 标准 | 无 |
| > | 大端 | 标准 | 无 |
| ! | 网络(大端) | 标准 | 无 |
| 格式 | C类型 | Python类型 | 标准大小 |
|---|---|---|---|
| x | 填充 | 无 | |
| c | char | 长度为1的字节串 | 1 |
| b | signed char | 整数 | 1 |
| B | unsigned char | 整数 | 1 |
| ? | bool | bool | 1 |
| h | short | 整数 | 2 |
| H | unsigned short | 整数 | 2 |
| i | int | 整数 | 4 |
| I | unsigned int | 整数 | 4 |
| l | long | 整数 | 4 |
| L | unsigned long | 整数 | 4 |
| q | long long | 整数 | 8 |
| Q | unsigned long long | 整数 | 8 |
| n | ssize_t | 整数 | |
| N | size_t | 整数 | |
| e | float | 2 | |
| f | float | float | 4 |
| d | double | float | 8 |
| s | char[] | 字节串 | |
| p | char[] | 字节串 |
! - 网络字节序
6s - 6个char
H - unsigned short
在代码中就是读取6个char赋值给source_mac,再读取6个char赋值给destination_mac,再读取一个unsigned short赋值给ethertype
b'!6s6sH'中最前面的b有什么用呢,实际是python2的问题,就是如果后面的要转换的原数据是byte,那么前面必须加上b,不然报错;如果是str,就不用了。在python3中不需要额外增加这个b了,因为会自动判断。
如果数据流中要跳过几个字节怎么操作呢,就用到了x,可以指定跳过几个字节,比如a, b = struct.unpack('4xhh', datastream),就是跳过前面4个字节,然后读取两个short类型数据给a和b

浙公网安备 33010602011771号