Binär in Hexadezimal und Dezimal in einem Shell-Skript

20

Ich habe einen Kontext, in dem ich binär in hexadezimal und dezimal und umgekehrt in einem Shell-Skript konvertieren muss. Kann mir jemand ein Tool dafür vorschlagen?

Bangi
quelle
7
Wenn Sie die letzten Antworten sehen, sollten Sie vielleicht angeben, ob "binär" eine Binärzahl oder eine Binärdatei bedeutet .
Manatwork
1
mögliche Cross - Site - Duplikat: stackoverflow.com/questions/13280131/... und stackoverflow.com/questions/378829/...
Ciro Santilli新疆改造中心法轮功六四事件

Antworten:

39

Es ist ziemlich einfach, die Konvertierung von Binary in Pure Bash ( echound printfBuiltins) durchzuführen:

Binär bis dezimal

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

Binär zu hexadezimal

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

Es ist etwas komplexer, mit bash allein zur Binärdatei zurückzukehren. Ich schlage vor, Sie sehen die anderen Antworten für Lösungen dafür.

Chris Down
quelle
wie wäre es mit dezimal bis hexadezimal.
Bangi
2
@Bangi Tu es einfach printf '%x\n' 10, zum Beispiel.
Chris Down
1
Wozu printf %dbin2dec? $(( ... ))gibt schon ein dezimales ergebnis aus, echoreicht.
Andrea Corbellini
@AndreaCorbellini - Persönliche Präferenz. Im Allgemeinen verwende ich printf '%s\n' foostatt aus echoverschiedenen Gründen (meistens Portabilität), aus dem gleichen Grund verwende ich es hier nicht.
Chris Down
@ ChrisDown: Ich dachte, diese Frage betraf explizit Bash (das eine gut implementierte echoFunktion hat). Mein Fehler!
Andrea Corbellini
16

Angenommen, mit binär meinen Sie binäre Daten wie in Daten mit einem möglichen Bytewert einschließlich 0 und nicht Basis-2-Zahlen:

Zum Konvertieren von binären, od(Standard), xxd(kommt mit vim) oder perl‚s unpackin den Sinn kommen.

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*",$_)'

Nun, zu konvertieren zurück zu binär, awk(Standard), xxd -roder perl‚s pack:

Aus der dezimalen Ausgabe von od -tu1oder perlüber:

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

Aus dem Hexa perloder xxd -phöher:

xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Stéphane Chazelas
quelle
13

Sie können bc dafür verwenden, indem Sie die Parameter ibaseund obaseändern:

Der Trick ist, dass Sie über die Grundlagen explizit sein müssen. Wenn Ihre ibase 2 ist, dann wenn Sie Ihre obase auf 10 setzen, wird es nichts tun, da 10 in der Binärzahl 2 ist. Daher müssen Sie hexadezimale Notation verwenden.

Also binär zu dezimal wäre (achte darauf, dass obase A ist)

Binär zu Dezimal:

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

Binär zu Hex:

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

Wenn die Ausgabebasis obasezuerst geändert wird, sollte es einfacher sein:

$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
psarossy
quelle
6
Dieses zweite Beispiel ist falsch - 'F' wäre Basis 15, nicht 16 (Dezimal 16 in hex ist 10, nicht F). Versuchen Sie, echo 'ibase=2;obase=F;1111die sollte dezimal 15, also gleich. F in hex. Es wird als 10 ausgegeben, was der Basis 15 entspricht (Ziffern 0-E). Es ist auch einfacher , wenn Sie die obase angeben ersten , zum Beispiel: echo 'obase=16;ibase=2;1111'|bc. Keine Verwirrung.
Goldlöckchen
2
Jetzt ist es am schlimmsten. Sobald Sie festgelegt haben ibase, müssen Sie in dieser Basis Eingaben vornehmen, auch für obase. Also in deinem Beispiel wäre echo 'ibase=2;obase=10000;11110001011010'|bc. Höre besser auf den Rat von Goldlöckchen und kehre die Reihenfolge um - erst einstellen obase, dann ibase.
Manatwork
3

Wenn Sie Zahlen von der Basis 2 in 10 oder 16 und zurück konvertieren möchten , bcist dies das Standardwerkzeug, das bereits von psarossy erwähnt wurde .

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

Einige Shells wie zshhaben als Teil ihrer arithmetischen Expansionsoperatoren eine eingebaute Unterstützung für die Basiskonvertierung:

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

und so weiter.

Beides ksh93und zshauch Unterstützung:

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

Beachten Sie jedoch, dass beim Erweitern $binaryein 2#oder ein 16#Präfix (mit dem Sie den Strip ausführen können) angezeigt wird ${binary#*#}.

ksh93 unterstützt auch:

printf "%..2d\n" 123

zu binär konvertieren.

Stéphane Chazelas
quelle
1

Für die Verwendung von Binär zu Hexadezimal: Das xxd- Tool unter Linux und für die Verwendung von Binär zu Dezimal können Sie das qalculate-Tool verwenden.

Hilfe zu xxd type xxd --helpoder man xxdunter Linux.

P4cK3tHuNt3R
quelle
1

Sie können PHP verwenden:

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

Oder 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

Oder 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
Steven Penny
quelle
0

Wie in der vorherigen Antwort erwähnt, können Sie in Bash unter Verwendung von echo und printf Binär zu Dezimal und Hexadezimal wie folgt vorgehen. Ich füge hier nur hinzu, wie man mit Pure Bash von Dezimal und Hex zu Binär konvertiert.

Binär zu Dezimal mit Echo

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

Binär zu Hexa-Dezimal mit printf

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

Ganzzahlige Dezimal-Binär-Konvertierung, bei der nur Bash verwendet wird

Wenn Sie nur Bash verwenden und Dezimalzahlen in Binärzahlen konvertieren möchten, können Sie dies folgendermaßen tun:

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

Kopieren Sie anschließend Folgendes, und fügen Sie es ein:

#!/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;

Und dann probieren Sie es aus, wo Sie gespeichert haben:

./dec2bin 420
110100100

Ganzzahl muss hinzugefügt werden !!

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

Hexadezimal-Binär-Konvertierung nur mit Bash

In ähnlicher Weise hexadezimal zu binär, wie folgt, wenn nur bash verwendet wird:

#!/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;

Beispielsweise:

./hex2bin 1aF
110101111

Verhexung muss übergeben werden:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Rakib Fiha
quelle