BASH base conversion from decimal to hex
Solution 1
With bash
(or any shell, provided the printf
command is available (a standard POSIX command often built in the shells)):
printf '%x\n' 85
With zsh
, you can also do:
dec=85
hex=$(([##16]dec))
That works for bases from 2 to 36 (with 0-9a-z
case insensitive as the digits).
$(([#16]dev))
(with only one #
) expands to 16#55
or 0x55
(as a special case for base 16) if the cbases
option is enabled (also applies to base 8 (0125
instead of 8#125
) if the octalzeroes
option is also enabled).
With ksh93
, you can use:
dec=85
base54=${ printf %..54 "$dec"; }
Which works for bases from 2 to 64 (with 0-9a-zA-Z@_
as the digits).
With ksh
and zsh
, there's also:
$ typeset -i34 x=123; echo "$x"
34#3l
Though that's limited to bases up to 36 in ksh88, zsh and pdksh and 64 in ksh93.
Note that all those are limited to the size of the long
integers on your system (int
's with some shells). For anything bigger, you can use bc
or dc
.
$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF
With supported bases ranging from 2 to some number required by POSIX to be at least as high as 99. For bases greater than 16, digits greater than 9 are represented as space-separated 0-padded decimal numbers.
$ echo 'obase=30; 123456' | bc
04 17 05 06
Or same with dc
(bc
used to be (and still is on some systems) a wrapper around dc
):
$ echo 30o123456p | dc
04 17 05 06
Solution 2
Use printf:
$ printf "%d %x\n" $((16#55)) $((10#85))
85 55
To assign the value to a variable use command substitution:
$ x=$( printf "%x" 85 ) ; echo $x
55
Solution 3
Use the built-in Arithmetic Expansion substitution present in all POSIX compliant shells - which is pretty much universal these days.
$ echo $((0xbc))
188
and
$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005
CAUTION: Particularly in the last example the expansion could cause unexpected results - the hex digits in the variable 'hex' have to form a legal hex constant, otherwise potentially obscure error messages happen. e.g. if 'hex' were '0xdead', the arithmetic expansion would become 0x0xdead, which is not interpretable as a constant. Of course, in that case the arithmetic expansion $(($hex)) would do the trick. It is left as an exercise for the reader to create the simple substring processing pattern matching that would remove an optional '0x' prefix.
Related videos on Youtube
Dave Rove
Updated on September 18, 2022Comments
-
Dave Rove over 1 year
In Bash, how does one do base conversion from decimal to another base, especially hex. It seems easy to go the other way:
$ echo $((16#55)) 85
With a web-search, I found a script that does the maths and character manipulation to do the conversion, and I could use that as a function, but I'd have thought that bash would already have a built-in base conversion -- does it?
-
Ciro Santilli Путлер Капут 六四事 about 7 years
-
-
Dave Rove about 9 yearsThanks. Exactly what I was looking for. (And embarrassingly simple.)
-
Angel Todorov about 9 yearsOr, use the
-v
option for the builtin printf:printf -v foo "%d" $((16#BEEF)); echo $foo
-
Janis about 9 years@Glenn Using non-standard options (like
-v
) is unnecessary here; I'd avoid it. -
Angel Todorov about 9 years@StéphaneChazelas, wait a minute. Are you saying that ksh93 does not fork for
x=$(some_builtin)
? -
Janis about 9 years@Stephane That's correct. Though, the
#
numeric base indicator is at least supported by all the prominent shells. And for the hex-conversion in this case it's not necessary, as shown in my answer:x=$( printf "%x" 85 )
-
Janis about 9 years@Glenn, yes ksh has a lot optimization built in, that'a why it's often a magnitue faster than bash.
-
Thomas Guyot-Sionnest about 8 yearsYou're doing the exact same thing the OP did in his example; he's looking for the reverse operation.
-
flarn2006 over 7 yearsWhat if you want to do an arbitrary base like you can specify with
#
? -
Stéphane Chazelas over 7 years@flarn2006. With
bash
builtins, you can input numbers in any base, but not output in any base other than 8, 10 and 16. For other bases, you'd need another shell likezsh
orksh
or usebc/dc
. -
flarn2006 over 7 years@StéphaneChazelas Really? That's kind of weird. It almost seems like they were too lazy to program in a syntax for it or something; there's no way the idea of outputting in any base didn't cross their minds if they implemented inputting.
-
mwfearnley over 4 years
alias hex="printf '%x\n'"