Bash shell 十进制转二进制(基数为2)的转换

45

我正在寻找一种在Bash中将十进制数转换为二进制数的简单方法。我有需要被转换的变量:

$ip1 $ip2 $ip3 $ip4

有没有一种简单的方法可以在不查看每个单独数字的情况下完成这个任务?

我不想写很多代码。

9个回答

86
你可以使用bc来实现:
echo "obase=2;$ip1" | bc

查看它


目前我有以下代码: echo "obase=2;$ip1" | bc echo "obase=2;$ip2" | bc echo "obase=2;$ip3" | bc echo "obase=2;$ip4" | bc每个echo语句都会输出一个新行。是否有一种方法可以让它们从头到尾输出? - Daniel Del Core
2
@DanielDC:你可以这样做:echo "obase=2;10;20;30" | bc | tr -d '\n' - codaddict
8
更紧凑且性能略微更好的优秀解决方案是:bc <<<"obase=2;$ip1"。该命令可以将变量 ip1 转换为二进制并输出。 - mklement0
3
如果您正在寻找反转过程,即二进制转十进制,请使用以下命令:echo $((2#$@)),其中$@是您的二进制数。 - Paul Razvan Berg
你如何指定数字的位数? - Gabriel Staples
显示剩余4条评论

60

使用bash内置命令将十进制转换为二进制(范围为0到255):

D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})

echo ${D2B[7]}

00000111

echo ${D2B[85]}

01010101

echo ${D2B[127]}

01111111


为了去除前导零,例如从 ${D2B[7]} 中:

echo $((10#${D2B[7]}))

这使用bash的花括号扩展创建了一个数组,其中包含00000000 00000001 00000010 ... 11111101 11111110 11111111。数组D2B中的位置表示它的十进制值。

另请参阅:理解代码 ({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})


3
非常好的纯Bash解决方案!为了将其推广到0到2^n-1范围,使用eval D2B='('$(for ((i=0; i<$n; i++)); do printf '%s' "{0..1}"; done)')'(在设置n后执行)。唯一的缺点是该方法需要O(2^n)的空间(超多项式级别!)。这很快变得难以处理。 - Malte Skoruppa
echo $D2B 的输出是 00000000,这让我感到困惑,因为它看起来不像一个数组,而是一个简单的字符串。谢谢你给我启示! - domih
3
在这里,D2B是一个数组。我不建议使用$D2B,因为它旨在显示字符串。要访问数组的第一个元素,请使用${D2B[0]} - Cyrus
一个简单的例子帮助理解:a=({0..1}{2..3}); echo ${a[@]}echo语句打印出所有索引的a - Wolfson
@bjd2385:使用这个小数组可以保持内存消耗在限制范围内。以下是完整的数组:echo {0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1} - Cyrus
显示剩余7条评论

6

Bash中十进制转二进制:

我使用Ubuntu 14.04进行操作。

将1至5的十进制数转换为二进制。

el@apollo:~$ bc <<< "obase=2;1"
1
el@apollo:~$ bc <<< "obase=2;2"
10
el@apollo:~$ bc <<< "obase=2;3"
11
el@apollo:~$ bc <<< "obase=2;4"
100
el@apollo:~$ bc <<< "obase=2;5"
101

额外示例:

el@apollo:~$ bc <<< "obase=2;1024"
10000000000

el@apollo:~$ bc <<< "obase=2;2^128"
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

4

我喜欢使用dc来完成这个任务。它非常简洁:

$ n=50; dc -e "$n 2op"
110010

这里的命令如下:
  1. 通过shell扩展将数字 n 推送到栈上。
  2. 在栈上推入2,然后使用 o 弹出栈并将2用作输出基数。
  3. p 打印栈顶部(即 n),使用步骤2中设置的输出基数进行打印(因此以二进制形式打印)。

如果您需要填充:

$ n=50; pad_size=16; printf "%0${pad_size}d\n" $(dc -e "$n 2op")
0000000000110010

3

在bash中定义为一个函数:

# to Binary:
toBinary(){
    local n bit
    for (( n=$1 ; n>0 ; n >>= 1 )); do  bit="$(( n&1 ))$bit"; done
    printf "%s\n" "$bit"
}

使用 printf "%s\n" "$bit" 而不是仅仅使用 echo $bit 的原因是什么? - Victor Zamanian
1
很多原因。请阅读为什么printf比echo更好? - user8017719
额,是的,我想这足够引人入胜了。 - Victor Zamanian

3

将整数转换为另一种表示形式的通用方法,使用另一种基数进行表示(但由于使用数字0..9进行表示,因此基数<=10):

function convertIntvalToBase () # (Val Base)
{
   val=$1
   base=$2
   result=""
   while [ $val -ne 0 ] ; do
        result=$(( $val % $base ))$result #residual is next digit
        val=$(( $val / $base ))
   done
   echo -n $result
}

例如

convertIntvalToBase $ip1 2     # converts $ip1 into binary representation

1
@codaddict的答案更漂亮一点,使用以下代码在输出前加上0b表示"二进制":
printf "0b%s\n" "$(echo "obase=2; $((num1 + num2))" | bc)"

例子:

num1=2#1111  # binary  1111 (decimal 15)
num2=2#11111 # binary 11111 (decimal 31)
printf "0b%s\n" "$(echo "obase=2; $((num1 + num2))" | bc)"

输出:

0b101110

这是十进制数46。
关于bash中的二进制格式,如上面的2#1111,请参见我的答案末尾:如何在bash中使用所有bash运算符和算术展开
要输出至少8个数字,请使用:
printf "0b%08d\n" $(echo "obase=2; $((num1 + num2))" | bc)

来源:David Rankin,在此处回答我的问题。

0
toBin ()
{
    printf "%08d\n" $(dc -e "$1 2op")
}


$ toBin 37
00100101

0

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

任何整数都可以使用以下方法转换为二进制:

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

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

#!/bin/bash
num=$1;
dec2bin()
{
    op=2; ## Since we're converting to binary
    quo=$(( $num/ $op)); ## quotient
    rem=$(( $num% $op)); ## remainder
    array=(); ## array for putting remainder inside array
    array+=("$rem"); ## array expansion
        until [[ $quo -eq 0 ]]; do
            num=$quo; ## looping to get all remainder, untill the remainder is 0
            quo=$(( $num / $op));
            rem=$(( $num % $op));
            array+="$rem"; ## array expansion
        done
    binary=$(echo "${array[@]}" | rev); ## reversing array
    printf "$binary\n"; ## print array
}
main()
{
[[ -n ${num//[0-9]/} ]] &&
    { printf "$num is not an integer bruv!\n"; return 1;
    } || { dec2bin $num; }
}
main;

例如:

./dec2bin.bash $var
110100100

必须添加整数!!

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

另外,还有一种用Python的方法: 速度要慢得多

python -c "print(bin(420))"
0b110100100

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

同样,只需使用Bash即可将十六进制转换为二进制,如下所示:

#!/usr/local/bin/bash ## For Darwin :( higher bash :)
#!/bin/bash ## Linux :)
hex=$1;
hex2bin()
{
    op=2; num=$((16#$hex));
    quo=$(( $num/ $op));
    rem=$(( $num% $op));
    array=();
    array+=("$rem");
        until [[ $quo -eq 0 ]]; do
            num=$quo;
            quo=$(( $num / $op));
            rem=$(( $num % $op));
            array+="$rem";
        done
    binary=$(echo "${array[@]}" | rev);
    printf "Binary of $1 is: $binary\n";
}
main()
{
[[ -n ${hex//[0-9,A-F,a-f]/} ]] &&
    { printf "$hex is not a hexa decimal number bruv!\n"; return 1;
    } || { hex2bin $hex; }
}
main;

例如:

./hex2bin.bash 1aF
Binary of 1aF is: 110101111

必须传递十六进制:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接