0

我一直在尝试创建一个 csv 文件,该文件将更改所有子网和 IP 地址范围,因此没有重叠。

我有这个文件开始:

Zone Name, IPStart, IPStop,Range,Source
Group A,10.0.0.0,10.127.255.255,10.0.0.0/9,New List
Group A Sales,10.16.0.0,10.31.255.255,10.16.0.0/12,New List
Group A Marketing,10.62.0.0,10.62.255.255,10.62.0.0/16,New List
Group A Research,10.62.0.0,10.63.255.255,10.62.0.0/15,Old List
Group A Sales Primary routers,10.23.1.0,10.23.1.15,10.24.1.0/28,New List
Group A Sales Web Servers - Primary,10.18.0.0,10.18.0.255,10.18.0.0/24,New List
Group A Sales Web Servers,10.16.0.0,10.19.255.255,10.16.0.0/14,New List
Group B,10.128.0.0,10.255.255.255,10.128.0.0/9,Old List

我希望它看起来像这样(行的顺序无关紧要):

Zone Name, IPStart, IPStop,Range,Source
Group A,10.0.0.0,10.15.255.255,10.0.0.0/12,New List
Group A,10.32.0.0,10.47.255.255,10.32.0.0/12,New List
Group A,10.48.0.0,10.55.255.255,10.48.0.0/13,New List
Group A,10.56.0.0,10.59.255.255,10.56.0.0/14,New List
Group A,10.60.0.0,10.61.255.255,10.60.0.0/15,New List
Group A,10.64.0.0,10.127.255.255,10.64.0.0/10,New List
Group A Marketing,10.62.0.0,10.62.255.255,10.62.0.0/16,New List
Group A Research,10.63.0.0,10.63.255.255,10.63.0.0/16,Old List
Group A Sales,10.20.0.0,10.21.255.255,10.20.0.0/15,New List
Group A Sales,10.22.0.0,10.22.255.255,10.22.0.0/16,New List
Group A Sales,10.23.0.0,10.23.0.255,10.23.0.0/24,New List
Group A Sales,10.23.1.128,10.23.1.255,10.23.1.128/25,New List
Group A Sales,10.23.1.16,10.23.1.31,10.23.1.16/28,New List
Group A Sales,10.23.1.32,10.23.1.63,10.23.1.32/27,New List
Group A Sales,10.23.1.64,10.23.1.127,10.23.1.64/26,New List
Group A Sales,10.23.128.0,10.23.255.255,10.23.128.0/17,New List
Group A Sales,10.23.16.0,10.23.31.255,10.23.16.0/20,New List
Group A Sales,10.23.2.0,10.23.3.255,10.23.2.0/23,New List
Group A Sales,10.23.32.0,10.23.63.255,10.23.32.0/19,New List
Group A Sales,10.23.4.0,10.23.7.255,10.23.4.0/22,New List
Group A Sales,10.23.64.0,10.23.127.255,10.23.64.0/18,New List
Group A Sales,10.23.8.0,10.23.15.255,10.23.8.0/21,New List
Group A Sales,10.24.0.0,10.31.255.255,10.24.0.0/13,New List
Group A Sales,10.24.32.0,10.24.63.255,10.24.32.0/19,New List
Group A Sales Primary routers,10.23.1.0,10.23.1.15,10.24.1.0/28,New List
Group A Sales Web Servers,10.16.0.0,10.17.255.255,10.16.0.0/15,New List
Group A Sales Web Servers,10.19.0.0,10.19.255.255,10.19.0.0/16,New List
Group A Sales Web Servers,10.18.128.0,10.18.255.255,10.18.128.0/17,New List
Group A Sales Web Servers,10.18.64.0,10.18.127.255,10.18.64.0/18,New List
Group A Sales Web Servers,10.18.32.0,10.18.63.255,10.18.32.0/19,New List
Group A Sales Web Servers,10.18.16.0,10.18.31.255,10.18.16.0/20,New List
Group A Sales Web Servers,10.18.8.0,10.18.15.255,10.18.8.0/21,New List
Group A Sales Web Servers,10.18.4.0,10.18.7.255,10.18.4.0/22,New List
Group A Sales Web Servers,10.18.2.0,10.18.3.255,10.18.2.0/23,New List
Group A Sales Web Servers,10.18.1.0,10.18.1.255,10.18.1.0/24,New List
Group A Sales Web Servers - Primary,10.18.0.0,10.18.0.255,10.18.0.0/24,New List
Group B,10.128.0.0,10.255.255.255,10.128.0.0/9,Old List

我一直在使用此处描述的网络对象在 Python 3.3 中使用 ipaddress 模块http://docs.python.org/dev/library/ipaddress

到目前为止,这是我的代码:

import ipaddress
import csv
from csv import DictReader, DictWriter

with open(r'file1.csv', newline='') as fin3,\
     open(r'file2.csv', newline='') as fin4,\
     open(r'file3.csv', 'w', newline='') as fout3:


    read3 = DictReader(fin3) # fin 3 and 4 are copies of the same file
    read4 = DictReader(fin4)

    writenum3 = DictWriter(fout3, fieldnames=read3.fieldnames) 
    writenum3.writeheader()

    for line3 in read3:
        line3['Range']=ipaddress.ip_network(line3['Range']) # Convert IP ranges to ip network object
        for line4 in read4:
            line4['Range']=ipaddress.ip_network(line4['Range']) # Convert IP ranges to ip network object
            if line3['Range'].netmask < line4['Range'].netmask: # To avoid "Not contained in" errors
                if line3['Range'].overlaps(line4['Range']): # Tests for IP overlap
                        for line4 in read4:
                            line4['Range']=ipaddress.ip_network(line4['Range'])
                            lst=list(line3['Range'].address_exclude(line4['Range'])) # List of subnets excluding line4 subnet
                            print (lst) # Temporary to view contents of lst
                            for val in lst:
                                line3['Range']=val # New range
                                line3[' IPStart']=val.network_address #New net address
                                line3[' IPStop']=val.broadcast_address #New broadcast address
                                writenum3.writerow(line3) # Write lines

使用此代码,我试图获取具有正确名称的新子网以写入文件 3。 file1 和 file2 都是代码开头的起始文件(基本上将其与自身进行比较)。这段代码有两个问题:

  1. 它一直工作到找到不包含在另一个子网中的子网为止。然后它返回ValueError: 10.24.1.0/28 not contained in 10.20.0.0/14(例如)。我试图通过使用if上面的语句来阻止这种情况的发生,以确保线路重叠并且被排除的 IP 子网的子网掩码大于排除的子网掩码,但它显然不起作用,我尝试了很多不同的尝试使它们工作的东西(将它们放在所有 for 语句之后,等等)。如果我能以某种方式绕过此错误并让它忽略该条目并继续比较其余条目,我认为它可以工作。

  2. 当子网被写入 file3 时,无论名称应该是什么,它们总是使用第一个区域名称“组 A”。

对于我可能遗漏的任何事情,我深表歉意,我仍然是编程的初学者。

任何帮助表示赞赏。

-B0T

4

1 回答 1

0

我的两个问题都通过重新排序 if 语句并正确重置迭代器来解决。代码仍然存在问题,但我在这里的问题已得到解答。

这是我当前的代码,效果更好:

import ipaddress
import csv
from csv import DictReader, DictWriter
from itertools import filterfalse

with open(r'file1.csv', newline='') as fin3,\
     open(r'file2.csv', newline='') as fin4,\
     open(r'file3.csv', 'w', newline='') as fout3:


    read3 = DictReader(fin3) # fin 3 and 4 are copies of the same file
    read4 = DictReader(fin4)

    writenum3 = DictWriter(fout3, fieldnames=read3.fieldnames) 
    writenum3.writeheader()

    lst4=[] # To prevent duplicate lines


    for line3 in read3:
        line3['Range']=ipaddress.ip_network(line3['Range']) # Convert IP ranges to ip network object
        fin4.seek(0) # Reset iterator
        read4 = DictReader(fin4) # Read again to prevent errors
        for line4 in read4:
            line4['Range']=ipaddress.ip_network(line4['Range']) # Convert IP ranges to ip network object
            if line3 not in lst4: # To prevent duplicate lines
                if line3['Range'].overlaps(line4['Range']): # Tests for IP overlap
                    if line3['Range'].netmask < line4['Range'].netmask: # To avoid "Not contained in" errors
                        lst=list(line3['Range'].address_exclude(line4['Range'])) # List of subnets excluding line4 subnet
                        for val in lst:
                            line3['Range']=val # New range
                            line3[' IPStart']=val.network_address #New net address
                            line3[' IPStop']=val.broadcast_address #New broadcast address
                            lst4.append(line3)
                            writenum3.writerow(line3) # Write lines

                    else:
                        lst4.append(line3)
                        writenum3.writerow(line3) # Write lines
                else:
                    lst4.append(line3)
                    writenum3.writerow(line3) # Write lines
于 2013-07-31T19:51:22.667 回答