[Tutor] print IP address range to stdout

Rich Lovely roadierich at googlemail.com
Tue Dec 22 18:36:21 CET 2009


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.

-- 
Rich "Roadie Rich" Lovely

There are 10 types of people in the world: those who know binary,
those who do not, and those who are off by one.


More information about the Tutor mailing list