Da binario a esadecimale e decimale in uno script di shell


20

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?


7
Vedendo le risposte recenti, forse dovresti specificare se "binario" significa numero binario o file binario .
arte

Risposte:


39

È abbastanza semplice fare la conversione da binario in puro bash ( echoe printfsono builtin):

Da binario a decimale

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

Da binario a esadecimale

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


che ne dite da decimale a esadecimale.
Bangi,

2
@Bangi Basta printf '%x\n' 10, per esempio.
Chris Down,

1
Qual è lo scopo di usare printf %dbin2dec? $(( ... ))dà già un risultato decimale, echoè sufficiente.
Andrea Corbellini,

@AndreaCorbellini - Preferenze personali. In generale, lo uso printf '%s\n' fooinvece echoper una serie di motivi (principalmente portabilità), per lo stesso motivo, non lo uso qui.
Chris Down,

@ChrisDown: pensavo che questa domanda fosse esplicitamente su Bash (che ha un echobuiltin ben implementato ). Colpa mia!
Andrea Corbellini,

16

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

Dall'output decimale da od -tu1o perlsopra:

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

Dall'exa perlo xxd -psopra:

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

13

Puoi usare bc per questo manipolando i parametri ibasee 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" obaseviene cambiata per prima, dovrebbe essere più semplice:

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

6
Questo secondo esempio è errato: "F" sarebbe la base 15, non 16 (il decimale 16 in esadecimale è 10, non F). Prova echo 'ibase=2;obase=F;1111che 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
Riccioli d'oro

2
Adesso è peggio. Una volta impostato 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.
arte

3

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 zshhanno 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 ksh93e zshanche il supporto:

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

Ma nota che, una volta espanso, $binaryavrà un prefisso 2#o 16#(con il quale puoi rimuovere ${binary#*#}.

ksh93 supporta anche:

printf "%..2d\n" 123

per convertire in binario.


1

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


1

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

0

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!
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.