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