Binario a hexadecimal y decimal en un script de shell


20

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?


77
Al ver las respuestas recientes, tal vez debería especificar si "binario" significa número binario o archivo binario .
manatwork

Respuestas:


39

Es bastante sencillo hacer la conversión de binario en bash puro ( echoy printfson incorporados):

Binario a decimal

$ echo "$((2#101010101))"
341

Binario a hexadecimal

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


¿Qué hay de decimal a hexadecimal?
Bangi

2
@Bangi Just do printf '%x\n' 10, por ejemplo.
Chris Down

1
¿Cuál es el punto de usar printf %dpara bin2dec? $(( ... ))Ya da un resultado decimal, echoes suficiente.
Andrea Corbellini

@AndreaCorbellini - Preferencia personal. En general, lo uso en printf '%s\n' foolugar de echopor una variedad de razones (principalmente portabilidad), por la misma razón, no lo uso aquí.
Chris Down

@ChrisDown: pensé que esta pregunta era explícitamente sobre Bash (que tiene una función echointegrada bien implementada ). ¡Culpa mía!
Andrea Corbellini

16

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 unpackvienen 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 -ro perl's pack:

De la salida decimal de od -tu1o perlsuperior:

LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'

Del hexa perlo xxd -psuperior:

xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'

13

Puede usar bc para esto manipulando los parámetros ibasey 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' obasese 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

66
Este segundo ejemplo es incorrecto: 'F' sería base 15, no 16 (el decimal 16 en hexadecimal es 10, no F). Pruebe echo 'ibase=2;obase=F;1111cuá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
Ricitos de oro

2
Ahora es lo peor. Una vez que establezca 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.
manatwork

3

Si te refieres a convertir números de base-2 a 10 o 16 y viceversa, bces 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 zshtienen 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 ksh93y zshtambién apoyan:

typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'

Pero tenga en cuenta que, cuando se expande, $binarytendrá un prefijo 2#o 16#(que puede eliminar ${binary#*#}.

ksh93 también es compatible con:

printf "%..2d\n" 123

para convertir a binario.


1

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 --helpo man xxden Linux.


1

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

0

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!
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.