Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Confused Newbie question: Decimal to IP

Reply
Thread Tools

Confused Newbie question: Decimal to IP

 
 
Monica Roman
Guest
Posts: n/a
 
      05-10-2004
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
 
Reply With Quote
 
 
 
 
Mark Clements
Guest
Posts: n/a
 
      05-10-2004
Monica Roman wrote:
> 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
 
Reply With Quote
 
 
 
 
Tad McClellan
Guest
Posts: n/a
 
      05-10-2004
Monica Roman <(E-Mail Removed)> wrote:

> 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?


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      05-10-2004
Monica Roman wrote:
>
> 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
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      05-11-2004
John W. Krahn <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> 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


 
Reply With Quote
 
Monica Roman
Guest
Posts: n/a
 
      05-11-2004
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
decimal.Decimal formatting python@lists.fastmail.net Python 0 07-19-2010 12:32 PM
how to convert from Decimal('1.23456789') to Decimal('1.234') valpa Python 11 03-24-2009 07:11 AM
Error: Cannot convert Decimal("0.0000") to Decimal Vitaliy Python 1 05-29-2008 10:36 AM
TypeError: unsupported operand type(s) for -: 'Decimal' and 'Decimal'. Why? Gilbert Fine Python 8 08-01-2007 01:58 AM
Decimal to Packed Decimal Conversion in C++ Ven C++ 3 08-01-2006 03:56 PM



Advertisments