GNU/Linux >> Belajar Linux >  >> Linux

mengkonversi file teks dari bit ke file biner

Menambahkan -r opsi (mode terbalik) ke xxd -b sebenarnya tidak berfungsi sebagaimana mestinya, karena xxd sama sekali tidak mendukung penggabungan kedua flag ini (mengabaikan -b jika keduanya diberikan). Sebagai gantinya, Anda harus mengubah bit menjadi hex sendiri terlebih dahulu. Contohnya seperti ini:

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

Penjelasan lengkap:

  • Bagian di dalam tanda kurung membuat bc naskah. Ini pertama-tama mengatur basis input ke biner (2) dan basis output ke heksadesimal (16). Setelah itu, sed perintah mencetak isi instructions.txt dengan titik koma antara setiap kelompok 4 bit, yang sesuai dengan 1 digit hex. Hasilnya disalurkan ke bc .
  • Titik koma adalah pemisah perintah di bc , jadi yang dilakukan skrip hanyalah mencetak kembali setiap bilangan bulat input (setelah konversi basis).
  • Keluaran dari bc adalah urutan digit hex, yang dapat dikonversi menjadi file dengan xxd -r -p biasa .

Keluaran:

$ 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  ....

oneliner untuk mengonversi string 32-bit satu dan nol menjadi biner yang sesuai:

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

apa fungsinya:

  • perl -ne akan mengulangi setiap baris file input yang disediakan di STDIN (instructions.txt )
  • pack("B32", $_) akan mengambil daftar string 32 bit ($_ yang baru saja kita baca dari STDIN), dan mengubahnya menjadi nilai biner (Anda juga dapat menggunakan "b32" jika Anda ingin urutan bit naik di dalam setiap byte, bukan urutan bit turun; lihat perldoc -f pack untuk detail lebih lanjut)
  • print kemudian akan menampilkan nilai yang dikonversi ke STDOUT, yang kemudian kami alihkan ke file biner kami instructions.bin

verifikasi:

$ 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  ....

Jawaban asli saya salah - xxd tidak dapat menerima -p atau -r dengan -b ...

Mengingat bahwa jawaban lain bisa diterapkan, dan untuk kepentingan "cara lain ", bagaimana dengan yang berikut:

Masukan

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

Keluaran

$ 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

Pipa bash:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - tidak perlu, tetapi digunakan untuk kejelasan
  • tr -d $'\n' - hapus semua baris baru dari input
  • read -N 4 nibble - baca tepatnya 4× karakter ke dalam nibble variabel
  • printf '%x' "$((2#${nibble}))" mengonversi nibble dari karakter biner menjadi 1× hex
    • $((2#...)) - konversi nilai yang diberikan dari basis 2 (biner) ke basis 10 (desimal)
    • printf '%x' - format nilai yang diberikan dari basis 10 (desimal) ke basis 16 (heksadesimal)
  • xxd -r -p - terbalik (-r ) dump biasa (-p ) - dari heksadesimal ke biner mentah

Piton:

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
  • Sebuah heredoc yang tidak dikutip (<< EOF ) digunakan untuk memasukkan konten ke dalam kode Python
    • Ini tidak efisien jika masukan menjadi besar
  • cat dan tr - digunakan untuk mendapatkan input bersih (satu baris)
  • range(0, len(d), 8) - dapatkan daftar angka dari 0 hingga akhir string d , melangkah 8× karakter sekaligus.
  • chr(int(d[i:i+8],2)) - mengonversi irisan saat ini (d[i:i+8] ) dari biner ke desimal (int(..., 2) ), lalu ke karakter mentah (chr(...) )
  • [ x for y in z] - pemahaman daftar
  • ''.join(...) - ubah daftar karakter menjadi string tunggal
  • print(...) - cetak itu

Linux
  1. Cara Menambahkan Teks ke Akhir File di Linux

  2. Bash Script:Periksa Apakah File Adalah File Teks?

  3. Menggunakan Uniq Pada Teks Unicode?

  1. Apa yang Membuat Grep Mempertimbangkan File Menjadi Biner?

  2. Bagaimana membedakan biner dari file teks di linux

  3. Bagaimana cara menambahkan teks ke file?

  1. Konversikan string teks dalam bash ke array

  2. Bagaimana cara mengekstrak bagian teks dari file biner di linux/bash?

  3. Bagaimana cara mengonversi tar.bz2 ke tar.gz?