Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^3: How to convert binary to hexadecimal

by toolic (Bishop)
on Oct 04, 2012 at 13:56 UTC ( #997236=note: print w/ replies, xml ) Need Help??


in reply to Re^2: How to convert binary to hexadecimal
in thread How to convert binary to hexadecimal

Since the code Does What I Want (works even for bit widths > 32), I have made it readable by using perltidy. I have also made it strict and removed the print statements:

use warnings FATAL => 'all'; use strict; for ( qw( 00 1010 1110 010001 01101011 ), '1' x 33, '0101' x 16 ) { my $h = b2h($_); print "$_ $h width=", length($_), "\n"; } exit; sub b2h { my $num = shift; my $WIDTH = 32; my $index = length($num) - $WIDTH; my $hex = ''; do { my $width = $WIDTH; if ($index < 0) { $width += $index; $index = 0; } my $cut_string = substr($num, $index, $width); $hex = sprintf('%X', oct("0b$cut_string")) . $hex; $index -= $WIDTH; } while ($index > (-1 * $WIDTH)); return $hex; } __END__ Output: 00 0 width=2 1010 A width=4 1110 E width=4 010001 11 width=6 01101011 6B width=8 111111111111111111111111111111111 1FFFFFFFF width=33 0101010101010101010101010101010101010101010101010101010101010101 55555 +55555555555 width=64

I have also been attempting to implement this with pack and unpack, to no avail.


Comment on Re^3: How to convert binary to hexadecimal
Download Code
Replies are listed 'Best First'.
Re^4: How to convert binary to hexadecimal
by Lotus1 (Chaplain) on Oct 02, 2014 at 17:46 UTC

    Here's another way to do it.

    use warnings; use strict; foreach ( qw( 00 1010 1110 010001 01101011 ), '1' x 33, '0101' x 16 ) { my $h2 = b2h2($_); $h2 =~ s/(\w{4})\B/$1 /g; print "$_ $h2 width=", length($_), "\n\n"; } sub b2h2 { my $bin = shift; my $extra_characters = length($bin)%16; $bin = '0' x (16-$extra_characters) . $bin if $extra_characters; $bin =~ s/([01]{4})/sprintf "%X", oct("0b$1")/eg; return $bin; } __END__ Output: 00 0000 width=2 1010 000A width=4 1110 000E width=4 010001 0011 width=6 01101011 006B width=8 111111111111111111111111111111111 0001 FFFF FFFF width=33 0101010101010101010101010101010101010101010101010101010101010101 5555 +5555 5555 5555 width=64

    Here is a way to convert without padding with zeros on the left side. Reverse the binary string and convert groups of four bits then reverse the final string.

    sub b2h { my $revbin = reverse shift; $revbin =~ s/([01]{1,4})/sprintf "%X", oct('0b' . reverse $1)/eg; return reverse $revbin; }
Re^4: How to convert binary to hexadecimal
by Anonymous Monk on Mar 21, 2013 at 07:09 UTC
    hi, I wanted to convert a long binary string to a hexadecimal string. sprintf didn't work because the number was more than 32 bits and thr pack/unpack functions are very complicated for me to understand. hence, I converted it using a truth table. The code is
    sub Bin2Hex{ my %truth_table = ( '0000' => '0' , '0001' => '1' , '0010' => '2' , '0011' => '3' , '0100' => '4' , '0101' => '5' , '0110' => '6' , '0111' => '7' , '1000' => '8' , '1001' => '9' , '1010' => 'A' , '1011' => 'B' , '1100' => 'C' , '1101' => 'D' , '1110' => 'E' , '1111' => 'F' , ); my $count = 0; my $hex_string = ''; my $len = $#_ ; #print "len $len" ; my $nibble = '' ; my $abit ; my $hex_len ; my $hex_nibble ; $hex_len = ceil($len/4) ; #print "hex len $hex_len \n" ; for(my $i=0; $i < $hex_len ; $i++) { for(my $j= 0 ; $j < 4; $j++){ $abit = pop(@_) ; if (defined $abit) { $nibble = $abit.$nibble; } else { $nibble = '0'.$nibble ; } } $hex_nibble = $truth_table{$nibble} ; $hex_string = $hex_nibble.$hex_string ; $nibble = '' ; } #print "the converted hex : $hex_string" ; return $hex_string ; }
    the input to the function is binary string stored in list.

      Anonymonk:

      Here's another way to do it:

      $ cat bin2hex.pl #!/usr/bin/perl use strict; use warnings; for my $b (qw(101101110101001010010100101000101011101010101010101010 1 10 101 1010 10101 101010 11010011 000000000000001 000 +1111 11111 11000011 )) { print "$b --> ", bin2hex($b), "\n"; } sub bin2hex { my $bin = shift; # Make input bit string a multiple of 4 $bin = substr("0000",length($bin)%4) . $bin if length($bin)%4; my ($hex, $nybble) = (""); while (length($bin)) { ($nybble,$bin) = (substr($bin,0,4), substr($bin,4)); $nybble = eval "0b$nybble"; $hex .= substr("0123456789ABCDEF", $nybble, 1); } return $hex; } $ perl bin2hex.pl 101101110101001010010100101000101011101010101010101010 --> 2DD4A528AEA +AAA 1 --> 1 10 --> 2 101 --> 5 1010 --> A 10101 --> 15 101010 --> 2A 11010011 --> D3 000000000000001 --> 0001 0001111 --> 0F 11111 --> 1F 11000011 --> C3

      It uses an old[1] trick: Since each "nybble"[2] represents a decimal value from 0 to 15, you can build a 16 character string of digits, and use the nybble value as the index of a character.

      Then, to simplify things, we ensure that the string is a multiple of four characters long. That way, we simply chop off four characters, turn it into a hex digit, repeating until the string is consumed.

      Notes:

      [1] How old? It was old when I learned it, roughly 35 years ago.

      [2] Four bits == half a byte, thus, a nybble.

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://997236]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2015-07-30 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (271 votes), past polls