長さヘッダープロトコル — 確実な抽出のための32ビットプレフィックス
LSB steganography で隠しデータの先頭に32ビットの長さヘッダーを付与するプロトコルを解説。デコーダーがペイロードの正確な終端を知るための仕組みと実装方法を説明します。
Techniques
詳細な説明
なぜ長さヘッダーが必要か
LSB steganography でメッセージを埋め込むとき、デコーダーは「何ビット分のデータを抽出すればよいか」を知る必要があります。長さヘッダーがなければ、デコーダーは画像全体の LSB を抽出することになり、メッセージの後に続く無関係なビット(元のピクセルの LSB)も含まれてしまいます。
32ビット長さヘッダーの構造
[32ビット: ペイロード長] [ペイロード本体: N ビット]
|← 固定長ヘッダー →|← 可変長データ →|
最初の32ビットは、後続するペイロードのビット数を符号なし整数として格納します。32ビットで表せる最大値は約 4,294,967,295 ビット(約512 MB)であり、実用上のあらゆる画像サイズに対応できます。
エンコード(埋め込み側)
function encodeWithHeader(messageBytes) {
const messageBits = bytesToBits(messageBytes);
const lengthBits = new Array(32);
for (let i = 0; i < 32; i++) {
lengthBits[i] = (messageBits.length >> (31 - i)) & 1;
}
return [...lengthBits, ...messageBits];
}
デコード(抽出側)
function decodeWithHeader(extractedBits) {
let length = 0;
for (let i = 0; i < 32; i++) {
length = (length << 1) | extractedBits[i];
}
const messageBits = extractedBits.slice(32, 32 + length);
return bitsToBytes(messageBits);
}
ヘッダーがない場合の問題
| 方式 | 抽出結果 |
|---|---|
| 長さヘッダーあり | メッセージのみを正確に抽出 |
| 長さヘッダーなし | メッセージ+余分なゴミビットを抽出、終端が不明 |
| 終端マーカー方式 | メッセージ本体に終端マーカーと同じパターンが含まれるリスク |
終端マーカー方式との比較
一部の実装では、長さヘッダーの代わりに特定のバイト列(例: null バイト8連続)を終端として使用します。しかしこの方式では:
- メッセージ本体に同じパターンが含まれると誤って終端と判定される
- バイナリデータを埋め込む場合に null バイトが頻出するため不向き
長さヘッダー方式はこれらの問題を回避し、任意のバイナリデータを正確に扱えます。
オーバーヘッドの影響
32ビット(4バイト)のオーバーヘッドは非常に小さく、640×480 の画像でも全容量の約0.003%にすぎません。このわずかなコストで確実なデータ抽出が保証されます。
ユースケース
独自の steganography ツールやデコーダーを実装する開発者が、このツールと互換性のあるヘッダープロトコルを理解し、正しくペイロードの境界を処理するため。