Shell脚本中的二进制到十六进制和十进制


20

我有一个上下文,需要在shell脚本中将二进制转换为十六进制和十进制,反之亦然。有人可以建议我使用此工具吗?


7
看到最近的答案,也许您应该指定“ binary”是二进制数还是二进制文件
manatwork

Answers:


39

它相当简单做转换二元纯庆典(echoprintf是建宏):

二进制到十进制

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

二进制到十六进制

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

仅使用bash返回二进制文件会稍微复杂一些,因此我建议您查看其他解决方案。


十进制到十六进制如何。
Bangi

2
@Bangi printf '%x\n' 10例如,做。
克里斯·

1
printf %d对bin2dec 使用有什么意义?$(( ... ))已经给出了十进制结果,echo就足够了。
Andrea Corbellini

@AndreaCorbellini-个人喜好。通常,出于各种原因(主要是可移植性),我使用printf '%s\n' foo代替echo,出于相同的原因,我在这里不使用它。
克里斯·

@ChrisDown:我虽然这个问题明确地与Bash有关(它具有echo内置的良好实现的)。我的错!
Andrea Corbellini

16

假设以二进制表示,则是指二进制数据与具有任何可能的字节值(包括0而不是基数2)的数据一样:

转换二进制od(标准), xxd(自带vim)或perlunpack浮现在脑海中。

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

现在,转换回二元,awk(标准),xxd -rperlpack

从十进制输出od -tu1perl以上:

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

从6进perlxxd -p以上:

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

13

您可以通过操作ibaseand obase参数来使用bc :

诀窍是您需要明确说明基础。因此,如果您的ibase是2,那么如果将obase设置为10,它将不会执行任何操作,因为二进制中的10是2。因此,您需要使用十六进制表示法。

因此二进制将是十进制(请注意,obase是A)

二进制到十进制:

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

二进制到十六进制:

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

如果obase首先更改“输出基础” ,则应该更容易:

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

6
第二个示例是错误的-'F'将以15为底,而不是16(十六进制的16进制是10,而不是F)。尝试echo 'ibase=2;obase=F;1111哪个等于十进制15,即。F(十六进制)。它以10表示,以15为底(数字0-E)。如果声明状态,则也更容易,例如:echo 'obase=16;ibase=2;1111'|bc。不会造成混乱。
goldilocks

2
现在最糟糕了。设置好之后ibase,您必须在基础上提供输入,甚至对于obase。因此,在您的示例中将是echo 'ibase=2;obase=10000;11110001011010'|bc。最好听听goldilocks的建议并颠倒顺序-首先设置obase,然后设置ibase
manatwork

3

如果要将数字从base-2转换为10或16再转换回来,bc则是psarossy提到的执行此操作的标准工具。

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

诸如此类的某些Shell zsh已将对基本转换的内置支持作为其算术扩展运算符的一部分:

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

等等。

双方ksh93zsh还支持:

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

但请注意,展开时,$binary将带有2#16#前缀(您可以使用前缀)${binary#*#}

ksh93 还支持:

printf "%..2d\n" 123

转换为二进制。


1

对于二进制到十六进制使用:Linux中的xxd工具,对于二进制到十进制,可以使用qalculate工具。

有关xxd类型xxd --helpman xxd在Linux中的帮助。


1

您可以使用PHP:

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

或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

或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

如前面的答案中所述,您可以使用echo和printf在Bash中按以下方式进行Binary to Decimal和Hexa Decimal。我只是在这里添加如何使用纯Bash从十进制和十六进制转换为二进制。

从二进制到十进制

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

使用printf二进制到十六进制十进制

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

仅使用Bash将整数从十进制转换为二进制

仅使用Bash,如果您想将十进制转换为二进制,则可以执行以下操作:

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

然后复制并粘贴以下内容:

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

然后从保存的位置尝试:

./dec2bin 420
110100100

必须添加整数!

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

仅使用Bash将十六进制转换为二进制

同样,从十六进制到二进制,仅使用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;

例如:

./hex2bin 1aF
110101111

十六进制必须通过:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.