Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^3: How to convert binary to hexadecimal

by toolic (Bishop)
on Oct 04, 2012 at 13:56 UTC ( [id://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.

Replies are listed 'Best First'.
Re^4: How to convert binary to hexadecimal
by Lotus1 (Vicar) 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 Jan 11, 2019 at 16:56 UTC

    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.

Re^4: How to convert binary to hexadecimal
by Anonymous Monk on Mar 03, 2020 at 20:13 UTC
    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.

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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://997236]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-19 20:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found