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 obsahinstructions.txt
se středníkem mezi každou skupinou 4 bitů, což odpovídá 1 hexadecimální číslici. Výsledek je přenesen dobc
. - 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ýmxxd -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ů; vizperldoc -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 souboruinstructions.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 vstupuread -N 4 nibble
- přečtěte si přesně 4× znaků donibble
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
atr
- používá se k získání čistého (jednořádkového) vstupurange(0, len(d), 8)
- získat seznam čísel od 0 do konce řetězced
, 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ězecprint(...)
- vytisknout
Jak rekurzivně nahradit znaky sed?
K čemu v symbolickém odkazu ukazujícím na „127.0.1.1:+xxxxx“ je znak plus?