J'ai un contexte où j'ai besoin de convertir le binaire en hexadécimal et décimal et vice-versa dans un script shell. Quelqu'un peut-il me suggérer un outil pour cela?
J'ai un contexte où j'ai besoin de convertir le binaire en hexadécimal et décimal et vice-versa dans un script shell. Quelqu'un peut-il me suggérer un outil pour cela?
Réponses:
Il est assez simple de faire la conversion à partir de binaire en bash pur ( echo
et printf
sont intégrés):
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Revenir au binaire en utilisant bash seul est un peu plus complexe, donc je vous suggère de voir les autres réponses pour trouver des solutions à cela.
printf '%x\n' 10
, par exemple.
printf %d
bin2dec? $(( ... ))
donne déjà un résultat décimal, echo
suffit.
printf '%s\n' foo
au lieu de echo
pour diverses raisons (principalement la portabilité), pour la même raison, je ne l'utilise pas ici.
echo
intégrée bien implémentée ). Ma faute!
En supposant que par binaire, vous voulez dire des données binaires comme dans des données avec toute valeur d'octet possible, y compris 0, et non des nombres en base 2:
Pour convertir de binaire, od
(standard), xxd
(livré avec vim
) ou perl
l » unpack
viennent à l' esprit.
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*",$_)'
Maintenant, pour se reconvertir à binaire, awk
(standard), xxd -r
ou perl
de pack
:
De la sortie décimale de od -tu1
ou perl
au - dessus:
LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'
Depuis l'hexa perl
ou xxd -p
au - dessus:
xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Vous pouvez utiliser bc pour cela en manipulant les paramètres ibase
et obase
:
L'astuce est que vous devez être explicite sur les bases. Donc, si votre ibase est 2, alors si vous définissez votre obase sur 10, il ne fera rien, car 10 en binaire est 2. Par conséquent, vous devez utiliser la notation hexadécimale.
Donc binaire à décimal serait (attention à ce que obase soit A)
Binaire à décimal:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
Binaire à hex:
$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A
Si la «base de sortie» obase
est modifiée en premier, cela devrait être plus facile:
$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
echo 'ibase=2;obase=F;1111
qui doit être égal à 15 décimal, c.-à-d. F en hex. Il apparaît comme 10, qu'il est en base 15 (chiffres 0-E). Il est également plus facile si vous déclarez la obase première , par exemple: echo 'obase=16;ibase=2;1111'|bc
. Pas de confusion.
ibase
, vous devez fournir une entrée dans cette base, même pour obase
. Donc, dans votre exemple, ce serait echo 'ibase=2;obase=10000;11110001011010'|bc
. Mieux vaut écouter les conseils de goldilocks et inverser l'ordre - premier set obase
, puis ibase
.
Si vous entendez convertir des nombres de base 2 en 10 ou 16 et inversement , bc
est l'outil standard pour le faire, comme déjà mentionné par psarossy .
decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)
Certains shells comme zsh
ont un support intégré pour la conversion de base dans le cadre de leurs opérateurs d'expansion arithmétique:
decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))
etc.
Les deux ksh93
et zsh
prennent également en charge:
typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'
Mais notez que, une fois développé, $binary
il aura un préfixe 2#
ou 16#
(avec lequel vous pouvez supprimer ${binary#*#}
.
ksh93
prend également en charge:
printf "%..2d\n" 123
pour convertir en binaire.
Pour une utilisation binaire en hexadécimal: outil xxd sous linux et pour binaire en décimal, vous pouvez utiliser l'outil qalculate.
Pour obtenir de l'aide concernant le type xxd xxd --help
ou man xxd
sous Linux.
Vous pouvez utiliser 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
Comme mentionné dans la réponse précédente, vous pouvez faire du binaire en décimal et hexa décimal comme suit dans Bash en utilisant echo et printf. J'ajoute juste ici comment convertir de Decimal et Hex en binaire en utilisant du Bash pur.
Binaire à décimal en utilisant l'écho
echo "$((2#101010101))"
341
Binaire en hexa-décimal en utilisant printf
printf '%x\n' "$((2#101010101))"
155
Conversion décimale en binaire en utilisant uniquement Bash
En utilisant uniquement Bash, si vous souhaitez convertir des décimales en binaires, vous pouvez le faire comme suit:
touch dec2bin && chmod +x "$_" && vim "$_"
Et puis copiez et collez les éléments suivants:
#!/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;
Et puis essayez-le d'où vous avez enregistré:
./dec2bin 420
110100100
Un entier doit être ajouté !!
./dec2bin 420.py
420.py is not an integer bruv!
Conversion hexadécimale en binaire en utilisant uniquement Bash
De même, hexadécimal à binaire, comme suit en utilisant uniquement 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;
Par exemple:
./hex2bin 1aF
110101111
L'hex doit être passé:
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!