Biner ke heksadesimal dan desimal dalam skrip shell


20

Saya memiliki konteks di mana saya perlu mengkonversi biner ke heksadesimal dan desimal dan sebaliknya dalam skrip shell. Dapatkah seseorang menyarankan saya alat untuk ini?


7
Melihat jawaban terakhir, mungkin Anda harus menentukan apakah "biner" berarti angka biner atau file biner .
manatwork

Jawaban:


39

Cukup mudah untuk melakukan konversi dari biner di bash murni ( echodan printfsudah builtin):

Biner ke desimal

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

Biner ke heksadesimal

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

Kembali ke biner menggunakan bash saja agak lebih kompleks, jadi saya sarankan Anda melihat jawaban lain untuk solusi untuk itu.


bagaimana dengan desimal hingga heksadesimal.
Bangi

2
@ Bangi Lakukan saja printf '%x\n' 10, misalnya.
Chris Down

1
Apa gunanya menggunakan printf %duntuk bin2dec? $(( ... ))sudah memberikan hasil desimal, echosudah cukup.
Andrea Corbellini

@AndreaCorbellini - Preferensi pribadi. Secara umum, saya menggunakan printf '%s\n' foobukan echokarena berbagai alasan (kebanyakan portabilitas), untuk alasan yang sama, saya tidak menggunakannya di sini.
Chris Down

@ ChrisDown: Saya pikir pertanyaan ini secara eksplisit tentang Bash (yang memiliki echobuiltin diimplementasikan dengan baik ). Salahku!
Andrea Corbellini

16

Dengan asumsi bahwa dengan biner, yang Anda maksud adalah data biner seperti dalam data dengan nilai byte yang mungkin termasuk 0, dan bukan angka dasar-2:

Untuk mengkonversi dari biner, od(standar), xxd(datang dengan vim) atau perl's unpackdatang ke pikiran.

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

Sekarang, untuk mengkonversi kembali ke biner, awk(standar), xxd -ratau perl's pack:

Dari output desimal dari od -tu1atau di perlatas:

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

Dari heksa perlatau di xxd -patas:

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

13

Anda dapat menggunakan bc untuk ini dengan memanipulasi ibasedan obaseparameter:

Kuncinya adalah bahwa Anda harus eksplisit tentang pangkalan. Jadi jika ibase Anda adalah 2, maka jika Anda menetapkan huruf ke 10, itu tidak akan melakukan apa-apa, karena 10 dalam biner adalah 2. Oleh karena itu Anda perlu menggunakan notasi heksadesimal.

Jadi biner ke desimal akan (perhatikan bahwa obase adalah A)

Biner ke desimal:

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

Biner ke hex:

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

Jika 'basis output' obasediubah terlebih dahulu, seharusnya lebih mudah:

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

6
Contoh kedua ini salah - 'F' akan menjadi basis 15, bukan 16 (desimal 16 dalam hex adalah 10, bukan F). Coba echo 'ibase=2;obase=F;1111yang harus sama dengan desimal 15, yaitu. F dalam hex Keluar sebagai 10, yang ada di basis 15 (digit 0-E). Hal ini juga lebih mudah jika Anda menyatakan obase yang pertama , misalnya: echo 'obase=16;ibase=2;1111'|bc. Tidak ada kebingungan.
goldilocks

2
Sekarang ini yang terburuk. Setelah Anda mengatur ibase, Anda harus memberikan masukan dalam yang dasar, bahkan untuk obase. Jadi, dalam contoh Anda akan echo 'ibase=2;obase=10000;11110001011010'|bc. Lebih baik mendengarkan saran goldilocks dan membalikkan urutan - set pertama obase, lalu ibase.
manatwork

3

Jika Anda bermaksud mengonversi angka dari basis-2 ke 10 atau 16 dan kembali, bcadalah alat standar untuk melakukannya seperti yang telah disebutkan oleh psarossy .

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

Beberapa shell seperti zshmemiliki dukungan bawaan untuk konversi basis sebagai bagian dari operator ekspansi aritmatika mereka:

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

dan seterusnya.

Keduanya ksh93dan zshjuga mendukung:

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

Tetapi perhatikan bahwa, ketika diperluas, $binaryakan memiliki 2#atau 16#awalan (yang dapat Anda strip dengan ${binary#*#}.

ksh93 juga mendukung:

printf "%..2d\n" 123

untuk mengkonversi ke biner.


1

Untuk penggunaan biner ke heksadesimal: alat xxd di linux dan untuk biner ke desimal Anda dapat menggunakan alat qalculate.

Untuk bantuan tentang tipe xxd xxd --helpatau man xxddi Linux.


1

Anda bisa menggunakan PHP:

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

Atau 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

Atau 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

Seperti yang disebutkan dalam jawaban sebelumnya Anda dapat melakukan Binary ke Decimal dan Hexa Decimal seperti berikut di Bash menggunakan echo dan printf. Saya hanya menambahkan di sini cara mengkonversi dari Desimal dan Hex ke biner menggunakan Bash murni.

Biner ke Desimal menggunakan gema

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

Biner ke Hexa-Desimal menggunakan printf

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

Bilangan bulat desimal ke konversi Biner hanya menggunakan Bash

Hanya menggunakan Bash, jika Anda ingin mengonversi desimal menjadi biner, Anda dapat melakukannya seperti berikut:

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

Dan kemudian salin dan tempel yang berikut ini:

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

Dan kemudian coba dari tempat Anda menyimpan:

./dec2bin 420
110100100

Integer harus ditambahkan !!

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

Konversi heksadesimal ke Biner hanya menggunakan Bash

Demikian pula, heksadesimal ke biner, sebagai berikut hanya menggunakan 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;

Sebagai contoh:

./hex2bin 1aF
110101111

Hex harus dilewati:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.