pack
壓縮資料到位字符串之中。
語法: string pack(string format, mixed [args]...);
返回值: 字符串
函數種類: 資料處理
本函數用來將資料壓縮打包到位的字符串之中。本函數和 Perl 的同名函數功能用法完全相同。參數 format 爲壓縮的格式,見下表
例子 1
<?php
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
$data = "PHP";
print_r(unpack("C*",$data));
?>
輸出:
Array
(
[1] => 80
[2] => 72
[3] => 80
)
例子 2
<?php
$data = "PHP";
print_r(unpack("C*myint",$data));
?>
輸出:
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
)
玩了玩 PHP 的 pack/unpack !還是蠻簡單的
2007-07-04 16:34
這幾天要做雙向的加解密,因爲加密後的結果都是二進制的,不得不瞭解一下它了
小try了一把pack/unpack,基本用法還是蠻簡單的,下面的例子基本上是給了個做數據庫的原型(嘻嘻,不能用PHP5了,只好用PHP4的語法寫)
<?php
/**
* 這是一個測試pack/unpack操作的東西
* @author 張心靈
* Email: [email protected]
*
* 一下文件存儲如下幾個字段
* 姓名: 長度 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' => '[email protected]');
$data = new Person_Data();
$data->openDb('./wps.db');
//$data->writeRecord($me);
print_r($data->read(1));
以上文件運行了兩側,寫入了兩行記錄,最後我讀取第二行記錄(索引自然從 1 開始)
運行一切正常:
Array
(
[name] => 張心靈
[age] => 23
[email] => [email protected]
)
雙就一個字!
翻譯:
pack()函數的作用是:將數據壓縮成一個二進制字符串。
a - NUL-padded string
a - NUL- 字符串填滿[padded string]
A - SPACE-padded string
A - SPACE- 字符串填滿[padded string]
h - Hex string, low nibble first
h – 十六進制字符串,低“四位元”[low nibble first]
H - Hex string, high nibble first
H - 十六進制字符串,高“四位元”[high nibble first]
c - signed char
c – 帶有符號的字符
C - unsigned char
C – 不帶有符號的字符
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 byte
x – 空字節[NUL byte]
X - Back up one byte
X- 後面一個字節[Back up one byte]
@ - NUL-fill to absolute position
@ - NUL- 添加到一個絕對位置[absolute position]
php裏的pack及unpack--轉
2009-03-15 22:11
用了很久php了卻很少有機會用php進行一些二進制操作。 最近用php寫一個socket客戶端連接一個用C++語言開發的遊戲服務端。 服務器端開發人員使用了二進制的形式來定義協議的格式。協議格式如下:
包頭(2bytes)+加密(1byte)+命令碼(2bytes)+幀內容
1.包頭的內容是記錄幀內容的長度;
2. 加密:0表示不加密,1表示加密;
3. 命令碼爲服務端命令識別符號;
一開始不瞭解php原來有pack可以來組裝二進制包, 走了彎路,讓服務端開發人員用C語言幫忙開發了的幾個內存操作函數,按照協議規則返回二進制包,然後我將這幾個方法編譯成一組擴展函數供php使用。
話歸正題,本文是介紹如何使用pack和unpack這兩個方法的。php官方手冊舉例太少,不能很容易理解,特別是那些格式化參數的使用。
轉摘的參數中文說明:
pack/unpack 的摸板字符字符 含義
a 一個填充空的字節串
A 一個填充空格的字節串
b 一個位串,在每個字節裏位的順序都是升序
B 一個位串,在每個字節裏位的順序都是降序
c 一個有符號 char(8位整數)值
C 一個無符號 char(8位整數)值;關於 Unicode 參閱 U
d 本機格式的雙精度浮點數
f 本機格式的單精度浮點數
h 一個十六進制串,低四位在前
H 一個十六進制串,高四位在前
i 一個有符號整數值,本機格式
I 一個無符號整數值,本機格式
l 一個有符號長整形,總是 32 位
L 一個無符號長整形,總是 32 位
n 一個 16位短整形,“網絡”字節序(大頭在前)
N 一個 32 位短整形,“網絡”字節序(大頭在前)
p 一個指向空結尾的字串的指針
P 一個指向定長字串的指針
q 一個有符號四倍(64位整數)值
Q 一個無符號四倍(64位整數)值
s 一個有符號短整數值,總是 16 位
S 一個無符號短整數值,總是 16 位,字節序跟機器芯片有關
u 一個無編碼的字串
U 一個 Unicode 字符數字
v 一個“VAX”字節序(小頭在前)的 16 位短整數
V 一個“VAX”字節序(小頭在前)的 32 位短整數
w 一個 BER 壓縮的整數
x 一個空字節(向前忽略一個字節)
X 備份一個字節
Z 一個空結束的(和空填充的)字節串
@ 用空字節填充絕對位置
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 $data )
$data = "010000020007";
unpack("Sint1/Cchar1/Sint2/Cchar2",$data);
## 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);
來自: http://hi.baidu.com/sgooo/blog/item/a6e73cf0b689a5a6a50f52ed.html