分类:
2009-11-06 15:00:41
pack TEMPLATE,LIST
把LIST里面的值看成是TEMPLATE指定的格式,然后转换为字节序(即内存保存的形式).
unpack TEMPLATE,EXPR
把EXPR 转换为TEMPLATE指定的格式.
通过pack 转换后的值将模拟一块内存, 保存转换后的字节序;而unoack 通过TEMPLATE指定的格式分块取出字节序,转换为指定的格式.
TEMPLATE大致分为两种.整数型和字符型.在处理时有一些差别.
整数格式
Format Description
c,C A signed/unsigned char (8-bit integer) value
s,S A signed/unsigned short, always 16 bits
l,L A signed/unsigned long, always 32 bits
q,Q A signed/unsigned quad (64-bit integer) value
i,I A signed/unsigned integer, native format
n,N A 16/32 bit value in "network" (big-endian) order
v,V A 16/32 bit value in "VAX" (little-endian) order
U A Unicode character number. Encodes to a character in character mode and UTF-8 (or UTF-EBCDIC in EBCDIC platforms) in byte mode.
因为整数型规定了字节长度,所以后面接的数字表示需要格式化列表中的几个元素.*表示全部.
$foo = pack("s2",1,2);
"\1\0\2\0" on little-endian
"\0\1\0\2" on big-endian
字符格式
Format Description
a,A A null/space padded string
b,B A bit (binary) string in ascending/descending bit order
h,H A hexadecimal string, low/high nybble first
Z A null terminated string
因为字符型没有规定字符长度,所以后面接的数字表示每个元素接收的字符数,只是对一个元素而言.
ord(pack('b8','00100110')) produces 100 (4 + 32 + 64)
ord(pack('B8','00100110')) produces 38 (32 + 4 + 2)
pack('h4','1234') produces 0x21,0x43
pack('H4','1234') produces 0x12,0x34
pack('a8',"hello") produces "hello\0\0\0"
pack('Z8',"hello") produces "hello\0\0\0"
pack('A8',"hello") produces "hello "
unpack('a8',"hello\0\0\0") produces "hello\0\0\0"
unpack('Z8',"hello\0\0\0") produces "hello"
unpack('A8',"hello ") produces "hello"
unpack('A8',"hello\0\0\0") produces "hello"
特殊格式
x A null byte.
X Back up a byte.
@ Null fill or truncate to absolute position, counted from the start of the innermost ()-group.
. Null fill or truncate to absolute position specified by value.
( Start of a ()-group.
/
Unicode
pack和unpack有2种模式:字符模式(C0) ,UTF8模式(U0)
默认为C0模式,如果格式开始为U,则为U0模式.
我的理解.转换出的格式,U0的utf8 flag为 on,而C0的utf-8 flag 为off.
print encode( "cp936", pack( "U", 0x53cd ) )
print encode( "cp936", decode("utf-8", pack( "C0U", 0x53cd ) ) )
上面的例子都打印汉字”反”.
U默认为U0模式,直接转换为String,而C0模式转换为了Octets,所以需要decode函数转换为String.
附:
字符串与数字的转换
十进制的数字可以在数字和字符串之间自动转换.带0前缀的十六进制和八进制字符串不能自动转换为相应的数字.必须通过函数来转换.数字转换为字符串将先把数字转换为十进制,然后把十进制数字转换为字符.
hex 把字符串看成十六进制并返回相应的十进制数字
可省略0x前缀, 参数为字符串
oct 把字符串看成相应前缀的进制转换为十进制数字.
默认为八进制,可省略0前缀,可选 0x,0b 参数为字符串
chr 返回数字所代表的字符.
参数为数字
ord 返回字符串第一个字符的数字形式
参数为字符串
hex “0x10” hex 0x10 区别
因为hex把参数看成字符串, 0x10为16,然后把16看成十六进制字符串转换为十进制数字 22.
chr(“0x48”) 和 chr(0x48) 区别
因为 chr 把参数看成数字,所以”0x48”转换为数字为0,所以 chr(“0x48”) ==chr(0);
对于后面接字符串参数的函数(hex,oct,ord),如果参数为数字,先转换为十进制数字,然后在把数字转换为字符串,最后才传递给函数来处理.
对于后面接数字参数的函数(chr),如果参数为字符串,就要转换为十进制数字,然后在传递给函数处理.