[Tutor] print IP address range to stdout

Dave Angel davea at ieee.org
Tue Dec 22 20:32:21 CET 2009


Rich Lovely wrote:
> 2009/12/22 MK <lopoff at gmx.net>:
>   
>> Ok. That was very helpful. As i dont know how to do it i googled
>> and found this one:
>> http://anonymouse.org/cgi-bin/anon-www.cgi/http://snipplr.com/view/14807/convert-ip-to-int-and-int-to-ip/
>>
>> But frankly i dont understand it. The program works now like it should
>> but i want to understand the code i use. So any help would be great.
>>
>> First function the ip is splitted as i did it. Alright.
>> The use 256 as it is the maximum for any digit. ok.
>> But what is that ** and exp meaning ????
>>
>> ----------------------------------------------------------
>> def ip_to_int(dotted_ip):
>>        exp = 3
>>        intip = 0
>>        for quad in dotted_ip.split('.'):
>>                intip = intip + (int(quad) * (256 ** exp))
>>                exp = exp - 1
>>        return(intip)
>>
>> ---------------------------------------------------
>>
>> def int_to_ip(intip):
>>        octet = ''
>>        for exp in [3,2,1,0]:
>>                octet = octet + str(intip / (256 ** exp)) + "."
>>                intip = intip % ( 256 ** exp)
>>        return (octet.rstrip("."))
>>
>> Am Dienstag, den 22.12.2009, 06:32 -0500 schrieb Dave Angel:
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
>>
>>     
>
> The ** operator means "to the power of", and is sometimes seen in text
> as "^" (but that means something different in python).
>
> 3**5 is 3 to the power of 5,or 3*3*3*3*3 (3 times itself five times) or 243.
>
> As it's only a short loop, we can unroll it quite easily, to make it
> clear what is happening.
>
> def ip_to_int(dotted_ip):
>     exp = 3
>     intip = 0
>     for quad in dotted_ip.split('.'):
>         intip = intip + (int(quad) * (256 ** exp))
>         exp = exp - 1
>     return(intip)
>
> Unrolling the for loop:
> def ip_to_int(dotted_ip):
>     exp = 3
>     intip = 0
>     quads = dotted_ip.split('.')
>
>     #Unrolled
>
>     quad = quads[0]
>     intip = intip + (int(quad) * (256 ** exp)) # intip + int(quad) *
> (256**3 (=16777216, =0xff000000))
>     exp = exp - 1 # exp = 2
>     quad = quads[1]
>     intip = intip + (int(quad) * (256 ** exp)) # intip + int(quad) *
> (256**2 (=65536, =0x00ff000000)
>     exp = exp - 1 # exp = 1
>     quad = quads[2]
>     intip = intip + (int(quad) * (256 ** exp)) # intip + int(quad) *
> (256**1 (=256, =0x0000ff00)
>     exp = exp - 1 # exp = 0
>     quad = quads[3]
>     intip = intip + (int(quad) * (256 ** exp)) # intip + int(quad) * (256**0)
>     exp = exp - 1 # exp = -1
>
>     return(intip)
>
> Now, cleaning that up, we get:
>
> def ip_to_int(dotted_ip):
>     quads = dotted_ip.split('.')
>     intip = int(quads[0]) * 0xff000000 + int(quads[1]) * 0xff000000
>     intip += int(quads[2]) * 0xff00 + int(quads[3])
>     return(intip)
>
> So, what it does is it takes each "quad" (the term for each number in
> an IP address), multiply it by a certain constant depending on where
> in the address it falls, and then adding it to the numeric address.
>
> Perhaps there's a library function to do this, but it's a useful
> learning experience - although a quick search of the docs hasn't
> turned anything up.
>
>   
MK:  My description for the first function was:
 >>>Note that the int you're looking for in the first function will be 
gotten by multiplying the various parts of the IP address by different 
powers of 256.

and that's just what the ** operator does.

I personally would shorten it to:

def ip_to_int(dotted_ip):
    intip = 0
    for quad in dotted_ip.split('.'):
        intip = intip * 256 + int(quad)
    return(intip)

Rich,  re. library functions:
   I'm sure one could format a string of 8 hex digits by using a 
zero-filled conversion of each int.  Then convert that to a single int 
with int(hex_string, 16).  But I don't think it'd be worth it.

Similarly, we could do 4 slices of hex() of the int, and convert each to 
decimal for display.

DaveA



More information about the Tutor mailing list