プロトコルをテストする目的で、コマンドラインで16進数から生のバイナリパケットを生成したいと思います。アプリケーションを書くよりも、この方法で簡単に実行できることを願っています。
現在の状況は次のとおりです。
echo '0A' | xxd -b
0000000: 00110000 01000001 00001010
私が欲しいのは:
echo '0A' | xxd -b
0000000: 00001010
または
echo '0A' | xxd -b
0000000: 01010000
私は必要なエンディアンについて確信が持てないので。必要に応じて変更したい。これは達成可能ですか?
echo '0A'
は3つの文字を生成します。 ANL; xxd -b
は、これら3つの文字をバイナリで出力します。値が10の1バイト(つまり、16進数のA
)だけが必要な場合は、次のように記述できます(bashで)。
echo -n $'\x0A'
^ ^ ^
| | |
| | +-- `\x` indicates a hexadecimal escape
| +----- Inside a $' string, escapes are interpreted
+------- -n suppresses the trailing newline
より良い代替案はprintf '\x0A'
です。 printfは、フォーマット文字列のエスケープシーケンスを解釈し、暗黙の改行を出力しません。 (これはPosix互換シェルであり、すべてのPosix互換シェルで動作するはずです。)さらに別のbashの可能性はecho -n -e '\x0A'
;です。 (非標準)-e
フラグは、エスケープシーケンスを解釈するようにエコーに要求します。
なぜecho '1' | xxd -b
が16進数50
と同等の出力を期待するのか、私にはわかりません。 xxd
が0A
が16進数で1
がそうでないことをどのように理解することを期待していますか?さらに、なぜ50
? (文字1
のASCIIコードは16進数31
です。)
エンディアンはバイトに影響しません。バイト内のビットの順序は、バイトがシリアルラインを介して送信されるまで完全に概念的であり、オシロスコープまたは類似のものでのみ表示されます。
16進数の文字列のバイナリ出力が必要な場合は、xxd -r -p
。例えば。:
$ echo '0A0B0C0D' | xxd -r -p | xxd -b
0000000: 00001010 00001011 00001100 00001101 ....
0A0B0C0Dを4バイトのバイナリーに変換し(最初のxxdへの呼び出し)、次に変換して出力可能にします(2番目の呼び出し)。あなたはバイナリ出力が欲しいと言いますが、あなたがしようとしている例は印刷可能な表現です。
2番目の例で示唆しているように、ニブルレベルでエンディアンが曖昧なところは何も知りません。 xxdでの変換は、一度に純粋なバイトであり、特定のマルチバイト数を表すとは限りません。
はい、xxd
を使用してそれを行うことができますが、入力形式が気に入らない場合があります。あなたの例では、0x0aはASCII改行の16進値です。改行を1つ含むファイルを作成し、xxd
を使用してリストを作成できます。
$ xxd one_line_file
0000000: 0a .
適切なフラグを指定すると、その出力からxxd
から単一の改行を取得できます。
$ echo "0000000: 0a" | xxd -r > another_one_line_file
$ xxd another_one_line_file
0000000: 0a
xxd
にはかなりいい出力形式があります。テキストエディターを使用してパケットを作成し、xxd -r
を使用してバイナリに移動するのはそれほど面倒ではありません。 。