Bash has an interesting builtin feature to convert from any base to decimal, which is a part of bash’s arithmetic evaluation features. In this post i will quickly introduce you with this feature.

### Arithmetic Expansion

To allow arithmetic evaluation of an expression and substitution of the result bash has the following construct.

```\$((expression))
```

For example

```echo \$((2 + 5))
```

The above will evaluate the expression 2 + 5 substitute with the result, which will be displayed by echo.

### Any to decimal conversion

Now to come to the point. Consider the following construct.

```echo \$((2#1010))
```

This will print out 10 , that is the decimal equivalent of the binary (base 2) 1010 . The general construct is:

```echo \$((base#number))
```

Where the base is the value of the base in which the number is in. The value of base can be from 2 upto 64. After 10 base first lower case characters are used to represent additional base digits, when the base value is greater than 32 upper case characters are used. In the case of base value 63 and 64, the 63rd and 64th digit of the base are the @ and _ symbols respectively.

Also to represent hexadecimal you can start the hex number by 0x or 0X, and to denote an octal number you can start the number with 0 as normal. Like

```echo \$((0xa))
echo \$((012))
```

Both of these will print out 10, which is the decimal equivalent of 0xa in hex and 012 in octal.

The same can be achieved by

```echo \$((16#a))
echo \$((8#12))
```

At last for completeness i should also add that without any of the 0x, or 0 appended or the base#number format, plain integers are considered to be in decimal, ie. in base 10 by default.

Although you can only convert any integer base (within 2 and 64, both inclusive) to decimal, and not other base, this can come in handy.

### References

1. man bash ARITHMETIC EVALUATION section

## 8 thoughts on “Builtin Bash any base to decimal conversion”

1. Timothy Tucker says:

Very very cool man! I was just reading the bash man page on the ((expression)) section and I really could not think of much use of it. This is super awesome info as I was going to write a C app to do this myself if it didn’t exist.

2. varlogtim says:

I guess I just had not read enough – I didn’t make it to “The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION.

1. varlogtim says:

So, my other comment didn’t appear… Basically I just wanted to say thanks for making this blog post. It is very very cool information – I was going to write a C app to do this if linux didn’t already. You are one of the keyboard cowboys. Rock on man!

1. phoxis says:

Nice to know that this information helped you. If there are other problems, you might not need to write a C program to solve it and then use it with bash. You can checkout the ‘bc’ program which will fulfill all the required math operations.

Thank you very much for stopping by!

3. femalefaust says:

THANK YOU SO MUCH! i was searching for a simple base64 to base10 conversion via cl…. but — is there a way to reverse the function that is as simple?

1. phoxis says:

You can always use the base64 tool to encode and decode. Although throuhgh command line, if you do as follows echo -n “10” | base64 it will encode the string “10” to the base 64. Therefore possibly if you write a program which dumps the decimal number to stdout and then use base64 it should work. For example

```#include <stdio.h>
#include <unistd.h>

int main (void)
{
unsigned int a;
scanf (" %d", &a);
write (1, &a, sizeof (int));

return 0;
}
```

Let’s name the executable for this code a.out. Then

```echo "10" | ./a.out | base64
# This will output the base64 for decimal 10

echo "65" | ./a.out | base64
# This will output the base64 for decimal 65  (ASCII for character 'A')
```

To decode just use the decimal number to decode and pipe into base64 –decode

Let me know if this helps.

4. zibri says:

The base64 is NOT a number conversion in base64.
This is a common mistake.
Proof:
echo -n “1000” | base64 -d # 1000 in base 64 is: 262144
�M4

Got it?
Counterproof:
echo \$((64#1000))
262144

1. phoxis says:

True, but in your example the “1000” is a string, therefore it does not represent the integer 1000, but the string “1000”.