GNU/Linux >> Linux Esercitazione >  >> Linux

convertire file di testo di bit in file binario

Aggiunta di -r opzione (modalità inversa) a xxd -b in realtà non funziona come previsto, perché xxd semplicemente non supporta la combinazione di questi due flag (ignora -b se entrambi sono dati). Invece, devi prima convertire i bit in esadecimale da solo. Ad esempio in questo modo:

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

Spiegazione completa:

  • La parte all'interno delle parentesi crea un bc copione. Per prima cosa imposta la base di input su binario (2) e la base di output su esadecimale (16). Successivamente, il sed comando stampa il contenuto di instructions.txt con un punto e virgola tra ogni gruppo di 4 bit, che corrisponde a 1 cifra esadecimale. Il risultato viene reindirizzato in bc .
  • Il punto e virgola è un separatore di comandi in bc , quindi tutto ciò che fa lo script è stampare tutti i numeri interi di input (dopo la conversione di base).
  • L'output di bc è una sequenza di cifre esadecimali, che può essere convertita in un file con il solito xxd -r -p .

Uscita:

$ 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 per convertire stringhe a 32 bit di uno e zero nel binario corrispondente:

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

cosa fa:

  • perl -ne ripeterà ogni riga del file di input fornito su STDIN (instructions.txt )
  • pack("B32", $_) prenderà un elenco di stringhe di 32 bit ($_ che abbiamo appena letto da STDIN) e convertirlo in valore binario (puoi in alternativa usare "b32" se si desidera un ordine di bit crescente all'interno di ogni byte anziché un ordine di bit decrescente; vedi perldoc -f pack per maggiori dettagli)
  • print genererebbe quindi quel valore convertito in STDOUT, che poi reindirizzeremo al nostro file binario instructions.bin

verifica:

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

La mia risposta originale non era corretta - xxd non può accettare né -p o -r con -b ...

Dato che le altre risposte sono realizzabili e nell'interesse di "un altro modo ", che ne dici di quanto segue:

Inserimento

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

Uscita

$ 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 pipeline:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - non necessario, ma usato per chiarezza
  • tr -d $'\n' - rimuovere tutte le nuove righe dall'input
  • read -N 4 nibble - leggi esattamente 4× caratteri nel nibble variabile
  • printf '%x' "$((2#${nibble}))" convertire il bocconcino da binario a 1× carattere esadecimale
    • $((2#...)) - convertire il valore dato da base 2 (binario) a base 10 (decimale)
    • printf '%x' - formatta il valore dato da base 10 (decimale) a base 16 (esadecimale)
  • xxd -r -p - inverso (-r ) un semplice dump (-p ) - da esadecimale a binario grezzo

Pitone:

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
  • Un heredoc non quotato (<< EOF ) viene utilizzato per inserire contenuto nel codice Python
    • Questo non è efficiente se l'input diventa grande
  • cat e tr - utilizzato per ottenere un input pulito (una riga)
  • range(0, len(d), 8) - ottenere un elenco di numeri da 0 alla fine della stringa d , spostando 8× caratteri alla volta.
  • chr(int(d[i:i+8],2)) - converte la slice corrente (d[i:i+8] ) da binario a decimale (int(..., 2) ), quindi a un carattere non elaborato (chr(...) )
  • [ x for y in z] - comprensione dell'elenco
  • ''.join(...) - convertire l'elenco di caratteri in una singola stringa
  • print(...) - stampalo

Linux
  1. Come rimuovere i "dati binari" da un file di testo (ad es. Bash_history)?

  2. Cosa fa considerare Grep un file come binario?

  3. Decomprimere un file .gz per ottenere un file di testo ma ottenere un file binario??

  4. Come convertire un file eseguibile Linux (binario) in un file exe di Windows?

  5. Come estrarre la parte di testo di un file binario in linux/bash?

Come convertire un file Windows in un file UNIX

Come si aggiunge del testo a un file?

Converti una stringa di testo in bash in array

Converti immagine in testo

Converti la modalità binaria in modalità testo e l'opzione inversa

Come posso convertire i dati di testo a due valori in binario (rappresentazione in bit)