python3中的pack into_Python中struct.pack()和struct.unpack()用法详解|python3教程|python入门|python教程...

https://www.xin3721.com/eschool/python.html

python中的struct主要是用来处理C结构数据的,读入时先转换为Python的字符串类型,然后再转换为Python的结构化类型,比如元组(tuple)啥的~。一般输入的渠道来源于文件或者网络的二进制流。

1.struct.pack()和struct.unpack()

在转化过程中,主要用到了一个格式化字符串(format strings),用来规定转化的方法和格式。

下面来谈谈主要的方法:

1.1 struct.pack(fmt,v1,v2,.....)

将v1,v2等参数的值进行一层包装,包装的方法由fmt指定。被包装的参数必须严格符合fmt。最后返回一个包装后的字符串。

1.2 struct.unpack(fmt,string)

顾名思义,解包。比如pack打包,然后就可以用unpack解包了。返回一个由解包数据(string)得到的一个元组(tuple), 即使仅有一个数据也会被解包成元组。其中len(string) 必须等于 calcsize(fmt),这里面涉及到了一个calcsize函数。struct.calcsize(fmt):这个就是用来计算fmt格式所描述的结构的大小。

格式字符串(format string)由一个或多个格式字符(format characters)组成,对于这些格式字符的描述参照Python manual如下:

Format

c Type

Python

Note

x

pad byte

no value

c

char

string of length 1

b

signedchar

integer

B

unsignedchar

integer

?

_Bool

bool

(1)

h

short

integer

H

unsignedshort

integer

i

int

integer

I

unsignedint

integer or long

l

long

integer

L

unsignedlong

long

q

longlong

long

(2)

Q

unsignedlonglong

long

(2)

f

float

float

d

double

float

s

char[]

string

p

char[]

string

P

void*

long

2.代码示例

首先将参数1,2,3打包,打包前1,2,3明显属于python数据类型中的integer,pack后就变成了C结构的二进制串,转成 python的string类型来显示就是  '\x01\x00\x00\x00\x02\x00\x03'。由于本机是小端('little- endian',关于大端和小端的区别请参照这里, 故而高位放在低地址段。i 代表C struct中的int类型,故而本机占4位,1则表示为01000000;h 代表C struct中的short类型,占2位,故表示为0200;同理b 代表C struct中的signed char类型,占1位,故而表示为03。

其他结构的转换也类似,有些特别的可以参考官方文档的Manual。

在Format string 的首位,有一个可选字符来决定大端和小端,列表如下:

@

native

native

=

native

standard

<

little-endian

standard

>

big-endian

standard

!

network (= big-endian)

standard

如果没有附加,默认为@,即使用本机的字符顺序(大端or小端),对于C结构的大小和内存中的对齐方式也是与本机相一致的(native),比如有的机器integer为2位而有的机器则为四位;有的机器内存对其位四位对齐,有的则是n位对齐(n未知,我也不知道多少)。

还有一个标准的选项,被描述为:如果使用标准的,则任何类型都无内存对齐。

比如刚才的小程序的后半部分,使用的format string中首位为!,即为大端模式标准对齐方式,故而输出的为'\x00\x00\x00\x01\x00\x02\x03',其中高位自己就被放在内存的高地址位了。

在 Java ,你可以使用 ByteBuffer 类来实现类似于 Python struct 模块pack 和 unpack 方法的功能。以下是一个示例代码: ```javaimport java.nio.ByteBuffer; import java.nio.ByteOrder; public class StructExample { public static void main(String[] args) { // 将 int 值打包为字节序列 int intValue =12345; byte[] packedBytes = packInt(intValue); System.out.println("Packed bytes: " + bytesToHex(packedBytes)); // 将字节序列解包为 int 值 int unpackedInt = unpackInt(packedBytes); System.out.println("Unpacked int: " + unpackedInt); } private static byte[] packInt(int value) { ByteBuffer buffer = ByteBuffer.allocate(4); buffer.order(ByteOrder.LITTLE_ENDIAN); // 设置字节序为小端序列(与Pythonstruct默认相同) buffer.putInt(value); return buffer.array(); } private static int unpackInt(byte[] bytes) { ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.order(ByteOrder.LITTLE_ENDIAN); // 设置字节序为小端序列 return buffer.getInt(); } private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b)); } return sb.toString(); } } ``` 上述代码演示了 Java 如何实现类似于 Pythonstruct 模块pack 和 unpack 方法。`packInt` 方法将一个 int 值打包为字节序列,`unpackInt` 方法将字节序列解包为一个 int 值。在这个示例,我们使用了 ByteBuffer 类来处理字节操作,并通过设置字节序为小端序列来与 Pythonstruct 默认行为保持一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值