Chinaunix首页 | 论坛 | 博客
  • 博客访问: 477733
  • 博文数量: 104
  • 博客积分: 3455
  • 博客等级: 中校
  • 技术积分: 1216
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-18 18:33
文章分类

全部博文(104)

文章存档

2015年(3)

2014年(1)

2013年(7)

2012年(8)

2011年(11)

2010年(18)

2009年(56)

我的朋友

分类:

2009-11-06 15:00:41

大部分语言能够直接操作内存,比如C语言,能够通过内存的地址和大小,任意的修改值,在Perl,你不能任意的操作内存,但pack/unpack函数,其给你提供了一个好的选择.

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

packunpack2种模式:字符模式(C0) ,UTF8模式(U0)

默认为C0模式,如果格式开始为U,则为U0模式.

我的理解.转换出的格式,U0utf8 flag on,C0utf-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把参数看成字符串, 0x1016,然后把16看成十六进制字符串转换为十进制数字 22.


chr(“0x48”) chr(0x48) 区别

因为 chr 把参数看成数字,所以”0x48”转换为数字为0,所以 chr(“0x48”) ==chr(0);

 

对于后面接字符串参数的函数(hex,oct,ord),如果参数为数字,先转换为十进制数字,然后在把数字转换为字符串,最后才传递给函数来处理.

对于后面接数字参数的函数(chr),如果参数为字符串,就要转换为十进制数字,然后在传递给函数处理.

 



比较零乱,慢慢整理修改了


参考 perlpacktut,perldoc pack hex oct chr ord

阅读(2410) | 评论(1) | 转发(0) |
0

上一篇:伪终端

下一篇:正则字符串处理

给主人留下些什么吧!~~

chinaunix网友2010-12-27 08:20:44

比较零乱