Confused Newbie question: Decimal to IP

M

Monica Roman

I've read a lot of the threads on this conversion but could not figure
out which one is the correct function.

I have never written PERL before, but I want to give it a try and be
able to convert decimal numbers into IP addresses in the PERL script
used to load the IPs plus other data into an Oracle database. Right
now I use a SQL function within Oracle, but it slows down everything!

Can someone help the translate into PERL the following SQL function?

create or replace function int2ip(ip int)
return varchar2
is
ip_address varchar2(15);
t number;
w int(3);
x int(3);
y int(3);
z int(3);

begin

t:= ip / 256;
w:= 256 * (t - FLOOR(t));
t:= (FLOOR (t))/ 256;
x:= 256 * (t - FLOOR(t));
t:= (FLOOR (t)) / 256;
y:= 256 * (t - FLOOR(t));
z:= FLOOR (t);

ip_address := z||'.'||y||'.'||x||'.'||w;

return ip_address;
end int2ip;


Thank you very much,


Monica Roman
 
M

Mark Clements

Monica said:
I've read a lot of the threads on this conversion but could not figure
out which one is the correct function.

I have never written PERL before, but I want to give it a try and be
able to convert decimal numbers into IP addresses in the PERL script
used to load the IPs plus other data into an Oracle database. Right
now I use a SQL function within Oracle, but it slows down everything!
<snip horrific pl/sql> (yes, I know that that is its nature)

look at inet_ntoa in the Socket module for starters.

perldoc Socket

btw: it's written "Perl" or "perl".

regards,

Mark
 
T

Tad McClellan

Monica Roman said:
I've read a lot of the threads on this conversion but could not figure
out which one is the correct function.


Have you tried the Perl FAQ?

I have never written PERL before,


There is no PERL, there is only Perl and perl.

Can someone help the translate into PERL the following SQL function?


Yes. _You_ can.

If you run into trouble post what you have so far and we will
help you fix it.

t:= ip / 256;
w:= 256 * (t - FLOOR(t));


The assignment, division, multiplication and subtraction operators are
documented in:

perldoc perlop


The floor() function is a Question that is Asked Frequently:

perldoc -q floor

Does Perl have a round() function? What about ceil() and floor()?
Trig functions?
 
J

John W. Krahn

Monica said:
I've read a lot of the threads on this conversion but could not figure
out which one is the correct function.

I have never written PERL before, but I want to give it a try and be
able to convert decimal numbers into IP addresses in the PERL script
used to load the IPs plus other data into an Oracle database. Right
now I use a SQL function within Oracle, but it slows down everything!

Can someone help the translate into PERL the following SQL function?

create or replace function int2ip(ip int)
return varchar2
is
ip_address varchar2(15);
t number;
w int(3);
x int(3);
y int(3);
z int(3);

begin

t:= ip / 256;
w:= 256 * (t - FLOOR(t));
t:= (FLOOR (t))/ 256;
x:= 256 * (t - FLOOR(t));
t:= (FLOOR (t)) / 256;
y:= 256 * (t - FLOOR(t));
z:= FLOOR (t);

ip_address := z||'.'||y||'.'||x||'.'||w;

return ip_address;
end int2ip;

A direct Perl translation would be something like:

use POSIX qw( floor );

sub int2ip {
my $ip = shift;

my $t = $ip / 256;
my $w = 256 * ( $t - floor $t );
$t = floor( $t ) / 256;
my $x = 256 * ( $t - floor $t );
$t = floor( $t ) / 256;
my $y = 256 * ( $t - floor $t );
my $z = floor $t;

return "$z.$y.$x.$w";
}


However that is still relatively slow. A more Perlish solution would
be:

sub int2ip { join '.', unpack 'CCCC', pack 'N', $_[ 0 ] }


Which is a lot faster. But an even faster solution would be:

use Socket;

sub int2ip { inet_ntoa inet_aton $_[ 0 ] }



John
 
A

Anno Siegel

John W. Krahn said:
Monica Roman wrote:
[...]
Can someone help the translate into PERL the following SQL function?

create or replace function int2ip(ip int)
return varchar2
is
ip_address varchar2(15);
t number;
w int(3);
x int(3);
y int(3);
z int(3);

begin

t:= ip / 256;
w:= 256 * (t - FLOOR(t));
t:= (FLOOR (t))/ 256;
x:= 256 * (t - FLOOR(t));
t:= (FLOOR (t)) / 256;
y:= 256 * (t - FLOOR(t));
z:= FLOOR (t);

ip_address := z||'.'||y||'.'||x||'.'||w;

return ip_address;
end int2ip;

A direct Perl translation would be something like:

use POSIX qw( floor );

sub int2ip {
my $ip = shift;

my $t = $ip / 256;
my $w = 256 * ( $t - floor $t );
$t = floor( $t ) / 256;
my $x = 256 * ( $t - floor $t );
$t = floor( $t ) / 256;
my $y = 256 * ( $t - floor $t );
my $z = floor $t;

return "$z.$y.$x.$w";
}

[snip other solutions]

That can be Perlified a bit (no critique, the OP asked for a direct
translation):

sub int2ip {
my $ip = shift;
$ip *= 256;
join '.', reverse map $_ % 256, map $ip = floor( $ip/256), 1 .. 4;
}

I mention this because it shows a particular difficulty. The step

"map $ip = floor( $ip/256), 1 .. 4"

is meant to produce a list of iterative applications of "floor( $ip/26)"
to $ip. So it does, but the list starts with the operation applied
once to $ip while we want the list to start with the original value of
$ip (the operation applied zero times).

In the given case that could be corrected by multiplying $ip with 256
first, but that's not always applicable, ugly and fragile.

Other possibilities are

map { my $sav = $ip; $ip = floor( $ip/256); $sav} 1 .. 4;
or
map ( "$ip", $ip = floor( $ip/256))[ 0], 1 .. 4;
or
( "$ip", map $ip = floor( $ip/256), 2 .. 4);

but I can't say I like either very much. So currently I'd probably
write this

my @coll;
for ( 1 .. 4 ) {
push @coll, $ip;
$ip = floor( $ip/256);
}

but I can't help thinking there must be a nice map solution.

Is there?

Anno
 
M

Monica Roman

Thank you Mark, John, Tad, for all your answers. John, I'll try all
the options you gave me...nothing better than something tangible to
start learning Perl, a question with the answer, perfect. I have two
Perl books on my desk right now and I'm excited about learning it.

Thanks again,

Monica
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top