'\ x00'バイトを含むバイナリストリームの編集


8

シェルツールだけを使用して、出力ストリームに0x00文字を保持しながら、NULL(0x00文字)を含むバイナリストリームをどのように編集できますか?

編集では、次のように、指定された位置の文字を別の文字(次の例では文字 '|')に置き換える必要があります。

dd ibs=1 skip=$offset count=$reglen status=none if=$ARQ |
        sed 's/./\|/2' |
        sed 's/./\|/5' #| more replacements....

ただし、sedは置換前にすべての '\ 0x00'文字を削除しています。

編集-@George Vasiliouテストを使用した私の環境でのsed動作のデモ:

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | od -t x1
0000000 6c 69 6e 65 41 00 6c 69 6e 65 42 00 6c 69 6e 65
0000020 43 00
0000022

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | sed 's/./|/5' | od -t x1
0000000 6c 69 6e 65 7c 6c 69 6e 65 42 6c 69 6e 65 43
0000017

私の環境はAIX 7.1であり、そこにあるsedにはGNUバージョンがありません。

回答:


10

sedあるテキストユーティリティが。これは、テキスト行(改行文字で区切られた、制限された長さの非NUL文字(バイトではない)のシーケンス)で機能します。

バイトシーケンスの2 番目と5 番目の バイトを変更する場合、いくつかの理由で機能しません。

  • sedテキストで動作します。入力にNUL文字が含まれている場合、改行文字で終わらない場合、2つの改行文字の間にLINE_MAXバイトを超える場合、sed実装によっては有効な文字を形成しないバイトシーケンスが含まれる場合、入力は機能しません。すべて。(GNUにsedはこれらの制限の多くがないことに注意してください)。
  • そのバイナリ入力がたまたま有効なテキストを形成し.ていても、バイトではなく文字に一致するため、複数のバイトに一致する場合があります。
  • sedコードは入力のすべてのに対して実行されるため、入力全体ではなく、各行の2番目と5番目の文字が変更されます。

入力を任意のバイト配列として扱うには(NULバイトの制限や長さの制限なし)、perl代わりに使用したい場合があります。

 dd.... | perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}'

例:

$ printf 'a\0b\0cd' |
>   perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}' |
>   od -Ax -tx1 -tc
000000  61  7c  62  00  7c  64
         a   |   b  \0   |   d
000006

または、vimxxdヘルパーを使用するなど、中間テキスト表現を使用することもできます。

dd... | xxd -p | sed '1s/../7c/2;1s/../7c/5' | xxd -p -r

xxd -pデフォルトでは、1行あたり60文字の16進ダンプが表示されます。上記では、最初の行の2番目と5番目の2桁の16進7c数を、ASCIIの番号であるに置き換えています|


ありがとう。私はxxdを使用して回避策を構築していました。すごい !どちらのソリューションもAIXで機能しました。
ルチアーノ

1

本気ですか ?単純なテストでは、これは私のケースでは発生しないようです(gnu sed 4.2.2)

$ echo -e "lineA\nlineB\nlineC"
lineA
lineB
lineC
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0'
lineAlineBlineC
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/5'
line|lineBlineC
# Verification if the nulls are still there:
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/5' |tr '\0' '\n'                                                                                                
line|
lineB
lineC

さらにテストを行うと、テストの6番目の文字(null位置)を置き換えるとnullが失われます。

$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/6' |tr '\0' '\n'
lineA|lineB 
lineC

$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/7' |tr '\0' '\n'
lineA
|ineB           
lineC 

@Luciano See update
George Vasiliou 2017

私の編集を見てください
ルチアーノ

@Luciano、私はまた、sedの--posix私の取扱説明書は無効にされ、ACCのすべてのGNU拡張が、それでもNULLバイトが存在している....で試してみました
ジョージ・バジリウー

Linuxでsedを試しましたが、はい、動作しているようです。しかし、私はそれをAIXで動作させる必要があります。
Luciano

1
@Luciano、確かに、私はこれを理解できます...残念ながら私はあなたを助けるためのAIXを持っていません、そして私が知っている限りでは、オンラインでプレイできるAIXシェルがないようです...私は答えを確信していますChazelas氏がお手伝いします。
George Vasiliou 2017

0

bbeを試してください-バイナリストリームのsedクローン:https : //sourceforge.net/projects/bbe/


AIX環境のユーザーが使用する方法など、サポートの詳細を追加できますか?また、ノートでは問題は、彼らは追加のツールをインストール/コンパイルを制限することができるので、「ちょうどシェルのツールを使用する」と言うことを
ジェフ・シャラー

適切なツールにリンクしていますか?あなたのリンクは、2013年に最後に更新された「ブロックベースの暗号化(別名2Bx4Bx2B)」プロジェクトに行く
Ale
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.