Binarny na szesnastkowy i dziesiętny w skrypcie powłoki


20

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?


7
Widząc najnowsze odpowiedzi, być może powinieneś określić, czy „binarny” oznacza liczbę binarną czy plik binarny .
manatwork

Odpowiedzi:


39

Konwersja z pliku binarnego w czystym bashu ( echoi printfsą wbudowane) jest dość prosta :

Binarny na dziesiętny

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

Binarny na szesnastkowy

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


co powiesz na dziesiętne na szesnastkowe.
Bangi,

2
@Bangi Po prostu zrób printf '%x\n' 10, na przykład.
Chris Down

1
Po co używać printf %dbin2dec? $(( ... ))już daje wynik dziesiętny, echowystarczy.
Andrea Corbellini,

@AndreaCorbellini - Preferencje osobiste. Ogólnie rzecz biorąc, używam printf '%s\n' foozamiast z echoróżnych powodów (głównie przenośności), z tego samego powodu nie używam go tutaj.
Chris Down,

@ChrisDown: Wydawało mi się, że to pytanie dotyczyło Basha (który ma dobrze zaimplementowaną echowbudowaną wersję). Mój błąd!
Andrea Corbellini,

16

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 unpackprzyjść 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 -rlub perl's pack:

Z wyniku dziesiętnego z od -tu1lub perlpowyżej:

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

Od hexa perllub xxd -pwyżej:

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

13

Możesz użyć do tego bc, manipulując parametrami ibasei 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 obasenajpierw zmieni się „podstawa wyjściowa” , powinno być łatwiej:

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

6
Ten drugi przykład jest błędny - „F” będzie podstawą 15, a nie 16 (liczba dziesiętna 16 w heksie to 10, a nie F). Spróbuj, echo 'ibase=2;obase=F;1111któ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.
goldilocks

2
Teraz jest najgorsze. Po ustawieniu ibasemusisz 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.
manatwork

3

Jeśli masz na myśli konwersję liczb z base-2 na 10 lub 16 i odwrotnie, bcto 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 zshmają 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 ksh93i zshwsparcie:

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

Pamiętaj jednak, że po rozwinięciu $binarybę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.


1

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 --helplub man xxdw systemie Linux.


1

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

0

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!
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.