1

I've got a number (3232251030) that needs to be translated from Decimal to Binary. Once I've gotten the binary, I need to separate 8-bits of it into digits, revealing an ip address.

Converting Decimal to Binary is simple:

sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros return $str; }

sub bin2dec { return unpack("N", pack("B32", substr("0" x 32 . shift, -32))); }

e.g. $num = bin2dec('0110110'); # $num is 54 $binstr = dec2bin(54); # $binstr is 110110

Reference: http://www.perlmonks.org/?node_id=2664

So now, I need to split 8 digits off the binary and save it into numbers that makes an IP address.

$num = dec2bin('3232251030');

($num is "11000000 10101000 01000100 00001110" in binary)

I need to split and save each 8-bits "11000000 10101000 01000100 00001110" into "192.168.60.150".

Care to advice? I'm looking into split function for this..

LynxLee
  • 321
  • 1
  • 6
  • 17
  • Are you sure you really need this whole binary stage? It sounds like you just want to turn a string into an integer, then unpack it into bytes. – Gabe Jun 24 '11 at 05:44
  • I got an integer that I want to turn into binary, and then process each 8 bit as separate numbers to form an ip address (xxx.xxx.xxx.xxx). – LynxLee Jun 24 '11 at 05:51
  • A link to a book on a .ua site is almost guaranteed to be an illegal copy. – ysth Jun 24 '11 at 06:02

2 Answers2

7

You don't actually have to convert to a binary string, just a 32-bit integer:

print join '.', unpack('CCCC', pack('N', 3232251030));

will print 192.168.60.150

Gabe
  • 84,912
  • 12
  • 139
  • 238
7
say join('.', unpack('C4', pack('N', 3232251030)));

and

use Socket qw( inet_ntoa );
say inet_ntoa(pack('N', 3232251030));

both output

192.168.60.150
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • +1 for the Socket module. `pack` does not show the intention of the code, using the appropriate module does. Once the code needs to change to accommodate for IPv6, the maintenance programmer will have a hard time with the `pack` code because of its low level of abstraction, whereas with the module it's just another function call. – daxim Jun 24 '11 at 07:46
  • @daxim: How do you avoid the `pack` call? Even using `inet_ntoa` requires `pack`. – Gabe Jun 24 '11 at 13:44
  • I made a mistake, apologies. s/pack/unpack/ and you know what I mean – daxim Jun 24 '11 at 18:12
  • @Gabe does have a point, really. We are dealing with an IPv4 address, and we have to know we are dealing with an IPv4 address in order to create the proper byte string for `inet_ntoa` or `join`+`unpack`. On the other hand, @daxim also has a point that using `inet_ntoa` does make things clearer and provides a better upgrade path, if only for half of the snippet. – ikegami Jun 24 '11 at 22:04
  • @daxim: The whole notion of converting 32-bit decimal numbers to IP addresses means that it's fairly incompatible with IPv6 from the get-go. – Gabe Jun 25 '11 at 02:15