Fancy Tricks for Changing Numeric Base
In this article, I'm covering something that's a little abstruse: converting numeric bases within shell scripts. There are really four commonly used numeric bases to consider: binary, octal, decimal and hexadecimal. You're used to working in base-10, so 10 = 1 * 10**1 + 0 and 100 = 1 * 10**2 + 0 * 10**1 + 0.
That maps to other numeric bases, so 1010 base-2 or binary is really 1 * 2**3 + 0 * 2**2 + 1 * 2**1 + 0 or 8 + 0 + 2 + 0 = 10 decimal. Octal is the same thing, so 33 base-8 converts to decimal as 3 * 8**1 + 3 = 27.
Hexadecimal presents a different challenge because a base-16 numbering system doesn't fit neatly into our Arabic numerals 0, 1, 2, ... 9. "Hex", as it's known informally, adds A, B, C, D, E and F, so that the decimal value 10 is represented in Hex as "A". That's where the math gets interesting, so 33 base-16 = 3 * 16**1 + 3 = 48 + 3 = 51.
The long, complicated way to create a base conversion utility is therefore to disassemble every value given and apply the translation shown, then have an internal value that's a common base (probably base-10), then have another routine that converts the common base to the desired output base.
There are smarter ways to do this, as I'll discuss, but for now,
let's look at the
bc command, which supports users specifying both
the input and output numeric bases.
bc, the binary calculator, is a bit
tricky to work with as it's an old-school UNIX command. As I discuss
at length in my book Wicked Cool Shell Scripts, the most common way to
work with the crude but interactive
bc program is
echo to send
it the commands needed, as demonstrated here:
$ echo '333 * 0.35' | bc 116.55
Useful (particularly since
)) can't work with floats and
decimal values), but where this gets really interesting is with those
input and output numeric bases.
Let's say I want to confirm a conversion I listed earlier, by converting 33 hex into decimal. This is easily done:
$ echo 'ibase=16; 33' | bc 51
That's simple. Now, let's do something bigger and more complicated:
$ echo 'ibase=16; FEF33D9' | bc 267334617
ibase is the input numeric base. The output base is specified as
obase. And that's it—easy enough!
So let's take the same hex value as input but force the output to octal instead of the default decimal:
$ echo 'ibase=16; obase=8; FEF33D9' | bc 1773631731
Would you rather work in binary? You can do that too:
$ echo 'ibase=16; obase=2; FEF33D9' | bc 1111111011110011001111011001
That's a lot of ones and zeroes, for sure. It makes me think of Interstellar, but that's another article entirely!
Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.
|PasswordPing Ltd.'s Exposed Password and Credentials API Service||Apr 28, 2017|
|Graph Any Data with Cacti!||Apr 27, 2017|
|Be Kind, Buffer!||Apr 26, 2017|
|Preparing Data for Machine Learning||Apr 25, 2017|
|openHAB||Apr 24, 2017|
|Omesh Tickoo and Ravi Iyer's Making Sense of Sensors (Apress)||Apr 21, 2017|
- Graph Any Data with Cacti!
- Teradici's Cloud Access Platform: "Plug & Play" Cloud for the Enterprise
- The Weather Outside Is Frightful (Or Is It?)
- Simple Server Hardening
- Understanding Firewalld in Multi-Zone Configurations
- Server Technology's HDOT Alt-Phase Switched POPS PDU
- Gordon H. Williams' Making Things Smart (Maker Media, Inc.)
- IGEL Universal Desktop Converter
- A Switch for Your RPi