GNU/Linux >> Znalost Linux >  >> Linux

převést textový soubor bitů na binární soubor

Přidání -r možnost (reverzní režim) na xxd -b ve skutečnosti nefunguje tak, jak bylo zamýšleno, protože xxd jednoduše nepodporuje kombinaci těchto dvou příznaků (ignoruje -b pokud jsou uvedeny oba). Místo toho musíte nejprve převést bity na hex sami. Například takto:

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

Úplné vysvětlení:

  • Část uvnitř závorek vytváří bc skript. Nejprve nastaví vstupní základnu na binární (2) a výstupní základ na šestnáctkovou (16). Poté sed příkaz vypíše obsah instructions.txt se středníkem mezi každou skupinou 4 bitů, což odpovídá 1 hexadecimální číslici. Výsledek je přenesen do bc .
  • Středník je oddělovač příkazů v bc , takže vše, co skript dělá, je tisknout každé vstupní celé číslo zpět (po základní konverzi).
  • Výstup bc je sekvence hexadecimálních číslic, kterou lze převést na soubor s obvyklým xxd -r -p .

Výstup:

$ 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 pro převod 32bitových řetězců jedniček a nul na odpovídající binární:

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

co to dělá:

  • perl -ne bude iterovat každý řádek vstupního souboru poskytnutého na STDIN (instructions.txt )
  • pack("B32", $_) bude mít seznam řetězců 32 bitů ($_ kterou jsme právě načetli ze STDIN) a převést ji na binární hodnotu (můžete také použít "b32" pokud jste chtěli vzestupné pořadí bitů uvnitř každého bajtu místo sestupného pořadí bitů; viz perldoc -f pack pro více podrobností)
  • print by pak vypsal tuto převedenou hodnotu do STDOUT, kterou pak přesměrujeme do našeho binárního souboru instructions.bin

ověřit:

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

Moje původní odpověď byla nesprávná - xxd nemůže přijmout ani -p nebo -r s -b ...

Vzhledem k tomu, že ostatní odpovědi jsou funkční, a v zájmu „jiného způsobu ", co třeba následující:

Vstup

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

Výstup

$ 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 potrubí:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - zbytečné, ale pro přehlednost se používá
  • tr -d $'\n' - odstranit všechny nové řádky ze vstupu
  • read -N 4 nibble - přečtěte si přesně 4× znaků do nibble proměnná
  • printf '%x' "$((2#${nibble}))" převést nibble z binárního na 1× hexadecimální znak
    • $((2#...)) - převeďte danou hodnotu ze základu 2 (binární) na základ 10 (desítkové)
    • printf '%x' - naformátujte danou hodnotu od základu 10 (desítkové) do základu 16 (šestnáctkové)
  • xxd -r -p - zpětně (-r ) prostý výpis (-p ) – od hexadecimální po surovou binární

Python:

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
  • Neuvozovaný heredoc (<< EOF ) se používá k získání obsahu do kódu Pythonu
    • To není efektivní, pokud je vstup velký
  • cat a tr - používá se k získání čistého (jednořádkového) vstupu
  • range(0, len(d), 8) - získat seznam čísel od 0 do konce řetězce d , krokování 8× znaků najednou.
  • chr(int(d[i:i+8],2)) - převést aktuální řez (d[i:i+8] ) z binárního na desítkové (int(..., 2) ) a poté na nezpracovaný znak (chr(...) )
  • [ x for y in z] - porozumění seznamu
  • ''.join(...) - převést seznam znaků na jeden řetězec
  • print(...) - vytisknout

Linux
  1. Používáte Uniq na Unicode Text?

  2. Připojování textu na konec textového souboru?

  3. Jak připojím text k souboru?

  1. Převeďte textový řetězec v bash na pole

  2. Jak extrahovat textovou část binárního souboru v linux/bash?

  3. Jak převedu tar.bz2 na tar.gz?

  1. Bash Script:Zkontrolujte, zda je soubor textovým souborem?

  2. Co by mohlo způsobit, že příkaz file v Linuxu nahlásí textový soubor jako binární data?

  3. Jak převést konkrétní text ze seznamu na velká písmena?