Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

create filename from IP#

by belize (Deacon)
on Nov 26, 2003 at 19:15 UTC ( #310352=perlquestion: print w/replies, xml ) Need Help??

belize has asked for the wisdom of the Perl Monks concerning the following question:

I need to create a filename from the users IP# (using $ipaddress = $ENV{REMOTE_ADDR};). I have managed to capture the IP# (i.e and change it to a proper filename (i.e. 127001) using $ipaddress =~ s/\.//g;, but I want to make it an "absolute" IP# (127000000001). I know you have to search for the first ".", count the number of intergers, and add the proper number of 0's to make three, then repeat the process, but I can't come up with a way of doing that. Any quick ideas?

Just for a little background, I want to do this so that I can log the number of login attempts to a page. I want to limit the number of attempts to 3, so I will create the file with the number of attempts incrementing 1 each time a login fails. If the number of login attempts exceeds 3, I will block the person from trying again for a specific amount of time.


Replies are listed 'Best First'.
Re: create filename from IP#
by Ovid (Cardinal) on Nov 26, 2003 at 19:21 UTC
    $ip_address ne $user

    From what I understand, AOL users get a different IP address with every request. Also, what about corporate users going through the same proxy that gives all of them the same IP address? IP addresses are like trivia: they're interesting, but don't rely on them to be useful.


    New address of my CGI Course.

Re: create filename from IP#
by waswas-fng (Curate) on Nov 26, 2003 at 19:22 UTC
    If you insist on doing this in this way, I would use directory trees to store the login count, meaning for the ip use  /var/run/iptracker/127/0/0/1/count this will make the application run much faster than storing a huge number of files in one directory. when you get above a certain number of files in a directory (it differs on platform/version) you will see a _HUGE_ slowdown when stating files and opening files in said directory. I would recommend using some type of database or tie hash to store this instead. You get one file with quick lookups and no messy filesystem cleanups to worry about. Also is a proper IP address.


    Edited to add: I agree with ovid that IP/failed login pairing not a very good metric for taking action. Many ISP's are claiming "Speed enhancers" nowadays which is really just a transparent proxy farm set up to grab a page, reduce image size/quality and push on to the requester. So more often than ever your site will be hit by proxy servers -- taking action based on IP is not worthwhile. One of the only things I can see being useful in that arena is to maybe take a rolling average of badauths/ip/time to throttle an attack from a source ip. But even that is hard to do without penalizing good users.
Re: create filename from IP#
by jdporter (Canon) on Nov 26, 2003 at 19:18 UTC
    my $IP = ''; # or whatever my $abs_IP = join '', map { sprintf "%03d", $_ } split /\./, $IP;

    The 6th Rule of Perl Club is -- There is no Rule #6.

      my $IP = ''; my $abs_IP = sprintf "%03d"x4, split /\./, $IP;

      Avoid map for simple stuff. The "%03d"x4 above is computed during compilation. Also, avoid loops at runtime.

      You should also consider using the resutling string as a prefix of the resulting filename for security reasons. There is File::Temp for that.

      UPDATE: Ignoring the fact that this might not be as useful as one might think, you should really use a database for this type of job. It's a lot safer, faster and scalable.

      It depends on what you store in each file. If you store small records of just a few bytes, you could be using 2k or 4k (or more) of disk space for each file according to your fs blocksize. Take a look to DB_File for more info.

Re: create filename from IP#
by dws (Chancellor) on Nov 26, 2003 at 20:04 UTC
    If you really must convert IP addresses to filenames, don't simply drop the period. If you do, you've introduced the equivalent of a hash collision, and can't tell whether "12345" came from,,, or
      you've introduced the equivalent of a hash collision

      I think he was hoping to convert his filenames to 3 digits per octet in order to avoid that exact problem. Of course, removing the dots first won't work. And I don't understand why he'd remove the dots to "change it to a proper filename". An IP would make a fine filename, I'd think.

      Shrug. As others have pointed out, this isn't likely to be an effective approach to his problem anyway because a requestor's IP can change from request to request and an IP may be shared among many requestors.

      "My two cents aren't worth a dime.";
Re: create filename from IP#
by Roger (Parson) on Nov 27, 2003 at 00:36 UTC
    Just extend your existing regular expression a bit will do the trick -
    use strict; while (<DATA>) { s/(\d+|\.)/ $1 eq '.' ? '' : sprintf "%03d", $1 /eg; print; } __DATA__
    And the output -
    127000000001 256123012001 256012031021
Re: create filename from IP#
by Stevie-O (Friar) on Nov 27, 2003 at 02:09 UTC
    What happens when someone connects using IPv6?
    -- Stevie-O
    $"=$,,$_=q>|\p4<6 8p<M/_|<('=> .q>.<4-KI<l|2$<6%s!<qn#F<>;$, .=pack'N*',"@{[unpack'C*',$_] }"for split/</;$_=$,,y[A-Z a-z] {}cd;print lc

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://310352]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2021-10-24 01:28 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (88 votes). Check out past polls.