Mam kontekst, w którym muszę przekonwertować dane binarne na szesnastkowe i dziesiętne oraz odwrotnie w skrypcie powłoki. Czy ktoś może zasugerować mi narzędzie do tego?
Mam kontekst, w którym muszę przekonwertować dane binarne na szesnastkowe i dziesiętne oraz odwrotnie w skrypcie powłoki. Czy ktoś może zasugerować mi narzędzie do tego?
Odpowiedzi:
Konwersja z pliku binarnego w czystym bashu ( echo
i printf
są wbudowane) jest dość prosta :
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Powrót do binarnego korzystania z samego basha jest nieco bardziej złożony, więc sugeruję, abyś zobaczył inne odpowiedzi na rozwiązania tego problemu.
printf '%x\n' 10
, na przykład.
printf %d
bin2dec? $(( ... ))
już daje wynik dziesiętny, echo
wystarczy.
printf '%s\n' foo
zamiast z echo
różnych powodów (głównie przenośności), z tego samego powodu nie używam go tutaj.
echo
wbudowaną wersję). Mój błąd!
Zakładając, że przez binarne, rozumiesz dane binarne jak w danych z dowolną możliwą wartością bajtu, w tym 0, a nie liczbami podstawowymi 2:
Aby przekonwertować z binarnym, od
(standard), xxd
(wyposażony vim
) lub perl
„s unpack
przyjść do głowy.
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*",$_)'
Teraz, aby przekonwertować z powrotem na binarne awk
(standardowe) xxd -r
lub perl
's pack
:
Z wyniku dziesiętnego z od -tu1
lub perl
powyżej:
LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'
Od hexa perl
lub xxd -p
wyżej:
xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Możesz użyć do tego bc, manipulując parametrami ibase
i obase
:
Sztuka polega na tym, że musisz wyraźnie mówić o bazach. Więc jeśli twój ibase ma wartość 2, to jeśli ustawisz obase na 10, nic to nie da, ponieważ 10 w systemie binarnym wynosi 2. Dlatego musisz użyć notacji szesnastkowej.
Więc binarny na dziesiętny będzie (patrz, że obase to A)
Binarny na dziesiętny:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
Binarny na hex:
$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A
Jeśli obase
najpierw zmieni się „podstawa wyjściowa” , powinno być łatwiej:
$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
echo 'ibase=2;obase=F;1111
który powinien być równy 15 po przecinku, tj. F na heksie Wychodzi jako 10, która znajduje się w podstawie 15 (cyfry 0-E). Łatwiej jest również, jeśli podać obase pierwszy , np echo 'obase=16;ibase=2;1111'|bc
. Bez zamieszania.
ibase
musisz podać dane wejściowe w tej bazie, nawet dla obase
. W twoim przykładzie byłoby echo 'ibase=2;obase=10000;11110001011010'|bc
. Lepiej słuchać rad Złotowłosa i odwrócić kolejność - najpierw ustawić obase
, a następnie ibase
.
Jeśli masz na myśli konwersję liczb z base-2 na 10 lub 16 i odwrotnie, bc
to standardowe narzędzie do robienia tego, jak już wspomniano w psarossy .
decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)
Niektóre powłoki zsh
mają wbudowaną obsługę konwersji bazowej w ramach arytmetycznych operatorów ekspansji:
decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))
i tak dalej.
Zarówno ksh93
i zsh
wsparcie:
typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'
Pamiętaj jednak, że po rozwinięciu $binary
będzie miał prefiks 2#
lub 16#
(za pomocą którego można usunąć ${binary#*#}
.
ksh93
obsługuje również:
printf "%..2d\n" 123
przekonwertować na binarny.
Do użycia binarnego do szesnastkowego: narzędzie xxd w systemie Linux, a do binarnego do dziesiętnego można użyć narzędzia qalculate.
Aby uzyskać pomoc dotyczącą typu xxd xxd --help
lub man xxd
w systemie Linux.
Możesz użyć PHP:
$ php -r 'printf("%b", 11);'
1011
Lub 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
Lub 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
Jak wspomniano w poprzedniej odpowiedzi, w Bash można wykonać Binary to Decimal i Hexa Decimal w następujący sposób, używając echa i printf. Właśnie dodam tutaj, jak przekonwertować z Decimal i Hex na binarne przy użyciu czystego Basha.
Binarny na dziesiętny za pomocą echa
echo "$((2#101010101))"
341
Binarny do szesnastkowego za pomocą printf
printf '%x\n' "$((2#101010101))"
155
Przeliczanie liczb całkowitych na dziesiętne na binarne przy użyciu tylko Bash
Używając tylko Bash, jeśli chcesz przekonwertować liczbę dziesiętną na binarną, możesz to zrobić w następujący sposób:
touch dec2bin && chmod +x "$_" && vim "$_"
A następnie skopiuj i wklej następujące elementy:
#!/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;
A następnie wypróbuj to, skąd zapisałeś:
./dec2bin 420
110100100
Liczba całkowita musi być dodana !!
./dec2bin 420.py
420.py is not an integer bruv!
Konwersja szesnastkowa na binarną przy użyciu tylko Bash
Podobnie, w systemie szesnastkowym lub binarnym, używając tylko 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;
Na przykład:
./hex2bin 1aF
110101111
Hex należy przekazać:
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!