No such thing as a small change PerlMonks

by ruzam (Curate)
 on Apr 28, 2006 at 19:47 UTC Need Help??
 Category: Miscellaneous Author/Contact Info Description: Convert long integers to dotted quad notation string. Convert dotted quad notation strings to long integer. A couple of quick functions I've been using to convert IP addresses. I seem to be using these quite often. Any and all comments/suggestions appreciated! Thanks to jdporter and ikegami who have shown me a better way. The code here is credited to ikegami. ```# thanks to jdporter and ikegami who have shown me a much better way t +o do this! # # Thanks to ikegami for the code example use Socket qw( inet_aton inet_ntoa ); sub DottedQuadToLong { # Accepts triton.littlefish.ca # Accepts 24.72.30.83 # Accepts 407379539 # etc return unpack('N', inet_aton(shift)); } sub LongToDottedQuad { return inet_ntoa(pack('N', shift)); } ```
Replies are listed 'Best First'.
Re: IP address - Converting between string and number
by ikegami (Patriarch) on Apr 28, 2006 at 20:10 UTC

Those are needlessly complicated. You're replicating functions inet_aton and inet_ntoa of the core module Socket:

```use Socket qw( inet_aton inet_ntoa );

# Accepts triton.littlefish.ca
# Accepts 24.72.30.83
# Accepts 407379539
# etc
return unpack('N', inet_aton(shift));
}

return inet_ntoa(pack('N', shift));
}

Here are alternatives that only use pack and unpack (but only accept addresses of the form a.b.c.d):

```sub DottedQuadToLong {
return unpack('N', (pack 'C4', split(/\./, shift)));
}

return join('.', unpack('C4', pack('N', shift)));
}
Wow! Excellent (and nearly instant) advice! Thanks both of you.

My use of regex was based on a very narrow definition of dotted quad I needed at the time. I'm totally in favor of using inet_aton and inet_ntoa instead!
by jdporter (Chancellor) on Apr 28, 2006 at 20:06 UTC
by davidrw (Prior) on Apr 28, 2006 at 20:20 UTC
Net::IP solutions:
```# for just DottedQuadToLong():
use Net::IP;
print Net::IP->new("24.72.30.83")->intip;

# for both directions:
use Net::IP qw/:PROC/;
print ip_bintoint(ip_iptobin("24.72.30.83",4));
print ip_bintoip(ip_inttobin("407379539",4),4);

• Personnally i'd write foreach (@quads) { \$_ = hex } w/map: return join '.', map {hex} @quads;
• in DottedQuadToLong, the split is just extra work -- just capture each piece (don't need the substitution, either)
```sub DottedQuadToLong {
my \$ip_str = shift;
return 0 unless \$ip_str =~ /^\s*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(
+\d{1,3})\s*\$/;
my \$ip = 0;
return 0 if (\$quad > 255);
\$ip = \$ip * 256 + \$quad;
}
return \$ip;
}
Nice tips. I rarely use map (it scares me) so I never would have thought of trying that. The spilt I should have seen coming...

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://546367]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2022-01-25 07:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In 2022, my preferred method to securely store passwords is:

Results (65 votes). Check out past polls.

Notices?