iprangeparse.py

来自「这是一个嵌入式linux系统下的命令工具包」· Python 代码 · 共 195 行

PY
195
字号
# Written by John Hoffman# see LICENSE.txt for license informationfrom bisect import bisect, insorttry:    Trueexcept:    True = 1    False = 0    bool = lambda x: not not xdef to_long_ipv4(ip):    ip = ip.split('.')    if len(ip) != 4:        raise ValueError, "bad address"    b = 0L    for n in ip:        b *= 256        b += int(n)    return bdef to_long_ipv6(ip):    if ip == '':        raise ValueError, "bad address"    if ip == '::':      # boundary handling        ip = ''    elif ip[:2] == '::':        ip = ip[1:]    elif ip[0] == ':':        raise ValueError, "bad address"    elif ip[-2:] == '::':        ip = ip[:-1]    elif ip[-1] == ':':        raise ValueError, "bad address"    b = []    doublecolon = False    for n in ip.split(':'):        if n == '':     # double-colon            if doublecolon:                raise ValueError, "bad address"            doublecolon = True            b.append(None)            continue        if n.find('.') >= 0: # IPv4            n = n.split('.')            if len(n) != 4:                raise ValueError, "bad address"            for i in n:                b.append(int(i))            continue        n = ('0'*(4-len(n))) + n        b.append(int(n[:2],16))        b.append(int(n[2:],16))    bb = 0L    for n in b:        if n is None:            for i in xrange(17-len(b)):                bb *= 256            continue        bb *= 256        bb += n    return bbipv4addrmask = 65535L*256*256*256*256class IP_List:    def __init__(self):        self.ipv4list = []  # starts of ranges        self.ipv4dict = {}  # start: end of ranges        self.ipv6list = []  # "        self.ipv6dict = {}  # "    def __nonzero__(self):        return bool(self.ipv4list or self.ipv6list)    def append(self, ip_beg, ip_end = None):        if ip_end is None:            ip_end = ip_beg        else:            assert ip_beg <= ip_end        if ip_beg.find(':') < 0:        # IPv4            ip_beg = to_long_ipv4(ip_beg)            ip_end = to_long_ipv4(ip_end)            l = self.ipv4list            d = self.ipv4dict        else:            ip_beg = to_long_ipv6(ip_beg)            ip_end = to_long_ipv6(ip_end)            bb = ip_beg % (256*256*256*256)            if bb == ipv4addrmask:                ip_beg -= bb                ip_end -= bb                l = self.ipv4list                d = self.ipv4dict            else:                l = self.ipv6list                d = self.ipv6dict        pos = bisect(l,ip_beg)-1        done = pos < 0        while not done:            p = pos            while p < len(l):                range_beg = l[p]                if range_beg > ip_end+1:                    done = True                    break                range_end = d[range_beg]                if range_end < ip_beg-1:                    p += 1                    if p == len(l):                        done = True                        break                    continue                # if neither of the above conditions is true, the ranges overlap                ip_beg = min(ip_beg, range_beg)                ip_end = max(ip_end, range_end)                del l[p]                del d[range_beg]                break        insort(l,ip_beg)        d[ip_beg] = ip_end    def includes(self, ip):        if not (self.ipv4list or self.ipv6list):            return False        if ip.find(':') < 0:        # IPv4            ip = to_long_ipv4(ip)            l = self.ipv4list            d = self.ipv4dict        else:            ip = to_long_ipv6(ip)            bb = ip % (256*256*256*256)            if bb == ipv4addrmask:                ip -= bb                l = self.ipv4list                d = self.ipv4dict            else:                l = self.ipv6list                d = self.ipv6dict        for ip_beg in l[bisect(l,ip)-1:]:            if ip == ip_beg:                return True            ip_end = d[ip_beg]            if ip > ip_beg and ip <= ip_end:                return True        return False    # reads a list from a file in the format 'whatever:whatever:ip-ip'    # (not IPv6 compatible at all)    def read_rangelist(self, file):        f = open(file, 'r')        while True:            line = f.readline()            if not line:                break            line = line.strip()            if not line or line[0] == '#':                continue            line = line.split(':')[-1]            try:                ip1,ip2 = line.split('-')            except:                ip1 = line                ip2 = line            try:                self.append(ip1.strip(),ip2.strip())            except:                print '*** WARNING *** could not parse IP range: '+line        f.close()def is_ipv4(ip):    return ip.find(':') < 0def is_valid_ip(ip):    try:        if is_ipv4(ip):            a = ip.split('.')            assert len(a) == 4            for i in a:                chr(int(i))            return True        to_long_ipv6(ip)        return True    except:        return False

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?