php 的pack方法 归纳总结
-- --转载
pack
压缩资料到位字符串之中。
语法: string pack(string format, mixed [args]...);
返回值: 字符串
函数种类: 资料处理
|
内容说明 |
本函数用来将资料压缩打包到位的字符串之中。本函数和 Perl 的同名函数功能用法完全相同。参数 format 为压缩的格式,见下表
a - NUL-padded string
a - NUL- 字符串填满[padded string] 将字符串空白以 NULL 字符填满
A - SPACE-padded stringA - SPACE- 字符串填满[padded string]
h - Hex string, low nibble firsth – 十六进制字符串,低“四位元”[low nibble first] (低位在前)
H - Hex string, high nibble firstH - 十六进制字符串,高“四位元”[high nibble first](高位在前)
c - signed charc – 带有符号的字符
C - unsigned charC – 不带有符号的字符
s - signed short (always 16 bit, machine byte order)s – 带有符号的短模式[short](通常是16位,按机器字节顺序)
S - unsigned short (always 16 bit, machine byte order)S – 不带有符号的短模式[short](通常是16位,按机器字节排序)
n - unsigned short (always 16 bit, big endian byte order)n -不带有符号的短模式[short](通常是16位,按大endian字节排序)
v - unsigned short (always 16 bit, little endian byte order)v -不带有符号的短模式[short](通常是16位,按小endian字节排序)
i - signed integer (machine dependent size and byte order)i – 带有符号的整数(由大小和字节顺序决定)
I - unsigned integer (machine dependent size and byte order)I – 不带有符号的整数(由大小和字节顺序决定)
l - signed long (always 32 bit, machine byte order)l– 带有符号的长模式[long](通常是32位,按机器字节顺序)
L - unsigned long (always 32 bit, machine byte order)L – 不带有符号的长模式[long](通常是32位,按机器字节顺序)
N - unsigned long (always 32 bit, big endian byte order)N – 不带有符号的长模式[long](通常是32位,按大edian字节顺序)
V - unsigned long (always 32 bit, little endian byte order)V– 不带有符号的长模式[long](通常是32位,按小edian字节顺序)
f - float (machine dependent size and representation)f –浮点(由大小和字节顺序决定)
d - double (machine dependent size and representation)d – 双精度(由大小和字节顺序决定)
x - NUL bytex – 空字节[NUL byte]
X - Back up on
X- 后面一个字节[Back up on
@ - NUL- 添加到一个绝对位置[absolute position](
<?php例子 1
echo pack("C3",80,72,80);
?>
输出:
PHP
例子 2
<?php
echo pack("C*",80,72,80);
?>
输出:
PHP
================================
unpack
解压缩位字符串资料。
语法: string pack(string format, mixed [args]...);
返回值: 数组
函数种类: 资料处理
内容说明 |
本函数用来将位的字符串的资料解压缩。本函数和 Perl 的同名函数功能用法完全相同。参数 format 为压缩的格式,参见 pack 的格式表。
例子 1
<?php
$da
print_r(unpack("C*",$da
?>
输出:
Array
(
[1] => 80
[2] => 72
[3] => 80
)
例子 2
<?php
$da
print_r(unpack("C*myint",$da
?>
输出:
Array
(
[myint1] => 80
[myint2] => 72
[myint3] => 80
)
例子 3
<?php
$bin = pack("c2n2",0x1234,0x5678,65,66);
print_r(unpack("c2chars/n2int",$bin));
?>
输出:
Array
(
[chars1] => 52
[chars2] => 120
[int1] => 65
[int2] => 66
)
这几天要做双向的加解密,因为加密后的结果都是二进制的,不得不了解一下它了
小 try了一把pack/unpack,基本用法还是蛮简单的,下面的例子基本上是给了个做数据库的原型(嘻嘻,不能用PHP5了,只好用PHP4的语法 写)
<?php
/**
* 这是一个测试pack/unpack操作的东西
* @author 张心灵
* Email: zhangsilly@gmail.com
*
* 一下文件存储如下几个字段
* 姓名: 长度 8 字节
* 年龄: unsigned int
* Email: 长度 30 字节
*/
class Person_Data
{
/**
* 数据库文件路径
* @var string
*/
var $_database = './wps.db';
/**
* 打开一个数据库文件
* @param string $file 数据库文件名
*/
function openDb($file = './wps.db')
{
$this->_database = $file;
$this->_database = fopen($this->_database, 'ab+');
}
/**
* 向数据库中写入一条记录
* @param array $data PHP4真的丑死了
* @return void
*/
function writeRecord($data)
{
$name = pack('a8', $data['name']);
$age = pack('S', $data['age']);
$email = pack('a30', $data['email']);
fwrite($this->_database, $name . $age . $email);
}
/**
* 读取一条记录
* @param int $count optional default to 0 记录id数
* @return array
*/
function read($count = 0)
{
rewind($this->_database);
fseek($this->_database, 40 * $count);
$return = array();
$return['name'] = unpack('a8', fread($this->_database, 8));
$return['name'] = $return['name'][1];
$return['age'] = unpack('S', fread($this->_database, 2));
$return['age'] = $return['age'][1];
$return['email'] = unpack('a30', fread($this->_database, 30));
$return['email'] = $return['email'][1];
return $return;
}
}
$me = array( 'name' => '张心灵',
'age' => 23,
'email' => 'zhangsilly@gmail.com');
$data = new Person_Data();
$data->openDb('./wps.db');
//$data->writeRecord($me);
print_r($data->read(1));
以 上文件运行了两侧,写入了两行记录,最后我读取第二行记录(索引自然从 1 开始)
运行一切正常:
Array
(
[name] => 张心灵
[age] => 23
[email] => zhangsilly@gmail.com
)
翻 译:
pack()函数的作用是:将数据压缩成一个二进制字符串。
================================
用了很久php了却很少有机会用php进行一些二进制操作。 最近用php写一个socket客户端连接一个用C++语言开发的游戏服务端。 服务器端开发人员使用了二进制的形式来定义协议的格式。协议格式如下:
包头(2bytes)+加密(1byte)+命令码(2bytes)+帧内容
1.包头的内容是记录帧内容的长度;
2. 加密:0表示不加密,1表示加密;
3. 命令码为服务端命令识别符号;
一开始不了解php原来有pack可以来组装二进制包, 走了弯路,让服务端开发人员用C语言帮忙开发了的几个内存操作函数,按照协议规则返回二进制包,然后我将这几个方法编译成一组扩展函数供php使用。
string pack ( string $format [, mixed $args [, mixed $...]] )
一些规则:
1.每个字母后面都可以跟着一个数 字,表示 count(计数),如果 count 是一个 * 表示剩下的所有东西。
2.如果你提供的参数比 $format 要求的少,pack 假设缺的都是空值。如果你提供的参数比 $format 要求的多,那么多余的参数被忽略。
下面还是用例子来说明用法会容易理解一点:
关于Pack:
下面的第一部分把数字值包装成字节:
$out = pack("CCCC", 65, 66, 67, 68); # $out 等于"ABCD"
$out = pack("C4", 65, 66, 67, 68); # 一样的东西
下面的对 Unicode 的循环字母做同样的事情:
$foo = pack("U4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);
下面的做类似的事情,增 加了一些空:
$out = pack("CCxxCC", 65, 66, 67, 68); # $out 等于 "AB\0\0CD"
打包你的短整数并不意味着你就可移植了:
$out = pack("s2", 1, 2);
# 在小头在前的机器上是 "\1\0\2\0"
# 在大头在前的机器上是 "\0\1\0\2"
在二进制和十六进制包装上,count 指的是位或者半字节的数量,而不是生成的字节数量:
$out = pack("B32", "...");
$out = pack("H8", "5065726c"); # 都生成“Perl”
a 域里的长度只应用于一个字串:
$out = pack("a4", "abcd", "x", "y", "z"); # "abcd"
要绕开这个限制,使用多倍声明:
$out = pack("aaaa", "abcd", "x", "y", "z"); # "axyz"
$out = pack("a" x 4, "abcd", "x", "y", "z"); # "axyz"
a 格式做空填充:
$out = pack("a14", "abcdefg"); # " abcdefg\0\0\0\0\0\0"
关于unpack:
array unpack ( string $format, string $da
$da
unpack("Sint1/Cchar1/Sint2/Cchar2",$da
## array('int1'=>1, 'char1'=>'0','int2'=>2,'char2'=>7);
最后本文开头讲到的协议使用pack/unpack 举例程序代码为 :
$lastact = pack('SCSa32a32',0x0040, 0x00, 0x0006, $username, $passwd );
unpack('Sint1/Cchar1/Sint2/Cchar2 /',$lastmessage);
标签: php pack php unpack pack unpack
-
链接
-
搜索
热门日志
分类
- Django(4)
- ssdb(1)
- Mac(7)
- C(1)
- memcache(1)
- Python(32)
- Vim(8)
- sed(2)
- ansible(3)
- awk(4)
- shell(3)
- about(1)
- git(9)
- bat(4)
- svn(0)
- docker(1)
- Tornado(1)
- go(2)
- 架构(18)
- Vue(1)
- game(2)
- Html(6)
- Java(8)
- Mysql(37)
- Ajax(2)
- Jsp(1)
- Struts(8)
- Linux(72)
- JavaScript(39)
- Staruml(0)
- Mouth(1)
- Php(102)
- Windows(8)
- Message(48)
- Lua(10)
- Compute(1)
- Redis(7)
- Nginx(12)
- Jquery(1)
- Apache(1)
- cocos2d-x(8)