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
bccopione. Per prima cosa imposta la base di input su binario (2) e la base di output su esadecimale (16). Successivamente, ilsedcomando stampa il contenuto diinstructions.txtcon un punto e virgola tra ogni gruppo di 4 bit, che corrisponde a 1 cifra esadecimale. Il risultato viene reindirizzato inbc. - 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 solitoxxd -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 -neripeterà 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; vediperldoc -f packper maggiori dettagli)printgenererebbe quindi quel valore convertito in STDOUT, che poi reindirizzeremo al nostro file binarioinstructions.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 chiarezzatr -d $'\n'- rimuovere tutte le nuove righe dall'inputread -N 4 nibble- leggi esattamente 4× caratteri nelnibblevariabileprintf '%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
catetr- utilizzato per ottenere un input pulito (una riga)range(0, len(d), 8)- ottenere un elenco di numeri da 0 alla fine della stringad, 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 stringaprint(...)- stampalo