in reply to How to convert binary to hexadecimal

Update: Oops....got a decimal in there. Sorry.

Another snippet for your perusal:

#!/usr/bin/perl use warnings; use strict; my $binary = '11101010101010101010101010101010'; my $int = unpack("N", pack("B32", substr("0" x 32 . $binary, -32))); my $hex = sprintf("%x", $int ); print $hex,"\n";

I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Replies are listed 'Best First'.
Re^2: How to convert binary to hexadecimal
by vaas_m (Initiate) on Oct 12, 2007 at 11:00 UTC
    Hi zentara and all, Thanx for the info. I got it done very easily using pack and unpack as suggested by zentara. Rgds, Kiran Polu
      THanks Ikigami . I was looking everywhere for that.
Re^2: How to convert binary to hexadecimal
by Anonymous Monk on Jun 14, 2009 at 09:04 UTC
    this function works only for 32 bits, this will work for any binary length sub b2h { my $num=shift; my $WIDTH=32; my $index=length($num)-$WIDTH; print "index= $index\n"; my $hex=""; do { my $width=$WIDTH; if ($index<0) { $width+=$index; $index=0; } $cut_string=substr($num,$index,$width); print "index is $index width is $width Cut String is $cut_string\n"; $hex= sprintf('%X', oct("0b$cut_string")). $hex; $index-=$WIDTH; } while ($index>(-1*$WIDTH)); return $hex; }
      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.

        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; }

        Good stuff, thanks a lot.

        However, the line $hex = sprintf... better works as follows:

        $hex = sprintf('%0' . $WIDTH * 2 / 8 . 'X', oct("0b$cut_string")) . $h +ex;

        This covers cases when there are long sequences of zeroes in binary strings.

        I believe the above posted code is incorrect. An example string that breaks this is:
        0001111000001111000001111000001111000001111000001111000001111000001111 +000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000001111000001111000001111000001111000001111000 +00111100000111100000111100000111100000111100
        One correct way of doing bin2hex is:
        sub bin2hex { my $line = $_[0]; my $lenCount = 4; my $hexLine = ""; my $width = '4'; while ( length($line) % $width != 0) { $line = '0' . $line; } while ($lenCount <= length($line)) { my $x = substr ($line, -($lenCount), $width); $hexLine = sprintf("%X", oct("0b$x")).$hexLine; $lenCount += 4; } print "In bin2hex: $line\nAfter bin2hex: $hexLine\n\n"; return $hexLine; }

        2020-03-04 Athanasius added code tags.

        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.