Octal, Hexadecimal, And Decimal Conversion
Perl offers a variety of ways to convert numbers from one form to another (remember, "There’s More Than One Way To Do It").
For example, if $num contains a number and you want the octal (base 8) value of that number, you can use printf or sprintf:
$num = 42;
printf("%o", $num);
$oct = sprintf("%o", $num);
(Note: you can control the number of digits output by any printf or sprintf formatting code simply by inserting a number. For example, use "%04o" to produce a 4-digit octal number: the 0 means to add zeroes to the front if the number would be less than 4 digits; "%4o" would add spaces instead of zeroes.)
To go from octal to decimal, use the hex() function:
$num = oct($oct);
Hexadecimal numbers work much the same way. Use "%x" for printf or sprintf:
printf("%x", $num);
$hex = sprintf("%x", $num);
(Note: use "%X" if you want any letters to be in uppercase.)
But there are two ways to convert hexadecimal numbers to decimal: the oct() function will handle hexadecimal values if they start with "0x", or you can use hex():
$num = hex($hex);
$num = oct("0x" . $hex);
What about binary (base 2)? You can use printf or sprintf with %b…
printf("%b", $num);
$bin = sprintf("%b", $num);
But there’s no bin() function in Perl. You have to use oct() with a "0b" prefix:
$num = oct("0b" . $bin);

Hello,
Thank you for the helpful page. I’d like to contribute my 0.2 cents.
Sometimes you to format with leading 0s, e.g. when encoding URLs,
you need x0A rather than xA. For those cases you can use “%0numberx”
instead of “%0x” as the format string, and the sprintf will fill in
the necessary number of zeroes to make sure that the resulting string
is the specified number of characters.
Here’s how we could use this to encode strings for URLs:
perl -pe ’s/([^a-zA-z])/”\%” . sprintf(”%02x”,ord($1))/eg’
You could use it to send files as thunderbird emails from command line:
cat email.txt | perl -pe ’s/([^a-zA-z])/”\%” . sprintf(”%02x”,ord($1))/eg’ | xargs -iX thunderbird -compose ‘mailto:somebody@nowhere.net?subject=PerlHack&body=X’
Hope this would be helpful to someone.
-umut
Comment by Umut Topkara — January 29, 2006 @ 6:39 pm
Yes, I mentioned that above (the “%04o” example) but you explained it better. Thanks!
Comment by William Ward — January 29, 2006 @ 10:26 pm
Nice piece of work. Exactly what I wanted.
Comment by Praneel — October 2, 2006 @ 6:15 pm
Thanks a lot to William Ward & Umut Topkara
This conversion had helped me a lot…
Comment by bharat — December 26, 2007 @ 4:02 pm
> But there’s no bin() function in Perl. You have to use oct() with a “0b” prefix:
> $num = oct(”0b” . $bin);
And how exactly does that replace “bin()” (you know it’s converting binary to octal right)?
Comment by saurabh — April 14, 2008 @ 8:39 am
Oh sorry, never mind. oct converts from octal, i thought it was the string representation in octal of its arg.
Comment by saurabh — April 14, 2008 @ 8:41 am
to convert a decimal number into binary it’s just even more easy: use UNPACK!!
for example:
$number=5;
print unpack “B8″, $number;
will output:
00000101
Comment by makjander — July 7, 2008 @ 11:45 pm
That doesn’t work the way you say. Did you run it?
When I run your program I get “00110101″ instead. Pack and unpack work on character strings, so 5 is really the string “5″ and 00110101 is the ASCII code for the “5″ character.
Comment by William Ward — July 8, 2008 @ 8:28 am
oops… hehe… i’ve run it now and see what you say it outputs, i’ve didn’t tested before
but you can change it using a workaround:
$number=5;
print unpack “B8″, (pack “J”, $number);
Comment by makjander — July 8, 2008 @ 9:42 am
I think (s)printf is probably a lot more readable than using pack and unpack, though I suspect yours may be faster.
Comment by William Ward — July 8, 2008 @ 11:47 am