PHP には、pack と unpack という 2 つの関数がありますが、多くの PHPer は実際のプロジェクトでこれらを使用したことがなく、これら 2 つのメソッドが何に使用されるのかさえ知りません。この記事では、それらが何に使われるのかを紹介します。
pack
string pack ( string $format [, mixed $args [, mixed $... ]] )
この関数は、対応するパラメータ ($args) をバイナリ文字列にパックするために使用されます。
最初のパラメータ $format には次のオプションがあります (オプションのパラメータは多数ありますが、一般的なパラメータをいくつか選択して後で説明します):
非常に多くのパラメータを確認した後、初めて非常に混乱しました。ほとんどの命令は理解するのは簡単ですが、ホスト、ビッグ エンディアン、リトル エンディアンのバイト オーダーは何ですか? 、など?以下の内容は比較的退屈ですが、理解する必要があるので、最後まで読んでください。
バイトオーダーとは何ですか?
はバイトの順序であり、端的に言えば、マルチバイト データが格納される順序です (1 バイトには順序は必要ありません)。
たとえば、A と B の対応するバイナリ表現は、それぞれ 0100 0001 と 0100 0010 です。文字列 AB を格納するには、0100 0001 0100 0010 または 0100 0010 0100 0001 を使用できます。この順序は、いわゆるバイト オーダーです。
上位/下位バイト
たとえば、文字列 AB、左が上位、右が下です (通常の読み取り順序) , Aが上位ワード部、Bが下位バイト
上位/下位アドレス
上位から順に0x123456が格納されているとします
高アドレス->低アドレス
12 -> 34 -> 56
ビッグ エンディアン バイト オーダー (ネットワーク バイト オーダー)
ビッグ エンディアンとは、上位バイトをメモリの下位アドレス端に配置し、下位バイトを上位アドレス端に配置することを意味します。ネットワーク伝送(TCP/IPなど)では、ストリームの先頭にアドレスの下位(上位バイト)が配置され、2バイト列(AB)の場合、A(0~7ビット)、 B (8-15ビット)。
したがって、リトルエンディアンのバイト順序は当然ビッグエンディアンの逆になります。
ホスト バイト オーダー
その年のマシンのバイト オーダーを示します (つまり、ネットワーク バイト オーダーが決定され、ホストバイトオーダー 順序はマシンによって決定されます)、通常はリトルエンディアンです。
a および A (NUL またはスペースで埋められたパックされた文字列)
$string = pack('a6', 'china’); var_dump($string); //输出结果: string(6) "china",最后一个字节是不可见的NUL echo ord($string[5]); //输出结果: 0(ASCII码中0对应的就是nul) //A同理 $string = pack('A6', 'china’); var_dump($string); //输出结果: string(6) "china ",最后一个字节是空格 echo ord($string[5]); //输出结果: 32(ASCII码中32对应的就是空格)
[画像のアップロードに失敗しました...(image-5d8a61 - 1577941896554)]
ASCII テーブルが付属しています (man ascii を使用して Linux/unix で表示できます)
h および H
$string = pack('H3', 281); var_dump($string); //输出结果: string(2) “(“ for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出结果: 40 16
h と H は特別な説明が必要ですが、対応するパラメータを 16 進文字として扱い、パッケージ化します。それはどういう意味ですか?たとえば、上記の 281 は、1 つの 16 進数が 4 つの 2 進数に対応するため、パッケージ化する前に 0x281 に変換されます。上記の 0x281 はわずか 1.5 バイトであり、デフォルトで 0 が追加されて 0x2810 になり、10 進数は 0x28 に対応します。は 40(()、0x10 に対応する 10 進数は 16 (非表示文字) です。
c および C
$string = pack('c3', 67, 68, -1); var_dump($string); //输出:string(3) “CD�” for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 67 68 225
最終出力は次のようになります。 be I think 67 68 -1
ordは文字のASCIIコード(範囲0~255)を取得します この時、-1(0000 0001)に相当する文字が補数形式で出力されますこれは 255 (1111 1110 0000 0001 = 1111 1111)
整数関連
すべての整数型は、主にまったく同じ方法で使用されます。ビット合計に注意してください。エンディアンネスは十分です。L は以下の例として使用されます:
$string = pack('L', 123456789); var_dump($string); //输出:string(4) “�[“ for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 21 205 91 7
f および d
$string = pack('f', 12345.123); var_dump($string); //输出:string(4) "~�@F” var_dump(unpack('f', $string)); //这里提前用到了unpack,后面会讲解 //输出:float(12345.123046875)
f および d は次のとおりです。浮動小数点パッケージ化の場合、パッケージ化前が 12345.123 で、解凍後は 12345.123046875 である理由については、これは浮動小数点数の格納に関係しています。
$string = pack('x'); //打包一个nul字符串
echo ord($string); //输出: 0
$string = pack('Z2', 'abc5'); //其实就是将从Z后面的数字位置开始,全部设置为nul var_dump($string); //输出:string(2) “a” for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 97 0
$string = pack('@4'); //我理解为填充N个nul var_dump($string); //输出: string(4) “” for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 0 0 0 0
これら 2 つの関数の用途
データ通信(バイナリ形式で他言語と通信)
·データ暗号化(梱包方法を第三者に伝えなければ、相手が開梱することは比較的困難です。) ·スペースの節約 (たとえば、比較的大きな数値を文字列として保存すると多くのスペースが無駄になりますが、32 桁未満のバイナリ形式にパッケージ化するのに必要なのは 4 桁だけです) >) PHP 中国語 Web サイトには、多数の無料の PHP 入門チュートリアル があり、誰でも学習することができます。 この記事はhttps://www.jianshu.com/p/942907071a4c
以上がPHPのpack関数とunpack関数の使い方を詳しく解説します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。