GNU/Linux >> Linux の 問題 >  >> Linux

ビットのテキスト ファイルをバイナリ ファイルに変換する

-r の追加 オプション (リバースモード) を xxd -b に xxd は単にこれら 2 つのフラグの組み合わせをサポートしていないためです (-b は無視されます)。 両方が指定されている場合)。代わりに、最初に自分でビットを 16 進数に変換する必要があります。たとえば、次のようになります:

( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin

完全な説明:

  • 括弧内の部分は bc を作成します 脚本。まず、入力基数を 2 進数 (2) に、出力基数を 16 進数 (16) に設定します。その後、sed コマンドは instructions.txt の内容を出力します 16 進数の 1 桁に相当する 4 ビットの各グループの間にセミコロンを挿入します。結果は bc にパイプされます .
  • セミコロンは bc のコマンド区切り文字です であるため、スクリプトはすべての入力整数を出力するだけです (基数変換後)。
  • bc の出力 通常の xxd -r -p でファイルに変換できる 16 進数のシーケンスです。 .

出力:

$ hexdump -Cv instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011  ....
00000004: 00000010 11010001 00100000 10000011  .. .
00000008: 00000000 01110011 00000010 10110011  .s..
0000000c: 00000000 01110011 00000100 00110011  .s.3
00000010: 00000000 01110011 01100100 10110011  .sd.
00000014: 00000000 00000000 00000000 00010011  ....

1 と 0 の 32 ビット文字列を対応するバイナリに変換する oneliner:

$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin

機能:

  • perl -ne STDIN (instructions.txt) で提供される入力ファイルの各行を反復処理します。 )
  • pack("B32", $_) 32 ビットの文字列リスト ($_ これを STDIN から読み取っただけ)、それをバイナリ値に変換します (代わりに "b32" を使用することもできます)。 降順のビット順ではなく、各バイト内で昇順のビット順が必要な場合。 perldoc -f pack を参照 詳細はこちら)
  • print 次に、変換された値を STDOUT に出力し、それをバイナリ ファイル instructions.bin にリダイレクトします。

検証:

$ hexdump -Cv instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018

$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011  ....
00000004: 00000010 11010001 00100000 10000011  .. .
00000008: 00000000 01110011 00000010 10110011  .s..
0000000c: 00000000 01110011 00000100 00110011  .s.3
00000010: 00000000 01110011 01100100 10110011  .sd.
00000014: 00000000 00000000 00000000 00010011  ....

元の回答が間違っていました - xxd -p のどちらも受け入れられません または -r -b で ...

他の答えが実行可能であり、「別の方法」の利益のために "、次はどうですか:

入力

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

出力

$ hexdump -Cv < instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018

Bash パイプライン:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - 不要ですが、わかりやすくするために使用しています
  • tr -d $'\n' - 入力からすべての改行を削除
  • read -N 4 nibble - 正確に読む nibble に 4× 文字 変数
  • printf '%x' "$((2#${nibble}))" ニブルをバイナリから 1× 16 進文字に変換します
    • $((2#...)) - 指定された値を基数 2 (2 進数) から基数 10 (10 進数) に変換します
    • printf '%x' - 指定された値を基数 10 (10 進数) から基数 16 (16 進数) にフォーマットします
  • xxd -r -p - 逆 (-r ) プレーン ダンプ (-p ) - 16 進数から生の 2 進数へ

パイソン:

python << EOF > instructions.bin
d = '$(cat instructions.txt | tr -d $'\n')'
print(''.join([chr(int(d[i:i+8],2)) for i in range(0, len(d), 8)]))
EOF
  • 引用されていないヒアドキュメント (<< EOF ) は、コンテンツを Python コードに取り込むために使用されます
    • 入力が大きくなると効率が悪い
  • cattr - クリーンな (1 行の) 入力を取得するために使用
  • range(0, len(d), 8) - 0 から文字列 d の末尾までの数字のリストを取得します 、一度に 8 倍の文字をステップ実行します。
  • chr(int(d[i:i+8],2)) - 現在のスライスを変換 (d[i:i+8] ) 2 進数から 10 進数 (int(..., 2)) )、そして生の文字 (chr(...)) )
  • [ x for y in z] - リストの理解
  • ''.join(...) - 文字のリストを単一の文字列に変換
  • print(...) - 印刷

Linux
  1. Bashスクリプト:ファイルがテキストファイルかどうかを確認しますか?

  2. テキストファイル(Bash_historyなど)から「バイナリデータ」を削除するにはどうすればよいですか?

  3. Grepがファイルをバイナリと見なす理由は何ですか?

  1. .gzファイルを解凍してテキストファイルを取得しますが、バイナリファイルを取得しますか?

  2. Linuxでテキストファイルからバイナリを見分ける方法

  3. ファイルにテキストを追加するにはどうすればよいですか?

  1. bash のテキスト文字列を配列に変換する

  2. Linux/bashでバイナリファイルのテキスト部分を抽出するには?

  3. Linux の file コマンドがテキスト ファイルをバイナリ データとして報告する原因は何ですか?