Pack()関数は、指定された形式の文字列とデータをバイナリ文字列にパッケージ化します。たとえば、 Pack( "C"、65)は、 ASCIIコード65(つまり、文字 "A")を持つ単一の文字を含むバイナリ文字列を返します。フォーマット文字列は、データのレイアウトを説明するために使用されます。一般的なフォーマットコードは次のとおりです。
C :署名されていない文字(8ビット、範囲0〜255)
N :署名されていない短い整数(16ビット、ビッグエンディアンエンディアン)
N :署名されていない長い整数(32ビット、ビッグエンディアンエンディアン)
H* :16進に関する文字列(高いビット優先度)
例えば:
$bin = pack("C*", 72, 101, 108, 108, 111); // 対応する文字 "Hello"
echo $bin; // 出力 Hello
このプロセスは、整数の配列を圧縮バイナリ文字列に変換するようなものです。
Pack()とは対照的に、 ord()は、文字を対応するASCIIまたはUnicode値に変換するために使用されます。これはPack()の「デコーダー」であり、バイナリ文字列からデータを抽出するときに非常に便利です。
例えば:
$char = "A";
$ascii = ord($char); // 戻る 65
この関数は、エンコードされた文字列から元のデータバイトバイトを復元するためにPack()と協力するのに非常に適しています。
データをバイナリにエンコードするときにpack()を使用し、バイナリから抽出するときにord()を使用します。これは、両者の相補的な関係を構成します。たとえば、最初に一連の数値をパッケージ化してから、バイトバイトを解析できます。
$data = [77, 54, 54];
$bin = pack("C*", ...$data);
// 各バイトを読んでください
for ($i = 0; $i < strlen($bin); $i++) {
echo ord($bin[$i]) . "\n"; // 出力 77, 54, 54
}
このコードでは、 pack()を使用して配列[77、54、54]を3バイトのバイナリ文字列に変換し、 ord()はバイトで元の数値に復元します。
この手法は、特定のプロトコルのバイナリメッセージを構築するときに特に役立ちます。たとえば、次のような短いリンク要求パッケージを作成します。
$url_id = 1234;
$payload = pack("N", $url_id);
file_put_contents("http://m66.net/api/store", $payload);
サーバーがこの4バイトデータを受信した後、次のように解析できます。
$data = file_get_contents("php://input");
$url_id = unpack("N", $data)[1];
ここでは、pack( "n"、$ url_id)およびuppack( "n"、$ data)は、まさに補完的な操作のペアです。
たとえば、ある種の軽量暗号化またはカスタム送信プロトコルを実装する場合、テキスト情報を数値バイトに変換し、バイナリにカプセル化する前にオフセット処理を実行する必要がある場合があります。
$text = "Hi!";
$encrypted = "";
for ($i = 0; $i < strlen($text); $i++) {
$encrypted .= pack("C", ord($text[$i]) + 1);
}
// 復号化
$decrypted = "";
for ($i = 0; $i < strlen($encrypted); $i++) {
$decrypted .= chr(ord($encrypted[$i]) - 1);
}
echo $decrypted; // 出力 Hi!
この例では、ord()は文字を数字に変え、 pack()をバイナリに包み、decryptionはord()で復元され、その後オフセットが復元されます。