Nhị phân đến thập lục phân và thập phân trong tập lệnh shell


20

Tôi có một bối cảnh mà tôi cần chuyển đổi nhị phân thành thập lục phân và thập phân và ngược lại trong một tập lệnh shell. Ai đó có thể gợi ý cho tôi một công cụ cho việc này không?


7
Nhìn thấy những câu trả lời gần đây, có lẽ bạn nên xác định xem tập tin nhị phân của tập đoàn có nghĩa là số nhị phân hay tập tin nhị phân .
manatwork

Câu trả lời:


39

Thật đơn giản để thực hiện chuyển đổi từ nhị phân trong bash thuần ( echoprintflà nội trang):

Nhị phân đến thập phân

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

Nhị phân đến thập lục phân

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

Quay trở lại nhị phân bằng cách sử dụng bash một mình có phần phức tạp hơn, vì vậy tôi khuyên bạn nên xem các câu trả lời khác cho các giải pháp cho điều đó.


làm thế nào về thập phân đến thập lục phân.
Bangi

2
@Bangi Chỉ cần làm printf '%x\n' 10, ví dụ.
Chris Down

1
Điểm sử dụng printf %dcho bin2dec là gì? $(( ... ))đã cho một kết quả thập phân, echolà đủ.
Andrea Corbellini

@AndreaCorbellini - Sở thích cá nhân. Nói chung, tôi sử dụng printf '%s\n' foothay vì echonhiều lý do (chủ yếu là tính di động), vì lý do tương tự, tôi không sử dụng nó ở đây.
Chris Down

@ChrisDown: Tôi mặc dù câu hỏi này rõ ràng về Bash (có một echonội dung được triển khai tốt ). Lỗi của tôi!
Andrea Corbellini

16

Giả sử rằng theo nhị phân, bạn có nghĩa là dữ liệu nhị phân như trong dữ liệu với bất kỳ giá trị byte nào có thể bao gồm 0 và không phải là số cơ sở 2:

Để chuyển đổi từ nhị phân, od(tiêu chuẩn), xxd(đi kèm với vim) hoặc perl's unpackđến tâm.

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

Bây giờ, để chuyển đổi trở lại để nhị phân, awk(tiêu chuẩn), xxd -rhoặc perl's pack:

Từ đầu ra thập phân từ od -tu1hoặc perltrên:

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

Từ hexa perltrở xxd -plên:

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

13

Bạn có thể sử dụng bc cho việc này bằng cách thao tác ibaseobasetham số:

Bí quyết là bạn cần phải rõ ràng về các căn cứ. Vì vậy, nếu ibase của bạn là 2, thì nếu bạn đặt obase của mình thành 10, thì nó sẽ không làm gì cả, vì 10 trong nhị phân là 2. Do đó bạn cần sử dụng ký hiệu thập lục phân.

Vì vậy, nhị phân đến thập phân sẽ là (xem obase là A)

Nhị phân đến thập phân:

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

Nhị phân thành hex:

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

Nếu 'cơ sở đầu ra' obaseđược thay đổi trước tiên, nó sẽ dễ dàng hơn:

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

6
Ví dụ thứ hai này là sai - 'F' sẽ là cơ sở 15, không phải 16 (số thập phân 16 trong hex là 10, không phải F). Hãy thử echo 'ibase=2;obase=F;1111nên bằng chữ số thập phân 15, tức là. F trong hex. Nó xuất hiện là 10, nằm trong cơ sở 15 (chữ số 0-E). Nó cũng dễ dàng hơn nếu bạn nêu obase trước , ví dụ : echo 'obase=16;ibase=2;1111'|bc. Không nhầm lẫn.
goldilocks

2
Bây giờ nó là tồi tệ nhất. Khi bạn đặt ibase, bạn phải cung cấp đầu vào trong cơ sở đó , thậm chí cho obase. Vì vậy, trong ví dụ của bạn sẽ là echo 'ibase=2;obase=10000;11110001011010'|bc. Tốt hơn hãy lắng nghe lời khuyên của goldilocks và đảo ngược trật tự - đầu tiên obase, sau đó ibase.
manatwork

3

Nếu bạn có nghĩa là chuyển đổi số từ cơ sở 2 sang 10 hoặc 16 và trở lại, bclà công cụ tiêu chuẩn để làm điều đó như đã được đề cập bởi psarossy .

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

Một số shell như zshđã hỗ trợ dựng sẵn để chuyển đổi cơ sở như là một phần của toán tử mở rộng số học của chúng:

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

vân vân

Cả hai ksh93zshcũng hỗ trợ:

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

Nhưng lưu ý rằng, khi được mở rộng, $binarysẽ có một 2#hoặc 16#tiền tố (mà bạn có thể thoát ra ${binary#*#}.

ksh93 cũng hỗ trợ:

printf "%..2d\n" 123

để chuyển đổi thành nhị phân.


1

Đối với sử dụng nhị phân đến thập lục phân: xxd công cụ trong linux và đối với nhị phân sang thập phân, bạn có thể sử dụng công cụ qalculate.

Để được trợ giúp về loại xxd xxd --helphoặc man xxdtrong Linux.


1

Bạn có thể sử dụng PHP:

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

Hoặc 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

Hoặc 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

Như đã đề cập trong câu trả lời trước, bạn có thể thực hiện Binary to Decimal và Hexa Decimal như sau trong Bash bằng echo và printf. Tôi chỉ thêm vào đây cách chuyển đổi từ Decimal và Hex sang nhị phân bằng Bash thuần túy.

Nhị phân đến số thập phân sử dụng echo

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

Nhị phân đến Hexa-Decimal bằng printf

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

Số nguyên thập phân sang chuyển đổi nhị phân chỉ sử dụng Bash

Chỉ sử dụng Bash, nếu bạn muốn chuyển đổi thập phân thành nhị phân, bạn có thể làm như sau:

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

Và sau đó sao chép và dán như sau:

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

Và sau đó thử nó từ nơi bạn đã lưu:

./dec2bin 420
110100100

Số nguyên phải được thêm vào !!

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

Chuyển đổi hệ thập lục phân sang nhị phân chỉ sử dụng Bash

Tương tự, thập lục phân thành nhị phân, như sau chỉ sử dụng 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;

Ví dụ:

./hex2bin 1aF
110101111

Hex phải được thông qua:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.