Binário para hexadecimal e decimal em um script de shell


20

Eu tenho um contexto onde eu preciso converter binário em hexadecimal e decimal e vice-versa em um script de shell. Alguém pode me sugerir uma ferramenta para isso?


7
Vendo as respostas recentes, talvez você deva especificar se "binário" significa número binário ou arquivo binário .
— manatwork

Respostas:


39

É bastante simples fazer a conversão do binário no bash puro ( echoe printfsão embutidos):

Binário para decimal

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

Binário para hexadecimal

$ printf '%x\n' "$((2#101010101))"
155

Voltando ao binário usando o bash sozinho é um pouco mais complexo, então sugiro que você veja as outras respostas para soluções para isso.


que tal decimal para hexadecimal.
— Bangi

2
@ Bangi Basta fazer printf '%x\n' 10, por exemplo.
— 19413 Chris Down

11
Qual é o sentido de usar printf %dpara o bin2dec? $(( ... ))já dá um resultado decimal, echoé suficiente.
— Andrea Corbellini

@AndreaCorbellini - Preferência pessoal. Em geral, eu uso em printf '%s\n' foovez de echopor vários motivos (principalmente portabilidade), pelo mesmo motivo, não o uso aqui.
— 21713 Chris Down

@ ChrisDown: Eu pensei que essa pergunta fosse explicitamente sobre o Bash (que tem um buildin bem implementado echo). Minha culpa!
— Andrea Corbellini

16

Supondo que por binário, você quer dizer dados binários como em dados com qualquer valor possível de bytes, incluindo 0 e não números de base 2:

Para converter de binário, od(standard), xxd(vem com vim) ou perl's unpackvêm à 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*",$_)'

Agora, para converter novamente em binário, awk(padrão) xxd -rou perl's pack:

A partir da saída decimal de od -tu1ou perlacima:

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

A partir do hexa perlou xxd -pacima:

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

13

Você pode usar o bc para isso manipulando os parâmetros ibasee obase:

O truque é que você precisa ser explícito sobre as bases. Portanto, se seu ibase é 2, se você definir seu obase para 10, ele não fará nada, pois 10 no binário é 2. Portanto, você precisa usar a notação hexadecimal.

Então, binário para decimal seria (observe que obase é A)

Binário para decimal:

$> echo 'ibase=2;obase=A;11110001011010'|bc
15450

Binário para hexadecimal:

$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A

Se a 'base de saída' obasefor alterada primeiro, será mais fácil:

$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A

6
Este segundo exemplo está errado - 'F' seria a base 15, não 16 (16 decimal em hexadecimal é 10, não F). Tente echo 'ibase=2;obase=F;1111qual deve ser igual a decimal 15, ou seja. F em hex. Ele sai como 10, que está na base 15 (dígitos 0-E). É também mais fácil se você indicar o obase primeiro , por exemplo: echo 'obase=16;ibase=2;1111'|bc. Sem confusão.
— GOLDILOCKS

2
Agora é pior. Depois de definir ibase, você deve fornecer informações nessa base, mesmo para obase. Então, no seu exemplo seria echo 'ibase=2;obase=10000;11110001011010'|bc. Melhor ouvir os conselhos de goldilocks e reverter a ordem - primeiro set obase, então ibase.
— 26413 manatwork

3

Se você quer dizer converter números da base 2 para 10 ou 16 e vice-versa, bcé a ferramenta padrão para fazer isso, como já mencionado por psarossy .

decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)

Alguns shells, como o zshsuporte interno para conversão de base, fazem parte de seus operadores de expansão aritmética:

decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))

e assim por diante.

Ambos ksh93e zshtambém suportam:

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

Mas observe que, quando expandido, $binaryterá um prefixo 2#ou 16#(com o qual você pode remover) ${binary#*#}.

ksh93 também suporta:

printf "%..2d\n" 123

converter para binário.


1

Para uso binário em hexadecimal: ferramenta xxd no linux e para binário em decimal, você pode usar a ferramenta qalculate.

Para obter ajuda sobre o tipo xxd xxd --helpou man xxdno Linux.


1

Você pode usar o PHP:

$ php -r 'printf("%b", 11);'
1011

Ou 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

Ou 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

Conforme mencionado na resposta anterior, você pode executar Binário em Decimal e Hexa Decimal da seguinte maneira no Bash usando echo e printf. Estou apenas adicionando aqui como converter de decimal e hexadecimal para binário usando o Bash puro.

Binário para decimal usando eco

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

Binário para Hexa-Decimal usando printf

printf '%x\n' "$((2#101010101))"
155

Conversão de decimal inteiro para binário usando apenas Bash

Usando apenas o Bash, se você quiser converter decimal em binário, faça o seguinte:

touch dec2bin && chmod +x "$_" && vim "$_"

E copie e cole o seguinte:

#!/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 tente de onde você salvou:

./dec2bin 420
110100100

Inteiro deve ser adicionado !!

./dec2bin 420.py
420.py is not an integer bruv!

Conversão hexadecimal em binário usando apenas Bash

Da mesma forma, hexadecimal para binário, da seguinte maneira, usando apenas o 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 exemplo:

./hex2bin 1aF
110101111

Hex deve ser passado:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.