批量ip段/子网转换
阅读原文时间:2023年07月08日阅读:1

#coding=utf-8
import re
import struct
from sys import argv

class CIDRHelper(object):
def ipFormatChk(self, ip_str):
pattern = r"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
if re.match(pattern, ip_str):
return True
else:
return False

def masklenChk(self, masklen):  
    if masklen > 0 and masklen < 32:  
        return True  
    else:  
        return False

def Parse(self, ip, masklen):  
    if False == self.ipFormatChk(ip) or False == self.masklenChk(masklen):  
        exit("子网格式不对或者掩码>32")

    ips = ip.split(".")  
    binip = 0  
    for id in ips:  
        binip = binip << 8  
        binip += int(id)

    mask = (1 << 32) - 1 - ((1 << (32 - masklen)) - 1)

    a, b, c, d = struct.unpack('BBBB', struct.pack('>I', (binip & mask)))  
    A = ".".join(\[str(a), str(b), str(c), str(d+1)\])  
    a, b, c, d = struct.unpack('BBBB', struct.pack('>I', (binip & mask) + (2 << (32 - masklen - 1)) - 1))  
    B = ".".join(\[str(a), str(b), str(c), str(d)\])  
    return A + "XXXXX" + B

class ipTransfer(object):
def __init__(self):
self.CIDR = CIDRHelper()

def exchange\_mask(self,mask):  
    # 计算二进制字符串中 '1' 的个数  
    count\_bit = lambda bin\_str: len(\[i for i in bin\_str if i == '1'\])  
    # 分割字符串格式的子网掩码为四段列表  
    mask\_splited = mask.split('.')  
    # 转换各段子网掩码为二进制, 计算十进制  
    mask\_count = \[count\_bit(bin(int(i))) for i in mask\_splited\]  
    return sum(mask\_count)

def group(self,line,mode=0):  
    r = re.split("\\s{2,}",line)  
    domain = r\[0\].strip()  
    ip = r\[1\].strip()  
    if mode == 0:  
        return domain  
    elif mode == 1:  
        return ip if len(ip)<16 else 0

def makeCList(self,tempIp,start=1,end=255):  
    return \[tempIp+str(temp) for temp in xrange(start,end)\]

def getIp(self,filename):  
    ipList = \[\]  
    with open(filename,"r") as fp:  
        for l in fp.readlines():  
            line = self.group(l,mode=1)  
            if line != 0:  
                if line.startswith("127") or line.startswith("192.168") or line.startswith("10.") or line.startswith("172") or line.startswith("255.") or line.startswith("169.254"):  
                    continue  
                else:  
                    ip = re.match(r"\\d+\\.\\d+\\.\\d+\\.", line)  
                    ips = self.makeCList(ip.group(0))  
                    ipList+=ips

    return sorted(list(set(ipList)))

def getDomain(self,filename):  
    domainList = \[\]  
    with open(filename,"r") as fp:  
        for d in fp.readlines():  
            domain = self.group(d,mode=0)  
            domainList.append(domain)

    return sorted(list(set(domainList)))

def getDomain\_Ip(self,filename):  
    list1 = self.getIp(filename)  
    list2 = self.getDomain(filename)  
    ipDomain = list1+list2  
    return ipDomain

def readfile(self,filename):  
    with open(filename,"r") as fp:  
        x = fp.readlines()  
    return x

def makeIp(self,filename,mode=0):  
    iplist = \[\]  
    preList = self.readfile(filename)  
    for line in preList:  
        line = line.strip()  
        times = len(re.findall(r"\\.",line))  
        if "-" in line:  
            start = re.split("-", line)\[0\]  
            end = re.split("-", line)\[1\]  
            if times == 3:  
                ip = re.match(r"(\\d+\\.\\d+\\.\\d+\\.)(\\d+)", start.strip())  
                start = int(ip.group(2))  
                end = int(end.strip())  
                iplist += self.makeCList(ip.group(1),start=start,end=end+1)  
            elif times > 3:  
                ipA= re.match(r"(\\d+\\.\\d+\\.\\d+\\.)(\\d+)", start.strip())  
                start = int(ipA.group(2))  
                ipB = re.match(r"(\\d+\\.\\d+\\.\\d+\\.)(\\d+)", end.strip())  
                end = int(ipB.group(2))  
                iplist += self.makeCList(ipA.group(1),start=start,end=end+1)  
        elif "/" in line:  
            ip = re.split("/",line)\[0\].strip()  
            netmask = re.split("/",line)\[1\].strip()  
            if netmask.startswith("255."):  
                exchange = self.exchange\_mask(netmask)  
                ipres = self.CIDR.Parse(ip,int(exchange))  
            else:  
                ipres = self.CIDR.Parse(ip,int(netmask))  
            print "子网掩码转换结果 -> "+ipres  
            ipA = re.match(r"(\\d+\\.\\d+\\.\\d+\\.)(\\d+)", ipres.split("XXXXX")\[0\].strip())  
            ipB = re.match(r"(\\d+\\.\\d+\\.\\d+\\.)(\\d+)", ipres.split("XXXXX")\[1\].strip())  
            start = int(ipA.group(2))  
            end = int(ipB.group(2))  
            iplist += self.makeCList(ipA.group(1), start=start, end=end)  
        else:  
            if mode == 0:  
                iplist.append(line)  
            elif mode == 1:  
                ip = re.match(r"\\d+\\.\\d+\\.\\d+\\.", line)  
                ips = self.makeCList(ip.group(0))  
                iplist += ips

    return sorted(list(set(iplist)))

def output(self,dstFile,list):  
    with open(dstFile,"w") as fp:  
        for k,v in enumerate(list):  
            if k+1 < len(list):  
                fp.write(v)  
                fp.write("\\n")  
            else:  
                fp.write(v)

if __name__ == "__main__":
LZ = ipTransfer()
# print LZ.getDomain("test.txt")
# print LZ.getIp("test.txt")
# print LZ.getDomain_Ip("test.txt")
# print LZ.makeIp("ip.txt")
if len(argv)<4: exit( "Usage : Welcome to Lzscanner\\n" \\ "------------------------------------------------\\n" \\ "-d filename -o dstfilename --full #获取子域名和ip保存到文件\\n" \\ "-d filename -o dstfilename --domain #仅获取子域名保存到文件\\n" \\ "-d filename -o dstfilename --onlyip #仅获取ip保存到文件\\n" \\ "-ip filename -o dstfilename #处理子网掩码 eg.\*/28, \*/255.255.255.240, 55.55.55.55-55.55.55.100,23.1.2.100-254\\n" "-ip filename -o dstfilename --fullip #处理ip时候单个ip也转换为c段\\n" \\ "------------------------------------------------") elif len(argv)>4:
if argv[1] == "-d" and argv[3] == "-o":
print "start 处理子域名扫描结果"
filename = argv[2]
dstFilename = argv[4]
if "--full" in argv:
LZ.output(dstFilename,LZ.getDomain_Ip(filename))
elif "--domain" in argv:
LZ.output(dstFilename, LZ.getDomain(filename))
elif "--onlyip" in argv:
LZ.output(dstFilename, LZ.getIp(filename))
print "success 处理完成"
elif argv[1] == "-ip" and argv[3] == "-o":
print "start 处理ip段"
filename = argv[2]
dstFilename = argv[4]
if len(argv) == 5:
LZ.output(dstFilename,LZ.makeIp(filename))
elif len(argv) == 6:
LZ.output(dstFilename,LZ.makeIp(filename,mode=1))

        print "success 处理完成"  
    else:  
        print "ipTransfer用法错误"