Ho un contesto in cui devo convertire i binari in esadecimali e decimali e viceversa in uno script di shell. Qualcuno può suggerirmi uno strumento per questo?
Ho un contesto in cui devo convertire i binari in esadecimali e decimali e viceversa in uno script di shell. Qualcuno può suggerirmi uno strumento per questo?
Risposte:
È abbastanza semplice fare la conversione da binario in puro bash ( echo
e printf
sono builtin):
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Tornare al binario usando bash da solo è un po 'più complesso, quindi ti suggerisco di vedere le altre risposte per soluzioni.
printf '%x\n' 10
, per esempio.
printf %d
bin2dec? $(( ... ))
dà già un risultato decimale, echo
è sufficiente.
printf '%s\n' foo
invece echo
per una serie di motivi (principalmente portabilità), per lo stesso motivo, non lo uso qui.
echo
builtin ben implementato ). Colpa mia!
Supponendo che per binario si intendono i dati binari come nei dati con qualsiasi valore di byte possibile incluso 0 e non numeri di base-2:
Per convertire da binario, od
(standard), xxd
(viene fornito con vim
) o perl
s' unpack
vengono in mente.
od -An -vtu1 # for decimal
od -An -vtx1 # for hexadecimal
xxd -p # for hexa
perl -pe 'BEGIN{$\="\n";$/=\30};$_=unpack("H*",$_)' # like xxd -p
# for decimal:
perl -ne 'BEGIN{$\="\n";$/=\30;$,=" "}; print unpack("C*",$_)'
Ora, per convertire nuovamente in binario, awk
(standard) xxd -r
o perl
's pack
:
Dall'output decimale da od -tu1
o perl
sopra:
LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'
Dall'exa perl
o xxd -p
sopra:
xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Puoi usare bc per questo manipolando i parametri ibase
e obase
:
Il trucco è che devi essere esplicito sulle basi. Quindi se il tuo ibase è 2, quindi se imposti il tuo obase su 10, non farà nulla, dato che 10 in binario è 2. Quindi devi usare la notazione esadecimale.
Quindi il binario al decimale sarebbe (guarda che obase è A)
Da binario a decimale:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
Da binario a esadecimale:
$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A
Se la "base di output" obase
viene cambiata per prima, dovrebbe essere più semplice:
$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
echo 'ibase=2;obase=F;1111
che dovrebbe essere uguale a 15 decimale, cioè. F in esadecimale. Viene fuori come 10, che è nella base 15 (cifre 0-E). E 'anche più facile se utilizzate un Obase prima , ad esempio: echo 'obase=16;ibase=2;1111'|bc
. Nessuna confusione
ibase
, devi fornire input in quella base, anche per obase
. Quindi nel tuo esempio sarebbe echo 'ibase=2;obase=10000;11110001011010'|bc
. Meglio ascoltare i consigli di riccioli d'oro e invertire l'ordine - prima set obase
, quindi ibase
.
Se intendi convertire i numeri da base-2 a 10 o 16 e viceversa , bc
è lo strumento standard per farlo come già menzionato da psarossy .
decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)
Alcune shell come zsh
hanno il supporto incorporato per la conversione di base come parte dei loro operatori di espansione aritmetica:
decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))
e così via.
Sia ksh93
e zsh
anche il supporto:
typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'
Ma nota che, una volta espanso, $binary
avrà un prefisso 2#
o 16#
(con il quale puoi rimuovere ${binary#*#}
.
ksh93
supporta anche:
printf "%..2d\n" 123
per convertire in binario.
Per l'uso da binario a esadecimale: strumento xxd in linux e per binario a decimale è possibile utilizzare lo strumento qalculate.
Per assistenza riguardo al tipo xxd xxd --help
o man xxd
in Linux.
Puoi usare PHP:
$ php -r 'printf("%b", 11);'
1011
O Perl:
$ perl -e 'print unpack("B*", pack("c", 11))'
00001011
$ perl -e 'print unpack("B*", pack("C", 11))'
00001011
$ perl -e 'print unpack("B*", pack("W", 11))'
00001011
$ perl -e 'print unpack("B*", pack("n", 11))'
0000000000001011
$ perl -e 'print unpack("B*", pack("N", 11))'
00000000000000000000000000001011
O POSIX Awk svnpenn / stdlib :
$ awklib 'BEGIN {print mt_basecon(1011, 2, 16)}'
B
$ awklib 'BEGIN {print mt_basecon(1011, 2, 10)}'
11
$ awklib 'BEGIN {print mt_basecon("B", 16, 2)}'
1011
$ awklib 'BEGIN {print mt_basecon(11, 10, 2)}'
1011
Come menzionato nella risposta precedente, puoi fare Binary to Decimal e Hexa Decimal come segue in Bash usando echo e printf. Sto solo aggiungendo qui come convertire da Decimale e Hex in binario usando puro Bash.
Da binario a decimale utilizzando l'eco
echo "$((2#101010101))"
341
Da binario a Hexa-decimale usando printf
printf '%x\n' "$((2#101010101))"
155
Conversione da decimale intero a binario utilizzando solo Bash
Utilizzando solo Bash, se desideri convertire i decimali in binari, puoi farlo nel modo seguente:
touch dec2bin && chmod +x "$_" && vim "$_"
E quindi copia e incolla quanto segue:
#!/bin/bash
## converting decimal integer to binary, pass int as a parameter
num=$1;
dec2bin()
{ [ "$num" == "" ] && { printf "Error: Pass an integer\n"; exit 1; };
op=2; ## Since we're converting to binary
quo=$(( $num / $op)); rem=$(( $num % $op)); ## quotient and remainder
remarray=(); ## array for putting remainder inside array
remarray+=("$rem"); ## array expansion
until [[ $quo -eq 0 ]]; do
num=$quo; quo=$(( $num / $op)); ## looping to get all remainder untill 0
rem=$(( $num % $op)); remarray+="$rem"; ## array expansion
done
binary=$(echo "${remarray[@]}" | rev); ## reversing array
printf "$binary\n"; ## printing reversed array
}
main()
{ [[ -n ${num//[0-9]/} ]] &&
{ printf "Error: $num is not an integer bruv!\n"; return 1;
} || { dec2bin $num; }
}
main;
E poi provalo da dove hai salvato:
./dec2bin 420
110100100
Numero intero deve essere aggiunto !!
./dec2bin 420.py
420.py is not an integer bruv!
Conversione da esadecimale a binario usando solo Bash
Allo stesso modo, da esadecimale a binario, come segue usando solo bash:
#!/usr/local/bin/bash
## converting hexadecimal to binary, pass hex as a parameter
hex=$1;
hex2bin()
{ [ "$hex" == "" ] && { printf "Error: Pass a hex\n"; exit 1; };
op=2; num=$((16#$hex)); ## converting hex to integer
quo=$(( $num/ $op)); rem=$(( $num% $op)); ## quotient and remainder
remarray=(); remarray+=("$rem"); ## array expansion
until [[ $quo -eq 0 ]]; do
num=$quo; quo=$(( $num / $op)); ## looping to get all remainder untill 0
rem=$(( $num % $op)); remarray+="$rem"; ## array expansion
done
binary=$(echo "${remarray[@]}" | rev); ## reversing array
printf "$binary\n"; ## printing reversed array
}
main()
{
[[ -n ${hex//[0-9,A-F,a-f]/} ]] &&
{ printf "Error: $hex is not a hex bruv!\n"; return 1;
} || { hex2bin $hex; }
}
main;
Per esempio:
./hex2bin 1aF
110101111
L'esagono deve essere passato:
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!