FireBird34 has asked for the wisdom of the Perl Monks concerning the following question:
This may seem trivial to most, but what is the easiest and most effective way to convert an address to hex? Basically, I want 127.0.0.1 (localhost) to become 7F.00.00.01. Also, vice versa aswell, hex to decimal. I think I read up on a short form of doing this before, but I can't recall it. Also, I am not using CGI.pm, but can put in a snippit if needed. Thanks.
Re: decimal -> hex
by jmcnamara (Monsignor) on Oct 11, 2002 at 07:35 UTC
|
$ip_hex = join '.', map {sprintf "%02x", $_} split /\./, $ip_dec;
$ip_dec = join '.', map {hex} split /\./, $ip_hex;
--
John.
| [reply] [d/l] |
Re: decimal -> hex
by blakem (Monsignor) on Oct 11, 2002 at 07:37 UTC
|
my $ip = '127.0.0.1';
$ip =~ s/(\d+)/sprintf "%02X",$1/ge;
hex -> dec:
my $ip = '7F.00.00.01';
$ip =~ s/([abcdef\d]+)/hex $1/gie;
-Blake
| [reply] [d/l] [select] |
Re: decimal -> hex
by jarich (Curate) on Oct 11, 2002 at 06:53 UTC
|
my $address = "127.0.0.1";
# from decimal to hex:
my ($a,$b,$c,$d) = $address =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", $a, $b, $c, $d;
print "[$hex_addr]\n"; #prints "[7f.00.00.01]";
# from hex to decimal:
my ($a, $b, $c, $d) = $hex_addr =~ /(\w+)\.(\w+)\.(\w+)\.(\w+)/;
my $addr = hex($a). "." . hex($b) . "." . hex($c) . "." . hex($d);
print "[$addr]\n"; #prints "[127.0.0.1]"
Hope it helps.
jarich
Update: Added the second part once I worked it out, but kabel beat me anyway. | [reply] [d/l] |
|
my @bytes = $address =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", @bytes;
| [reply] |
|
Save yourself some typing and use an array :-)
my @bytes = $address =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", @bytes;
Save yourself even more typing and make one expression of it.
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", $address =~ /(\d+)\.(\d+
+)\.(\d+)\.(\d+)/;
As you seem to be absolutely sure on the address format, split() will do:
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", split /\./, $address;
I'm sure others would recommend use of inet_aton(), from Socket.pm, because it's more flexible in what it accepts for an IP address. Unfortunately for us, if produces a string of 4 packed bytes, but it's nothing unpack() can't easily handle.
use Socket;
my $address = '127.1';
my $hex_addr = sprintf "%02x.%02x.%02x.%02x", unpack 'C*', inet_aton($
+address);
And if you prefer uppercase hex instead of lowercase, use '%02X' instead of '%02x' in the sprintf() template. | [reply] [d/l] [select] |
|
|
|
| [reply] |
Re: decimal -> hex
by kabel (Chaplain) on Oct 11, 2002 at 06:55 UTC
|
dec -> hex: s/printf with %x
printf "%x\n", 15;
hex -> dec: function hex
print hex ('F');
to break a wheel on the fly (one of the rare sayings i learned - would be in german: "mit kanonen auf spatzen schiessen" :) )
the package Math::BaseCalc;
HTH | [reply] [d/l] [select] |
Re: decimal -> hex
by rdfield (Priest) on Oct 11, 2002 at 09:58 UTC
|
$ip = "127.0.0.1";
print join(".",unpack("H2H2H2H2",pack("c4",split /\./,$ip)));
rdfield
Update: Fixed typo as per blakem's post. I blame the shift key :) | [reply] [d/l] |
|
I think you've got your nybble order mixed up...
print join(".",unpack("H2H2H2H2",pack("c4",split /\./,$ip)));
-Blake
| [reply] [d/l] |
Re: decimal -> hex
by zakzebrowski (Curate) on Oct 11, 2002 at 11:28 UTC
|
Not to belabour the point, but try the internal documentation / google.
For example
perldoc -f sprintf would have helped you with this question. The -f means that you are looking up an internal function.
C:\>perldoc -?
Unknown option: ?
perldoc [options] PageName|ModuleName|ProgramName...
perldoc [options] -f BuiltinFunction
perldoc [options] -q FAQRegex
----
Zak
Pluralitas non est ponenda sine neccesitate - mysql's philosphy | [reply] [d/l] [select] |
Re: IP Address Conversion to Hex
by tadman (Prior) on Oct 11, 2002 at 23:54 UTC
|
As I have commented before I am of the opinion that splitting your textual IP address is the same as parsing CGI using your own hand-rolled routines. It's dirty. It's bad. It might work.
use Socket;
my $ip_hex = join('.', map { sprintf("%02X", ord($_)) }
split(//, inet_aton($addr)));
my $ip_dec = join('.', map { hex($_) } split(/\./, $ip_hex));
The nice thing about inet_aton is that it works even with text names like "www.xyzco.com".
| [reply] [d/l] [select] |
Re: decimal -> hex
by LEFant (Scribe) on Oct 11, 2002 at 20:42 UTC
|
If the purpose of the conversion is to prepare an operand for a socket call, the dotted decimal ip notation must be converted to a packed 32 bit integer. For example, Perl's gethostbyaddress expects addresses in this format.
use Socket;
$ipaddr = inet_aton(127.0.0.1);
# In Perl 5.6 you can convert with the v-string notation:
# $ipaddr = v127.0.0.1;
Off the back of the third camel, page 720.
Bob
| [reply] [d/l] |
Re: decimal -> hex
by Aristotle (Chancellor) on Oct 11, 2002 at 23:32 UTC
|
my @octet = split /\./, $dec;
my $hex = sprintf +(join ".", ("%02X") x @octet), @octet;
Makeshifts last the longest. | [reply] [d/l] |
Re: decimal -> hex
by Juerd (Abbot) on Oct 12, 2002 at 13:28 UTC
|
perl -MSocket -le'print unpack "H*", inet_aton "127.0.0.1"'
- Yes, I reinvent wheels.
- Spam: Visit eurotraQ.
| [reply] [d/l] |
|
|