Bir kabuk komut dosyasında ikili - onaltılık ve ondalık


20

İkili onaltılık ve ondalık ve viceversa kabuk komut dosyasında dönüştürmek gereken bir bağlam var. Birisi bana bunun için bir araç önerebilir mi?


7
Son yanıtları görünce, belki “ikili” nin ikili sayı mı yoksa ikili dosya mı olduğunu belirtmelisiniz .
manatwork

Yanıtlar:


39

Oldukça dönüşüm yapmak basittir gelen saf bash ikili ( echove printfyerleşikleri şunlardır):

İkiliden onluya

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

İkiliden onaltılıya

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

Yalnızca bash kullanarak ikili dosyaya geri dönmek biraz daha karmaşıktır, bu yüzden çözümlerin diğer cevaplarını görmenizi öneririm.


Ondalıktan onaltılıya ne dersin.
Bangi

2
@Bangi printf '%x\n' 10Örneğin yapın.
Chris Down

1
printf %dBin2dec için kullanmanın anlamı nedir? $(( ... ))zaten ondalık bir sonuç verir echo, yeterlidir.
Andrea Corbellini

@AndreaCorbellini - Kişisel tercih. Genel olarak, çeşitli nedenlerle (çoğunlukla taşınabilirlik) printf '%s\n' fooyerine kullanıyorum echo, aynı nedenden dolayı burada kullanmıyorum.
Chris Down

@ChrisDown: Bu soru açıkça (iyi uygulanmış bir yerleşime sahip) Bash hakkındaydı echo. Benim hatam!
Andrea Corbellini

16

İkili olarak kabul ederseniz, temel verileri 2 ile değil, 0 dahil olası bayt değerine sahip verilerdeki gibi ifade edersiniz:

Dönüştürmek için gelen ikili, od(standart), xxd(birlikte gelir vim) ya da perl'ın unpackakla gelir.

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

Şimdi, ikili, (standart) veya 'lara geri dönüştürmek için :awkxxd -rperlpack

Yukarıdaki od -tu1veya perldaha sonraki ondalık çıktıdan :

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

Hexa perlveya xxd -püzeri:

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

13

Bunun için bc'yi ibaseve obaseparametrelerini değiştirerek kullanabilirsiniz :

İşin püf noktası, üsler hakkında açık olmanız gerektiğidir. Eğer ibase değeriniz 2 ise, obazınızı 10 olarak ayarlarsanız, ikili dosyada 10 2 olduğu için hiçbir şey yapmaz. Bu nedenle onaltılı gösterim kullanmanız gerekir.

Yani ikiliden ondalığa kadar olurdu (obazın A olduğunu izleyin)

İkiliden onluya:

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

İkiliden onaltıya:

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

obaseÖnce 'çıktı tabanı' değiştirilirse, daha kolay olmalıdır:

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

6
Bu ikinci örnek yanlıştır - 'F', taban 15'tir, 16 değil (onaltılık ondalık 16, F değil 10'dur). echo 'ibase=2;obase=F;1111Hangisinin ondalık 15'e eşit olması gerektiğini deneyin , yani. Altıgen F. Taban 15'te (0-E rakamları) olduğu 10 olarak ortaya çıkar. Eğer OBASE devlet durumunda da kolaydır ilk , örneğin: echo 'obase=16;ibase=2;1111'|bc. Karışıklık yok.
goldilocks

2
Şimdi en kötüsü. Bir kez ayarladıktan sonra ibase, bu temelde bile, girdi sağlamanız gerekir obase. Yani örneğinizde olur echo 'ibase=2;obase=10000;11110001011010'|bc. Goldilocks'un tavsiyelerini dinlemeniz ve siparişi tersine çevirmeniz daha iyi - ilk önce obaseo zaman ibase.
manatwork

3

Sayıları taban-2'den 10 veya 16'ya ve geri dönüştürmek istiyorsanız, bcbunu psarossy tarafından daha önce belirtildiği gibi yapmak için standart araçtır .

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

Gibi bazı kabuklar zsh, aritmetik genişletme operatörlerinin bir parçası olarak taban dönüşümü için yerleşik desteğe sahiptir:

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

ve bunun gibi.

Hem ksh93ve zshayrıca destek:

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

Ancak, genişletildiğinde, $binarybir 2#veya 16#önekinin (ile şeritleyebileceğiniz) olacağını unutmayın ${binary#*#}.

ksh93 ayrıca destekler:

printf "%..2d\n" 123

ikiliye dönüştürmek.


1

Onaltılık kullanımına ikili için: XXD linux aracı ve qalculate aracını kullanabilirsiniz onluya ikili için.

Xxd türü xxd --helpveya man xxdLinux ile ilgili yardım için .


1

PHP'yi kullanabilirsiniz:

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

Veya 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

Veya 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

Önceki yanıtta belirtildiği gibi, Bash'de echo ve printf kullanarak Binary to Decimal ve Hexa Decimal'ı aşağıdaki gibi yapabilirsiniz. Ben sadece saf Bash kullanarak Ondalık ve Hex ikili dönüştürmek nasıl ekliyorum.

Echo kullanarak İkili - Ondalık

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

Printf kullanarak İkili-Hexa-Ondalık

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

Yalnızca Bash kullanarak tam sayı ondalıktan İkili dönüşüme

Ondalık değeri ikiliye dönüştürmek istiyorsanız, yalnızca Bash kullanarak aşağıdaki gibi yapabilirsiniz:

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

Ardından aşağıdakileri kopyalayıp yapıştırın:

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

Sonra kaydettiğiniz yerden deneyin:

./dec2bin 420
110100100

Tam sayı eklenmelidir !!

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

Yalnızca Bash kullanarak onaltılıktan İkili dönüşüme

Benzer şekilde, sadece bash kullanılarak aşağıdaki gibi onaltılıdan ikiliye:

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

Örneğin:

./hex2bin 1aF
110101111

Onaltılı geçilmelidir:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.