現在の位置: ホーム> 最新記事一覧> unpack()とpack()を組み合わせてカスタムデータ構造分析を実装する

unpack()とpack()を組み合わせてカスタムデータ構造分析を実装する

M66 2025-05-27

PHPでは、バイナリデータを処理する場合、 pack()unpack()関数は2つの非常に実用的なツールです。データを特定の形式でバイナリ文字列に変換するか、バイナリ文字列を構造化されたデータに解析できます。これは、カスタムデータ構造のシリアル化と降下を実装したり、基礎となるプロトコルやファイル形式との対話をするために非常に重要です。

この記事では、Pack()unpack()関数を組み合わせて、カスタムデータ構造の解析と変換を実装する方法について詳しく説明します。


1。パック()およびunpack()関数の基本紹介

  • pack(format、args ...)フォーマット文字列に従ってパラメーターargsをバイナリ文字列にパッケージ化します。

  • [フォーマット、データ] :[形式]文字列に従ってバイナリ文字列データを連想配列に解除します。

フォーマット文字列は、データ型、長さ、およびエンディアン性を定義するフォーマットコードで構成されています。例えば:

  • C :署名されていない文字(1バイト)

  • N :署名されていない16ビットのビッグエンディアンエンディアンエンディアン整数

  • V :署名されていない32ビットリトルエンディアンエンディアンエンディアン整数

  • A :nul塗りつぶされた文字列

  • A :スペースが充填された文字列

その他のフォーマットコードについては、公式のPHPドキュメントを参照してください。


2。カスタムデータ構造の例を定義します

単純なデータ構造を次のように定義しているとします。

フィールド名タイプ長さ(バイト)説明します
タイプuint8 1データ型識別
長さUINT16 2後続のデータ長
ペイロードバイトストリーム長さ特定のデータコンテンツ

私たちの目標は次のとおりです。

  • PHPデータ構造を上記の形式を満たすバイナリデータにパッケージ化します。

  • バイナリデータは解析され、タイプ、長さ、ペイロードフィールドが抽出されます。


3。Pack()を使用してデータをパッケージ化します

<?php
function packData(int $type, string $payload): string {
    $length = strlen($payload);

    // 'C' - 1バイト符号なし整数
    // 'n' - 2バイト署名されていないビッグエンディアン整数
    // 'a*' - 任意の長さの文字列,NUL充填(这里不需要充填)
    return pack('Cn', $type, $length) . $payload;
}

// テスト
$type = 5;
$payload = "Hello, World!";
$binaryData = packData($type, $payload);
echo bin2hex($binaryData);
?>

ここでは、Pack( 'cn'、$ type、$ length)は、最初にタイプ長さを個別にパックし、次に元の文字列$ペイロードをスプライスします。


4. unpack()を使用してデータを解析します

解析中に、最初に固定長い部分のタイプ長さを取り出し、長さに応じて残りのペイロードを傍受します。

 <?php
function unpackData(string $binaryData): array {
    // 先解包前3バイト,type(1バイト) + length(2バイト大端)
    $header = unpack('Ctype/nlength', substr($binaryData, 0, 3));

    $type = $header['type'];
    $length = $header['length'];

    // 残りを取り出しますpayloadデータ
    $payload = substr($binaryData, 3, $length);

    return [
        'type' => $type,
        'length' => $length,
        'payload' => $payload,
    ];
}

// テスト
$data = $binaryData; // 上から仮定しますpackData出力
$result = unpackData($data);
var_dump($result);
?>

5.完全な例と説明

上記の2つの関数を統合して、カスタム構造のシリアル化と敏aserializationを実装します。

 <?php

function packData(int $type, string $payload): string {
    $length = strlen($payload);
    return pack('Cn', $type, $length) . $payload;
}

function unpackData(string $binaryData): array {
    $header = unpack('Ctype/nlength', substr($binaryData, 0, 3));
    $type = $header['type'];
    $length = $header['length'];
    $payload = substr($binaryData, 3, $length);
    return [
        'type' => $type,
        'length' => $length,
        'payload' => $payload,
    ];
}

// 使用の例
$type = 10;
$payload = "PHP pack/unpack デモ";

$packed = packData($type, $payload);
echo "二进制データ(hex):" . bin2hex($packed) . "\n";

$unpacked = unpackData($packed);
echo "分析結果:\n";
print_r($unpacked);

?>

実行結果:

 二进制データ(hex):0a0017... (hexエンコードされたバイナリコンテンツ)
分析結果:
Array
(
    [type] => 10
    [length] => 23
    [payload] => PHP pack/unpack デモ
)

6。概要

  • pack()およびunpack()は、バイナリデータを処理するための強力なツールであり、複数のデータ型とエンディアン変換をサポートしています。

  • カスタムデータ構造を解析するには、最初に固定ヘッダー形式を定義し、次に文字列操作を使用して可変長フィールドを処理できます。

  • バイナリ処理と組み合わせることで、PHPはネットワークプロトコル、ファイル形式の解析、その他のシナリオを簡単に扱うこともできます。