45

I'm looking for an easy way in Bash to convert a decimal number into a binary number. I have variables that need to be converted:

$ip1 $ip2 $ip3 $ip4

Is there a simple method to do this without looking at every individual number?

I would prefer not to have to write a lot of code.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Daniel Del Core
  • 3,071
  • 13
  • 38
  • 52

9 Answers9

85

You can use bc as:

echo "obase=2;$ip1" | bc

See it

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • At the moment i have echo "obase=2;$ip1" | bc echo "obase=2;$ip2" | bc echo "obase=2;$ip3" | bc echo "obase=2;$ip4" | bc and the echo each line is outputing a newline. is there a way to have it output tip to tail – Daniel Del Core Apr 23 '12 at 10:22
  • 2
    @DanielDC: You can do: `echo "obase=2;10;20;30" | bc | tr -d '\n'` – codaddict Apr 23 '12 at 10:26
  • @DanielDC: Add a `| tr -d '\n'` at the end. – codaddict Apr 23 '12 at 10:33
  • lol i totally forgot the | tr -d '\n' thanks heaps for your help man appreciate it – Daniel Del Core Apr 23 '12 at 10:37
  • 8
    Great solution; a slightly more compact (and marginally better-performing) version is: `bc <<<"obase=2;$ip1"`. – mklement0 Jul 27 '12 at 20:56
  • This is a great solution. The explanation is that `bc` is a calculator which accepts input from stdin. In this case, the input is the string to set the base of the output to 2 (presumable the default input is base 10), and then just echo the number in the "ip1" variable. The <<< is just a quick way to pass a string or variable to somethings stdin (ie. it is equivelent to `echo "obase=2;$ip1" | bc` (but presumably preferred since it eliminates the call to echo). A more straightforward example of `bc` adding two and two is `bc <<<"2+2"`. – Casey Apr 22 '18 at 16:12
  • 3
    In case you're looking for the reversal process, ie binary to decimal, here you go `echo $((2#$@))` where $@ is your binary number. – Paul Razvan Berg Jun 22 '18 at 14:42
  • How do you specify the number of digits? – Gabriel Staples Mar 22 '22 at 07:00
  • I asked that question here: [How to make `bc` output a desired number of base-2 binary digits](https://stackoverflow.com/q/71568169/4561887) – Gabriel Staples Mar 22 '22 at 07:18
60

Convert decimal to binary with bash builtin commands (range 0 to 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


To remove leading zeros, e.g. from ${D2B[7]}:

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

111


This creates an array with 00000000 00000001 00000010 ... 11111101 11111110 11111111 with bash‘s brace expansion. The position in array D2B represents its decimal value.

See also: Understanding code ({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • 3
    Very nice pure bash solution! To generalize this for range 0 to 2^n-1, use `eval D2B='('$(for ((i=0; i<$n; i++)); do printf '%s' "{0..1}"; done)')'` (after setting `n`). The only drawback is that this method takes O(2^n) space (superpolynomial!). This quickly draws unwieldy. – Malte Skoruppa Sep 25 '14 at 00:34
  • Incredible tight solution! Can you explain what happens? What does `{0..1}` ? – domih Oct 19 '17 at 22:31
  • The output of `echo $D2B` is `00000000` which was confusing me, as this does not look like an array but a simple string. Thank you for enlightening me! – domih Oct 20 '17 at 06:58
  • 3
    @domih: Here `D2B` is an array. I do not recommend using `$D2B` because it is intended to display strings. To access the first element of an array use `${D2B[0]}`. – Cyrus Oct 20 '17 at 17:32
  • simple example to help understand: `a=({0..1}{2..3}); echo ${a[@]}`. The `echo` statement prints `a` for all indices. – Wolfson Jan 16 '23 at 19:34
  • This is really cool, but won't this blow up in memory because it allocates the entire array? – bjd2385 Feb 28 '23 at 17:40
  • @bjd2385: Memory consumption is kept within limits with this small array. This shows the complete array: `echo {0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}` – Cyrus Feb 28 '23 at 17:48
  • @Cyrus but if I tried this option with a 4 byte arrangement, e.g. to represent an IP address in base 10 for a lookup...it seems to crash my terminal. Very cool though! There are other methods of accomplishing that though to get around this. – bjd2385 Feb 28 '23 at 17:58
  • @bjd2385: With more digits the array scales very quickly. – Cyrus Feb 28 '23 at 18:03
  • I never known `Brace Expansion` can do multi-dimensional orthogonal. very impressive!! – yurenchen Apr 16 '23 at 15:42
  • the magic of `Brace Expansion` x `Array`. you are a bash artist – yurenchen Apr 16 '23 at 15:49
6

Decimal to binary conversion in Bash:

I'm using Ubuntu 14.04 to do this.

Convert the decimals 1 through 5 to binary.

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

Bonus example:

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

el@apollo:~$ bc <<< "obase=2;2^128"
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
4

I like to use dc for this. It's very concise:

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

The commands here are as follows:

  1. Push the number, n, on the stack, via shell expansion.
  2. Push 2 on the stack, then use o to pop the stack and use 2 as the output radix.
  3. p to print the top of the stack (which is just n), using the output radix set in step 2 (so print in binary).

If you want padding:

$ n=50; pad_size=16; printf "%0${pad_size}d\n" $(dc -e "$n 2op")
0000000000110010
Victor Zamanian
  • 3,100
  • 24
  • 31
3

General method for converting an integer number into another representation with another base (but base<=10 because of using digits 0..9 for representation, only):

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
}

e.g.

convertIntvalToBase $ip1 2     # converts $ip1 into binary representation
3

Defined as a function in bash:

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

To make @codaddict's answer a little more pretty, use this to prefix the output with 0b for "binary":

printf "0b%s\n" "$(echo "obase=2; $((num1 + num2))" | bc)"

Example:

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

Output:

0b101110

This is decimal 46.

For details on the input base-2 formatting in bash, such as 2#1111 above, see the very end of my answer here: How to use all bash operators, and arithmetic expansion, in bash.

To have at least 8 digits in the output, use:

printf "0b%08d\n" $(echo "obase=2; $((num1 + num2))" | bc)

Source: David Rankin, in an answer to my question here.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
0

Decimal to Binary using only Bash

Any integer number can be converted ti binary using it::

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

And, then copy paste the following:

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

For example:

./dec2bin.bash $var
110100100

Integer must be added!!

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

Also, another way using python: Much slower

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

Hexadecimal to Binary using only Bash

Similarly, hexadecimal to binary, as follows using only 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;

For example:

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

Hex must be passed:

./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!
Rakib Fiha
  • 473
  • 8
  • 13
0
toBin ()
{
    printf "%08d\n" $(dc -e "$1 2op")
}


$ toBin 37
00100101
Zibri
  • 9,096
  • 3
  • 52
  • 44