Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a
virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month.
Click here for more info.
07-02-2008, 01:11 PM
#1
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Rep:
How Can I convert Hex to Binary in a perl script
I'm attempting to write a script that will convert a stream of Hex to a stream of binary using Perl.
I've found a number of code examples such as this:
Code:
%h2b = (0 => "0000",
1 => "0001", 2 => "0010", 3 => "0011",
4 => "0100", 5 => "0101", 6 => "0110",
7 => "0111", 8 => "1000", 9 => "1001",
a => "1010", b => "1011", c => "1100",
d => "1101", e => "1110", f => "1111",
);
$hex = "414243";
($binary = $hex) =~ s/(.)/$h2b{lc $1}/g;
print $binary, "\n";
But they are static and seem awfully convoluted to get a result, isn't there a function similar to "bc" at the shell, that can convert a piped "|" input.
07-02-2008, 01:18 PM
#2
Member
Registered: May 2004
Location: Raleigh, NC
Distribution: Debian, Solaris, HP-UX, AIX
Posts: 208
Rep:
07-02-2008, 01:24 PM
#3
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
Quote:
Originally Posted by
0.o
Thanks but that's way past my programing ability, I'm just starting to learn perl.
What I'm trying to do is take an input stream similar to this:
Code:
f6f6f628282801020300
9c3c045f3059edeae18c
8c000000000000000000
0000000055045f3059ed
33ff3700000000000000
d19c3c045f3059edeae1
00000000000000000000
b371aad19c3c045f3059
00000000000000000000
And convert it to it's binary equivalent in the same format.
07-02-2008, 02:20 PM
#4
Senior Member
Registered: Jul 2004
Distribution: Ubuntu 7.04
Posts: 1,994
Rep:
07-02-2008, 02:20 PM
#5
Senior Member
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780
Code:
#!/bin/bash
echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g')
07-02-2008, 02:51 PM
#6
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
Quote:
Originally Posted by
ntubski
Code:
#!/bin/bash
echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g')
That does some interesting stuff but not what I was expecting. Instead I get the following:
Code:
$ cat hex.txt
f6f6f628282801020300
9c3c045f3059edeae18c
8c000000000000000000
0000000055045f3059ed
33ff3700000000000000
d19c3c045f3059edeae1
00000000000000000000
b371aad19c3c045f3059
00000000000000000000
$ cat hex.txt | ./scripts/hex2bin.sh > hexout.txt
$ cat hexout.txt
���(((^A^B^C^@�<^D_0Y��ጌ^@^@^@^@^@^@^@^@^@^@^@^@^@U^D_0Y파3�7^@^@^@^@^@^@^@ќ<^D_0Y휌꜌ᜌ^@^@^@^@^@^@^@^@^@^@�q�ќ<^D_0Y^@^@^@^@^@^@^@^@^@^@
??
07-02-2008, 04:38 PM
#7
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
Quote:
Originally Posted by
ntubski
Code:
#!/bin/bash
echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g')
I'm trying to do it slightly more manually as a bash case statement with output like this:
Code:
while read VALUE; do
case "$VALUE" in
0) echo "0000";;
1) echo "0001";;
2) echo "0010";;
3) echo "0011";;
4) echo "0100";;
5) echo "0101";;
6) echo "0110";;
7) echo "0111";;
8) echo "1000";;
9) echo "1001";;
A) echo "1010";;
B) echo "1011";;
C) echo "1100";;
D) echo "1101";;
E) echo "1110";;
F) echo "1111";;
a) echo "1010";;
b) echo "1011";;
c) echo "1100";;
d) echo "1101";;
e) echo "1110";;
f) echo "1111";;
esac
done
However when I feed it an input like (f5) it reads it literally as the string f5 instead of the individual (f)and(5).
07-02-2008, 04:53 PM
#8
Senior Member
Registered: Jun 2008
Posts: 2,529
Rep:
Try man od
07-02-2008, 04:54 PM
#9
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
I got it work! Go me!
The following does the trick:
Code:
#!/usr/bin/perl
$/ = '';
%h2b = (0 => "0000",
1 => "0001", 2 => "0010", 3 => "0011",
4 => "0100", 5 => "0101", 6 => "0110",
7 => "0111", 8 => "1000", 9 => "1001",
a => "1010", b => "1011", c => "1100",
d => "1101", e => "1110", f => "1111",
A => "1010", B => "1011", C => "1100",
D => "1101", E => "1110", F => "1111",
);
while (<>) {
chomp;
($binary = $_) =~ s/(.)/$h2b{lc $1}/g;
print $binary, "\n";
}
If you input something like:
Code:
f6f6f628282801020300
9c3c045f3059edeae18c
8c000000000000000000
0000000055045f3059ed
33ff3700000000000000
d19c3c045f3059edeae1
00000000000000000000
b371aad19c3c045f3059
00000000000000000000
You get an output of:
Code:
11110110111101101111011000101000001010000010100000000001000000100000001100000000
10011100001111000000010001011111001100000101100111101101111010101110000110001100
10001100000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000010101010000010001011111001100000101100111101101
00110011111111110011011100000000000000000000000000000000000000000000000000000000
11010001100111000011110000000100010111110011000001011001111011011110101011100001
00000000000000000000000000000000000000000000000000000000000000000000000000000000
10110011011100011010101011010001100111000011110000000100010111110011000001011001
00000000000000000000000000000000000000000000000000000000000000000000000000000000
07-02-2008, 05:20 PM
#10
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
Now if I can figure out a way to do it in reverse I'll be all set.
07-02-2008, 08:38 PM
#11
Senior Member
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780
Quote:
That does some interesting stuff but not what I was expecting.
Yeah, I didn't realize you meant text binary. :P
binary -> hex
Code:
#!/usr/bin/perl
while (<>) {
chop;
for (my $i = 0; $i < length($_); $i += 4) {
my $nibble = '0b'.substr($_, $i, 4);
printf('%x', oct($nibble));
}
print "\n";
}
hex -> binary
Code:
#!/usr/bin/perl
while (<>) {
chop;
for (my $i = 0; $i < length($_); $i += 1) {
printf('%04b', hex(substr($_, $i, 1)))
}
print "\n";
}
07-02-2008, 08:59 PM
#12
Senior Member
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530
Rep:
can't you use pack and unpack?
07-02-2008, 09:10 PM
#13
Senior Member
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530
Rep:
Yes, here we go.
Code:
#!/usr/bin/perl
use warnings;
use strict;
foreach my $h (qw(0 1 2 e f 10 11 12 1e 1f 20 30 40 50 100 200 1000)) {
printf "hex = %4s binary = %16s\n", $h, hex2bin($h);
}
sub hex2bin {
my $h = shift;
my $hlen = length($h);
my $blen = $hlen * 4;
return unpack("B$blen", pack("H$hlen", $h));
}
Output:
Code:
hex = 0 binary = 0000
hex = 1 binary = 0001
hex = 2 binary = 0010
hex = e binary = 1110
hex = f binary = 1111
hex = 10 binary = 00010000
hex = 11 binary = 00010001
hex = 12 binary = 00010010
hex = 1e binary = 00011110
hex = 1f binary = 00011111
hex = 20 binary = 00100000
hex = 30 binary = 00110000
hex = 40 binary = 01000000
hex = 50 binary = 01010000
hex = 100 binary = 000100000000
hex = 200 binary = 001000000000
hex = 1000 binary = 0001000000000000
Last edited by matthewg42; 07-02-2008 at 09:12 PM .
Reason: added output
07-02-2008, 09:18 PM
#14
Member
Registered: Jun 2008
Location: Upstate NY
Distribution: Fedora on the desk / Gentoo in the Racks
Posts: 36
Original Poster
Rep:
Wow, there's a lot of ways to do it in perl...
Cool, I guess I'll time the processes and see what ones the most time efficient and go from there.
Thanks everyone.
01-12-2010, 03:36 AM
#15
LQ Newbie
Registered: Jan 2010
Posts: 2
Rep:
Hi guys,
For some of you still interested in converting hexadecimal to binary, here's a
hex to binary converter . You can make sure you are converting the right way using this tool
David
All times are GMT -5. The time now is 01:31 AM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News