Tengo un contexto donde necesito convertir binario a hexadecimal y decimal y viceversa en un script de shell. ¿Alguien puede sugerirme una herramienta para esto?
Tengo un contexto donde necesito convertir binario a hexadecimal y decimal y viceversa en un script de shell. ¿Alguien puede sugerirme una herramienta para esto?
Respuestas:
Es bastante sencillo hacer la conversión de binario en bash puro ( echo
y printf
son incorporados):
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Regresar a binario usando bash solo es algo más complejo, por lo que sugiero que vea las otras respuestas para soluciones a eso.
printf '%x\n' 10
, por ejemplo.
printf %d
para bin2dec? $(( ... ))
Ya da un resultado decimal, echo
es suficiente.
printf '%s\n' foo
lugar de echo
por una variedad de razones (principalmente portabilidad), por la misma razón, no lo uso aquí.
echo
integrada bien implementada ). ¡Culpa mía!
Suponiendo que por binario, se refiere a datos binarios como en datos con cualquier valor de byte posible, incluido 0, y no números de base 2:
Para convertir a binario, od
(estándar), xxd
(viene con vim
) o perl
's unpack
vienen a la 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*",$_)'
Ahora, para volver a convertir a binario, awk
(estándar) xxd -r
o perl
's pack
:
De la salida decimal de od -tu1
o perl
superior:
LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'
Del hexa perl
o xxd -p
superior:
xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Puede usar bc para esto manipulando los parámetros ibase
y obase
:
El truco es que debes ser explícito sobre las bases. Entonces, si su ibase es 2, entonces si establece su obase en 10, no hará nada, ya que 10 en binario es 2. Por lo tanto, debe usar la notación hexadecimal.
Entonces binario a decimal sería (mira que obase es A)
Binario a decimal:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
Binario a hexadecimal:
$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A
Si la 'base de salida' obase
se cambia primero, debería ser más fácil:
$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
echo 'ibase=2;obase=F;1111
cuál debería ser igual a 15 decimal, es decir. F en hex. Sale como 10, que está en la base 15 (dígitos 0-E). También es más fácil si usted indica el obase primero , por ejemplo: echo 'obase=16;ibase=2;1111'|bc
. No hay confusión
ibase
, debe proporcionar información en esa base, incluso para obase
. Así en tu ejemplo sería echo 'ibase=2;obase=10000;11110001011010'|bc
. Es mejor escuchar los consejos de goldilocks y revertir el orden: primero obase
, luego ibase
.
Si te refieres a convertir números de base-2 a 10 o 16 y viceversa, bc
es la herramienta estándar para hacer eso como ya lo mencionó psarossy .
decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)
Algunos shells como zsh
tienen soporte incorporado para conversión de base como parte de sus operadores de expansión aritmética:
decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))
y así.
Ambos ksh93
y zsh
también apoyan:
typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'
Pero tenga en cuenta que, cuando se expande, $binary
tendrá un prefijo 2#
o 16#
(que puede eliminar ${binary#*#}
.
ksh93
también es compatible con:
printf "%..2d\n" 123
para convertir a binario.
Para uso binario a hexadecimal: herramienta xxd en linux y para binario a decimal, puede usar la herramienta qalculate.
Para obtener ayuda sobre el tipo xxd xxd --help
o man xxd
en Linux.
Puedes usar 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
Como se mencionó en la respuesta anterior, puede hacer Binary to Decimal y Hexa Decimal de la siguiente manera en Bash usando echo e printf. Solo estoy agregando aquí cómo convertir de decimal y hexadecimal a binario usando Bash puro.
Binario a decimal usando echo
echo "$((2#101010101))"
341
Binario a Hexa-Decimal usando printf
printf '%x\n' "$((2#101010101))"
155
Conversión de entero decimal a binario usando solo Bash
Usando solo Bash, si desea convertir decimal a binario, puede hacerlo de la siguiente manera:
touch dec2bin && chmod +x "$_" && vim "$_"
Y luego copie y pegue lo siguiente:
#!/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;
Y luego pruébalo desde donde guardaste:
./dec2bin 420
110100100
¡Se debe agregar un entero!
./dec2bin 420.py
420.py is not an integer bruv!
Conversión hexadecimal a binaria usando solo Bash
Del mismo modo, hexadecimal a binario, de la siguiente manera 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;
Por ejemplo:
./hex2bin 1aF
110101111
Hex debe ser pasado:
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!