VLSM子网划分
格式: 子网名称 + 主机数量,点击添加按钮添加到列表
暂无子网需求
子网合并
超网计算
网络规划
计算结果
使用说明
VLSM子网划分
  • 输入网络地址和子网掩码(CIDR格式)
  • 添加各个子网的主机需求
  • 系统自动计算最优的子网划分方案
  • 支持按主机数量优化排序
子网合并
  • 输入多个子网地址(每行一个)
  • 选择合并策略和选项
  • 系统计算最优的合并方案
  • 支持相邻和连续子网合并
超网计算
  • 输入IP地址范围(起始IP到结束IP)
  • 选择超网类型和计算选项
  • 系统计算包含该范围的最小超网
  • 支持自定义掩码位数
网络规划
  • 输入可用的地址空间
  • 添加各部门的主机需求
  • 选择规划策略和选项
  • 生成完整的网络规划方案
示例代码

各语言示例代码

  • SubnetCalculator (JAVA)
    SubnetCalculator.java
      1import java.util.*;
                          2import java.util.regex.Pattern;
                          3import java.util.regex.Matcher;
                          4
                          5/**
                          6 * 子网划分工具 - Java版本
                          7 * 支持VLSM可变长子网掩码、子网合并、超网计算、网络规划等功能
                          8 */
                          9public class SubnetCalculator {
                         10    private static final Pattern IP_PATTERN = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
                         11    private static final Pattern CIDR_PATTERN = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/([0-9]|[1-2][0-9]|3[0-2])$");
                         12
                         13    // 子网需求类
                         14    public static class SubnetRequirement {
                         15        private String name;
                         16        private int hosts;
                         17
                         18        public SubnetRequirement(String name, int hosts) {
                         19            this.name = name;
                         20            this.hosts = hosts;
                         21        }
                         22
                         23        public String getName() { return name; }
                         24        public int getHosts() { return hosts; }
                         25    }
                         26
                         27    // 部门需求类
                         28    public static class DepartmentRequirement {
                         29        private String name;
                         30        private int size;
                         31
                         32        public DepartmentRequirement(String name, int size) {
                         33            this.name = name;
                         34            this.size = size;
                         35        }
                         36
                         37        public String getName() { return name; }
                         38        public int getSize() { return size; }
                         39    }
                         40
                         41    // VLSM结果类
                         42    public static class VLSMResult {
                         43        private List<SubnetInfo> subnets;
                         44        private SummaryInfo summary;
                         45        private String details;
                         46
                         47        public VLSMResult(List<SubnetInfo> subnets, SummaryInfo summary, String details) {
                         48            this.subnets = subnets;
                         49            this.summary = summary;
                         50            this.details = details;
                         51        }
                         52
                         53        public List<SubnetInfo> getSubnets() { return subnets; }
                         54        public SummaryInfo getSummary() { return summary; }
                         55        public String getDetails() { return details; }
                         56    }
                         57
                         58    // 子网信息类
                         59    public static class SubnetInfo {
                         60        private String name;
                         61        private String networkAddress;
                         62        private String subnetMask;
                         63        private int cidr;
                         64        private String firstHost;
                         65        private String lastHost;
                         66        private String broadcastAddress;
                         67        private int usableHosts;
                         68        private int requiredHosts;
                         69
                         70        public SubnetInfo(String name, String networkAddress, String subnetMask, int cidr,
                         71                         String firstHost, String lastHost, String broadcastAddress,
                         72                         int usableHosts, int requiredHosts) {
                         73            this.name = name;
                         74            this.networkAddress = networkAddress;
                         75            this.subnetMask = subnetMask;
                         76            this.cidr = cidr;
                         77            this.firstHost = firstHost;
                         78            this.lastHost = lastHost;
                         79            this.broadcastAddress = broadcastAddress;
                         80            this.usableHosts = usableHosts;
                         81            this.requiredHosts = requiredHosts;
                         82        }
                         83
                         84        // Getters
                         85        public String getName() { return name; }
                         86        public String getNetworkAddress() { return networkAddress; }
                         87        public String getSubnetMask() { return subnetMask; }
                         88        public int getCidr() { return cidr; }
                         89        public String getFirstHost() { return firstHost; }
                         90        public String getLastHost() { return lastHost; }
                         91        public String getBroadcastAddress() { return broadcastAddress; }
                         92        public int getUsableHosts() { return usableHosts; }
                         93        public int getRequiredHosts() { return requiredHosts; }
                         94    }
                         95
                         96    // 汇总信息类
                         97    public static class SummaryInfo {
                         98        private String originalNetwork;
                         99        private int totalSubnets;
                        100        private int totalHosts;
                        101        private double utilization;
                        102
                        103        public SummaryInfo(String originalNetwork, int totalSubnets, int totalHosts, double utilization) {
                        104            this.originalNetwork = originalNetwork;
                        105            this.totalSubnets = totalSubnets;
                        106            this.totalHosts = totalHosts;
                        107            this.utilization = utilization;
                        108        }
                        109
                        110        // Getters
                        111        public String getOriginalNetwork() { return originalNetwork; }
                        112        public int getTotalSubnets() { return totalSubnets; }
                        113        public int getTotalHosts() { return totalHosts; }
                        114        public double getUtilization() { return utilization; }
                        115    }
                        116
                        117    // 合并结果类
                        118    public static class MergeResult {
                        119        private List<MergedSubnet> mergedSubnets;
                        120        private MergeSummary summary;
                        121        private String details;
                        122
                        123        public MergeResult(List<MergedSubnet> mergedSubnets, MergeSummary summary, String details) {
                        124            this.mergedSubnets = mergedSubnets;
                        125            this.summary = summary;
                        126            this.details = details;
                        127        }
                        128
                        129        public List<MergedSubnet> getMergedSubnets() { return mergedSubnets; }
                        130        public MergeSummary getSummary() { return summary; }
                        131        public String getDetails() { return details; }
                        132    }
                        133
                        134    // 合并后的子网类
                        135    public static class MergedSubnet {
                        136        private String network;
                        137        private List<String> originalSubnets;
                        138        private int hostCount;
                        139
                        140        public MergedSubnet(String network, List<String> originalSubnets, int hostCount) {
                        141            this.network = network;
                        142            this.originalSubnets = originalSubnets;
                        143            this.hostCount = hostCount;
                        144        }
                        145
                        146        // Getters
                        147        public String getNetwork() { return network; }
                        148        public List<String> getOriginalSubnets() { return originalSubnets; }
                        149        public int getHostCount() { return hostCount; }
                        150    }
                        151
                        152    // 合并汇总信息类
                        153    public static class MergeSummary {
                        154        private int originalCount;
                        155        private int mergedCount;
                        156        private int reduction;
                        157        private int totalHosts;
                        158        private double utilization;
                        159
                        160        public MergeSummary(int originalCount, int mergedCount, int reduction, int totalHosts, double utilization) {
                        161            this.originalCount = originalCount;
                        162            this.mergedCount = mergedCount;
                        163            this.reduction = reduction;
                        164            this.totalHosts = totalHosts;
                        165            this.utilization = utilization;
                        166        }
                        167
                        168        // Getters
                        169        public int getOriginalCount() { return originalCount; }
                        170        public int getMergedCount() { return mergedCount; }
                        171        public int getReduction() { return reduction; }
                        172        public int getTotalHosts() { return totalHosts; }
                        173        public double getUtilization() { return utilization; }
                        174    }
                        175
                        176    // 超网结果类
                        177    public static class SupernetResult {
                        178        private String networkAddress;
                        179        private String subnetMask;
                        180        private int cidr;
                        181        private String broadcastAddress;
                        182        private String firstHost;
                        183        private String lastHost;
                        184        private int totalHosts;
                        185        private String startIP;
                        186        private String endIP;
                        187        private String details;
                        188
                        189        public SupernetResult(String networkAddress, String subnetMask, int cidr,
                        190                            String broadcastAddress, String firstHost, String lastHost,
                        191                            int totalHosts, String startIP, String endIP, String details) {
                        192            this.networkAddress = networkAddress;
                        193            this.subnetMask = subnetMask;
                        194            this.cidr = cidr;
                        195            this.broadcastAddress = broadcastAddress;
                        196            this.firstHost = firstHost;
                        197            this.lastHost = lastHost;
                        198            this.totalHosts = totalHosts;
                        199            this.startIP = startIP;
                        200            this.endIP = endIP;
                        201            this.details = details;
                        202        }
                        203
                        204        // Getters
                        205        public String getNetworkAddress() { return networkAddress; }
                        206        public String getSubnetMask() { return subnetMask; }
                        207        public int getCidr() { return cidr; }
                        208        public String getBroadcastAddress() { return broadcastAddress; }
                        209        public String getFirstHost() { return firstHost; }
                        210        public String getLastHost() { return lastHost; }
                        211        public int getTotalHosts() { return totalHosts; }
                        212        public String getStartIP() { return startIP; }
                        213        public String getEndIP() { return endIP; }
                        214        public String getDetails() { return details; }
                        215    }
                        216
                        217    // 规划结果类
                        218    public static class PlanningResult {
                        219        private List<DepartmentInfo> departments;
                        220        private PlanningSummary summary;
                        221        private String details;
                        222
                        223        public PlanningResult(List<DepartmentInfo> departments, PlanningSummary summary, String details) {
                        224            this.departments = departments;
                        225            this.summary = summary;
                        226            this.details = details;
                        227        }
                        228
                        229        public List<DepartmentInfo> getDepartments() { return departments; }
                        230        public PlanningSummary getSummary() { return summary; }
                        231        public String getDetails() { return details; }
                        232    }
                        233
                        234    // 部门信息类
                        235    public static class DepartmentInfo {
                        236        private String name;
                        237        private String networkAddress;
                        238        private String subnetMask;
                        239        private int cidr;
                        240        private String firstHost;
                        241        private String lastHost;
                        242        private int allocatedHosts;
                        243        private int totalHosts;
                        244
                        245        public DepartmentInfo(String name, String networkAddress, String subnetMask, int cidr,
                        246                            String firstHost, String lastHost, int allocatedHosts, int totalHosts) {
                        247            this.name = name;
                        248            this.networkAddress = networkAddress;
                        249            this.subnetMask = subnetMask;
                        250            this.cidr = cidr;
                        251            this.firstHost = firstHost;
                        252            this.lastHost = lastHost;
                        253            this.allocatedHosts = allocatedHosts;
                        254            this.totalHosts = totalHosts;
                        255        }
                        256
                        257        // Getters
                        258        public String getName() { return name; }
                        259        public String getNetworkAddress() { return networkAddress; }
                        260        public String getSubnetMask() { return subnetMask; }
                        261        public int getCidr() { return cidr; }
                        262        public String getFirstHost() { return firstHost; }
                        263        public String getLastHost() { return lastHost; }
                        264        public int getAllocatedHosts() { return allocatedHosts; }
                        265        public int getTotalHosts() { return totalHosts; }
                        266    }
                        267
                        268    // 规划汇总信息类
                        269    public static class PlanningSummary {
                        270        private int totalSpace;
                        271        private int allocatedSpace;
                        272        private int remainingSpace;
                        273        private double utilization;
                        274        private int departmentCount;
                        275
                        276        public PlanningSummary(int totalSpace, int allocatedSpace, int remainingSpace,
                        277                             double utilization, int departmentCount) {
                        278            this.totalSpace = totalSpace;
                        279            this.allocatedSpace = allocatedSpace;
                        280            this.remainingSpace = remainingSpace;
                        281            this.utilization = utilization;
                        282            this.departmentCount = departmentCount;
                        283        }
                        284
                        285        // Getters
                        286        public int getTotalSpace() { return totalSpace; }
                        287        public int getAllocatedSpace() { return allocatedSpace; }
                        288        public int getRemainingSpace() { return remainingSpace; }
                        289        public double getUtilization() { return utilization; }
                        290        public int getDepartmentCount() { return departmentCount; }
                        291    }
                        292
                        293    /**
                        294     * 验证IP地址格式
                        295     */
                        296    public boolean validateIP(String ip) {
                        297        return IP_PATTERN.matcher(ip).matches();
                        298    }
                        299
                        300    /**
                        301     * 验证CIDR格式
                        302     */
                        303    public boolean validateCIDR(String cidr) {
                        304        return CIDR_PATTERN.matcher(cidr).matches();
                        305    }
                        306
                        307    /**
                        308     * IP地址转换为长整数
                        309     */
                        310    public long ipToLong(String ip) throws IllegalArgumentException {
                        311        if (!validateIP(ip)) {
                        312            throw new IllegalArgumentException("无效的IP地址格式");
                        313        }
                        314
                        315        String[] parts = ip.split("\\.");
                        316        long result = 0;
                        317        for (int i = 0; i < 4; i++) {
                        318            result = result << 8 | Integer.parseInt(parts[i]);
                        319        }
                        320        return result;
                        321    }
                        322
                        323    /**
                        324     * 长整数转换为IP地址
                        325     */
                        326    public String longToIP(long ipLong) {
                        327        return String.format("%d.%d.%d.%d",
                        328                (ipLong >> 24) & 0xFF,
                        329                (ipLong >> 16) & 0xFF,
                        330                (ipLong >> 8) & 0xFF,
                        331                ipLong & 0xFF);
                        332    }
                        333
                        334    /**
                        335     * 获取子网掩码
                        336     */
                        337    public String getSubnetMask(int cidr) {
                        338        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        339        return longToIP(mask);
                        340    }
                        341
                        342    /**
                        343     * 获取网络地址
                        344     */
                        345    public String getNetworkAddress(String ip, int cidr) throws IllegalArgumentException {
                        346        long ipLong = ipToLong(ip);
                        347        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        348        long networkLong = ipLong & mask;
                        349        return longToIP(networkLong);
                        350    }
                        351
                        352    /**
                        353     * 获取广播地址
                        354     */
                        355    public String getBroadcastAddress(String ip, int cidr) throws IllegalArgumentException {
                        356        long ipLong = ipToLong(ip);
                        357        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        358        long broadcastLong = ipLong | (~mask & 0xFFFFFFFFL);
                        359        return longToIP(broadcastLong);
                        360    }
                        361
                        362    /**
                        363     * 获取第一个可用主机地址
                        364     */
                        365    public String getFirstHost(String ip, int cidr) throws IllegalArgumentException {
                        366        String networkIP = getNetworkAddress(ip, cidr);
                        367        long networkLong = ipToLong(networkIP);
                        368        return longToIP(networkLong + 1);
                        369    }
                        370
                        371    /**
                        372     * 获取最后一个可用主机地址
                        373     */
                        374    public String getLastHost(String ip, int cidr) throws IllegalArgumentException {
                        375        String broadcastIP = getBroadcastAddress(ip, cidr);
                        376        long broadcastLong = ipToLong(broadcastIP);
                        377        return longToIP(broadcastLong - 1);
                        378    }
                        379
                        380    /**
                        381     * 计算可用主机数量
                        382     */
                        383    public int getUsableHosts(int cidr) {
                        384        return (int) (Math.pow(2, 32 - cidr) - 2);
                        385    }
                        386
                        387    /**
                        388     * 解析CIDR格式
                        389     */
                        390    public String[] parseCIDR(String cidr) throws IllegalArgumentException {
                        391        if (!validateCIDR(cidr)) {
                        392            throw new IllegalArgumentException("无效的CIDR格式");
                        393        }
                        394
                        395        String[] parts = cidr.split("/");
                        396        return new String[]{parts[0], parts[1]};
                        397    }
                        398
                        399    /**
                        400     * VLSM子网划分
                        401     */
                        402    public VLSMResult calculateVLSM(String networkCIDR, List<SubnetRequirement> subnetRequirements,
                        403                                  Map<String, Object> options) throws IllegalArgumentException {
                        404        String[] parsed = parseCIDR(networkCIDR);
                        405        String networkIP = parsed[0];
                        406        int networkCIDRBits = Integer.parseInt(parsed[1]);
                        407
                        408        String networkAddress = getNetworkAddress(networkIP, networkCIDRBits);
                        409        long networkLong = ipToLong(networkAddress);
                        410        int totalHosts = getUsableHosts(networkCIDRBits);
                        411
                        412        // 按主机数量排序(如果需要)
                        413        List<SubnetRequirement> sortedRequirements = new ArrayList<>(subnetRequirements);
                        414        if (options != null && options.containsKey("optimize_order") && 
                        415            (Boolean) options.get("optimize_order")) {
                        416            sortedRequirements.sort((a, b) -> Integer.compare(b.getHosts(), a.getHosts()));
                        417        }
                        418
                        419        // 计算每个子网需要的掩码位数
                        420        List<SubnetInfo> subnets = new ArrayList<>();
                        421        long currentNetworkLong = networkLong;
                        422
                        423        for (SubnetRequirement requirement : sortedRequirements) {
                        424            int requiredHosts = requirement.getHosts();
                        425            if (options != null && options.containsKey("include_network_broadcast") && 
                        426                (Boolean) options.get("include_network_broadcast")) {
                        427                requiredHosts += 2;
                        428            }
                        429
                        430            int requiredCIDR = 32 - (int) Math.ceil(Math.log(requiredHosts) / Math.log(2));
                        431
                        432            if (requiredCIDR < networkCIDRBits) {
                        433                throw new IllegalArgumentException("子网 " + requirement.getName() + " 需要的主机数超出可用空间");
                        434            }
                        435
                        436            String subnetNetworkIP = longToIP(currentNetworkLong);
                        437            String subnetMask = getSubnetMask(requiredCIDR);
                        438            int subnetHosts = getUsableHosts(requiredCIDR);
                        439
                        440            String firstHost = getFirstHost(subnetNetworkIP, requiredCIDR);
                        441            String lastHost = getLastHost(subnetNetworkIP, requiredCIDR);
                        442            String broadcastAddress = getBroadcastAddress(subnetNetworkIP, requiredCIDR);
                        443
                        444            subnets.add(new SubnetInfo(
                        445                    requirement.getName(),
                        446                    subnetNetworkIP,
                        447                    subnetMask,
                        448                    requiredCIDR,
                        449                    firstHost,
                        450                    lastHost,
                        451                    broadcastAddress,
                        452                    subnetHosts,
                        453                    requirement.getHosts()
                        454            ));
                        455
                        456            // 计算下一个子网的起始地址
                        457            long subnetSize = (long) Math.pow(2, 32 - requiredCIDR);
                        458            currentNetworkLong += subnetSize;
                        459        }
                        460
                        461        // 计算汇总信息
                        462        int totalRequiredHosts = sortedRequirements.stream().mapToInt(SubnetRequirement::getHosts).sum();
                        463        double utilization = (double) totalRequiredHosts / totalHosts * 100;
                        464
                        465        return new VLSMResult(
                        466                subnets,
                        467                new SummaryInfo(networkCIDR, subnets.size(), totalRequiredHosts, utilization),
                        468                String.format("VLSM划分完成,共创建 %d 个子网,地址利用率 %.2f%%", subnets.size(), utilization)
                        469        );
                        470    }
                        471
                        472    /**
                        473     * 子网合并
                        474     */
                        475    public MergeResult mergeSubnets(List<String> subnetList, Map<String, Object> options) 
                        476            throws IllegalArgumentException {
                        477        List<SubnetData> subnets = new ArrayList<>();
                        478
                        479        // 解析子网列表
                        480        for (String subnetStr : subnetList) {
                        481            if (!validateCIDR(subnetStr)) {
                        482                if (options != null && options.containsKey("validate_subnets") && 
                        483                    (Boolean) options.get("validate_subnets")) {
                        484                    throw new IllegalArgumentException("无效的子网格式: " + subnetStr);
                        485                }
                        486                continue;
                        487            }
                        488
                        489            String[] parsed = parseCIDR(subnetStr);
                        490            String ip = parsed[0];
                        491            int cidr = Integer.parseInt(parsed[1]);
                        492
                        493            String networkIP = getNetworkAddress(ip, cidr);
                        494            long networkLong = ipToLong(networkIP);
                        495
                        496            subnets.add(new SubnetData(subnetStr, networkIP, cidr, networkLong, getUsableHosts(cidr)));
                        497        }
                        498
                        499        if (subnets.isEmpty()) {
                        500            throw new IllegalArgumentException("没有有效的子网可以合并");
                        501        }
                        502
                        503        // 按网络地址排序
                        504        subnets.sort(Comparator.comparingLong(SubnetData::getNetworkLong));
                        505
                        506        List<MergedSubnet> mergedSubnets = new ArrayList<>();
                        507        List<SubnetData> currentGroup = new ArrayList<>();
                        508        currentGroup.add(subnets.get(0));
                        509
                        510        for (int i = 1; i < subnets.size(); i++) {
                        511            SubnetData current = subnets.get(i);
                        512            SubnetData last = currentGroup.get(currentGroup.size() - 1);
                        513
                        514            // 检查是否相邻或连续
                        515            boolean isAdjacent = false;
                        516            boolean isContiguous = false;
                        517
                        518            if (options != null && options.containsKey("merge_adjacent") && 
                        519                (Boolean) options.get("merge_adjacent")) {
                        520                isAdjacent = areSubnetsAdjacent(last, current);
                        521            }
                        522
                        523            if (options != null && options.containsKey("merge_contiguous") && 
                        524                (Boolean) options.get("merge_contiguous")) {
                        525                isContiguous = areSubnetsContiguous(last, current);
                        526            }
                        527
                        528            if (isAdjacent || isContiguous) {
                        529                currentGroup.add(current);
                        530            } else {
                        531                // 合并当前组
                        532                if (currentGroup.size() > 1) {
                        533                    mergedSubnets.add(mergeSubnetGroup(currentGroup));
                        534                } else {
                        535                    List<String> originalSubnets = new ArrayList<>();
                        536                    originalSubnets.add(currentGroup.get(0).getNetwork());
                        537                    mergedSubnets.add(new MergedSubnet(
                        538                            currentGroup.get(0).getNetwork(),
                        539                            originalSubnets,
                        540                            currentGroup.get(0).getHostCount()
                        541                    ));
                        542                }
                        543                currentGroup = new ArrayList<>();
                        544                currentGroup.add(current);
                        545            }
                        546        }
                        547
                        548        // 处理最后一组
                        549        if (currentGroup.size() > 1) {
                        550            mergedSubnets.add(mergeSubnetGroup(currentGroup));
                        551        } else {
                        552            List<String> originalSubnets = new ArrayList<>();
                        553            originalSubnets.add(currentGroup.get(0).getNetwork());
                        554            mergedSubnets.add(new MergedSubnet(
                        555                    currentGroup.get(0).getNetwork(),
                        556                    originalSubnets,
                        557                    currentGroup.get(0).getHostCount()
                        558            ));
                        559        }
                        560
                        561        // 计算汇总信息
                        562        int originalCount = subnets.size();
                        563        int mergedCount = mergedSubnets.size();
                        564        int reduction = originalCount - mergedCount;
                        565        int totalHosts = mergedSubnets.stream().mapToInt(MergedSubnet::getHostCount).sum();
                        566
                        567        return new MergeResult(
                        568                mergedSubnets,
                        569                new MergeSummary(originalCount, mergedCount, reduction, totalHosts, 
                        570                               (double) totalHosts / 0xFFFFFFFFL * 100),
                        571                String.format("合并完成,从 %d 个子网合并为 %d 个,减少 %d 个", originalCount, mergedCount, reduction)
                        572        );
                        573    }
                        574
                        575    // 子网数据内部类
                        576    private static class SubnetData {
                        577        private String network;
                        578        private String networkIP;
                        579        private int cidr;
                        580        private long networkLong;
                        581        private int hostCount;
                        582
                        583        public SubnetData(String network, String networkIP, int cidr, long networkLong, int hostCount) {
                        584            this.network = network;
                        585            this.networkIP = networkIP;
                        586            this.cidr = cidr;
                        587            this.networkLong = networkLong;
                        588            this.hostCount = hostCount;
                        589        }
                        590
                        591        public String getNetwork() { return network; }
                        592        public String getNetworkIP() { return networkIP; }
                        593        public int getCidr() { return cidr; }
                        594        public long getNetworkLong() { return networkLong; }
                        595        public int getHostCount() { return hostCount; }
                        596    }
                        597
                        598    /**
                        599     * 检查两个子网是否相邻
                        600     */
                        601    private boolean areSubnetsAdjacent(SubnetData subnet1, SubnetData subnet2) {
                        602        String broadcast1 = getBroadcastAddress(subnet1.getNetworkIP(), subnet1.getCidr());
                        603        long broadcast1Long = ipToLong(broadcast1);
                        604        return subnet2.getNetworkLong() == broadcast1Long + 1;
                        605    }
                        606
                        607    /**
                        608     * 检查两个子网是否连续
                        609     */
                        610    private boolean areSubnetsContiguous(SubnetData subnet1, SubnetData subnet2) {
                        611        String broadcast1 = getBroadcastAddress(subnet1.getNetworkIP(), subnet1.getCidr());
                        612        long broadcast1Long = ipToLong(broadcast1);
                        613        return subnet2.getNetworkLong() <= broadcast1Long + 1;
                        614    }
                        615
                        616    /**
                        617     * 合并子网组
                        618     */
                        619    private MergedSubnet mergeSubnetGroup(List<SubnetData> subnetGroup) {
                        620        SubnetData first = subnetGroup.get(0);
                        621        SubnetData last = subnetGroup.get(subnetGroup.size() - 1);
                        622        String lastBroadcast = getBroadcastAddress(last.getNetworkIP(), last.getCidr());
                        623        long lastBroadcastLong = ipToLong(lastBroadcast);
                        624
                        625        // 计算合并后的CIDR
                        626        long rangeSize = lastBroadcastLong - first.getNetworkLong() + 1;
                        627        int mergedCIDR = 32 - (int) Math.ceil(Math.log(rangeSize) / Math.log(2));
                        628
                        629        String mergedNetworkIP = longToIP(first.getNetworkLong());
                        630        String mergedNetwork = mergedNetworkIP + "/" + mergedCIDR;
                        631        int mergedHostCount = getUsableHosts(mergedCIDR);
                        632
                        633        List<String> originalSubnets = new ArrayList<>();
                        634        for (SubnetData subnet : subnetGroup) {
                        635            originalSubnets.add(subnet.getNetwork());
                        636        }
                        637
                        638        return new MergedSubnet(mergedNetwork, originalSubnets, mergedHostCount);
                        639    }
                        640
                        641    /**
                        642     * 超网计算
                        643     */
                        644    public SupernetResult calculateSupernet(String startIP, String endIP, Map<String, Object> options) 
                        645            throws IllegalArgumentException {
                        646        if (!validateIP(startIP) || !validateIP(endIP)) {
                        647            throw new IllegalArgumentException("无效的IP地址格式");
                        648        }
                        649
                        650        long startLong = ipToLong(startIP);
                        651        long endLong = ipToLong(endIP);
                        652
                        653        if (startLong > endLong) {
                        654            throw new IllegalArgumentException("起始IP不能大于结束IP");
                        655        }
                        656
                        657        // 计算包含该范围的最小超网
                        658        long rangeSize = endLong - startLong + 1;
                        659        int requiredCIDR = 32 - (int) Math.ceil(Math.log(rangeSize) / Math.log(2));
                        660
                        661        // 找到包含该范围的最小网络地址
                        662        long mask = (0xFFFFFFFFL << (32 - requiredCIDR)) & 0xFFFFFFFFL;
                        663        long networkLong = startLong & mask;
                        664        String networkIP = longToIP(networkLong);
                        665
                        666        // 验证该网络是否包含整个范围
                        667        long broadcastLong = networkLong | (~mask & 0xFFFFFFFFL);
                        668        if (broadcastLong < endLong) {
                        669            // 需要更大的网络
                        670            int newCIDR = requiredCIDR - 1;
                        671            long newMask = (0xFFFFFFFFL << (32 - newCIDR)) & 0xFFFFFFFFL;
                        672            long newNetworkLong = startLong & newMask;
                        673            String newNetworkIP = longToIP(newNetworkLong);
                        674
                        675            return new SupernetResult(
                        676                    newNetworkIP,
                        677                    getSubnetMask(newCIDR),
                        678                    newCIDR,
                        679                    longToIP(newNetworkLong | (~newMask & 0xFFFFFFFFL)),
                        680                    longToIP(newNetworkLong + 1),
                        681                    longToIP((newNetworkLong | (~newMask & 0xFFFFFFFFL)) - 1),
                        682                    getUsableHosts(newCIDR),
                        683                    startIP,
                        684                    endIP,
                        685                    String.format("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, newNetworkIP, newCIDR)
                        686            );
                        687        }
                        688
                        689        return new SupernetResult(
                        690                networkIP,
                        691                getSubnetMask(requiredCIDR),
                        692                requiredCIDR,
                        693                longToIP(broadcastLong),
                        694                longToIP(networkLong + 1),
                        695                longToIP(broadcastLong - 1),
                        696                getUsableHosts(requiredCIDR),
                        697                startIP,
                        698                endIP,
                        699                String.format("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, networkIP, requiredCIDR)
                        700        );
                        701    }
                        702
                        703    /**
                        704     * 网络规划
                        705     */
                        706    public PlanningResult generateNetworkPlan(String addressSpace, List<DepartmentRequirement> departmentRequirements,
                        707                                            Map<String, Object> options) throws IllegalArgumentException {
                        708        String[] parsed = parseCIDR(addressSpace);
                        709        String networkIP = parsed[0];
                        710        int networkCIDRBits = Integer.parseInt(parsed[1]);
                        711
                        712        String networkAddress = getNetworkAddress(networkIP, networkCIDRBits);
                        713        long networkLong = ipToLong(networkAddress);
                        714        int totalSpace = getUsableHosts(networkCIDRBits);
                        715
                        716        // 按部门大小排序
                        717        List<DepartmentRequirement> sortedDepartments = new ArrayList<>(departmentRequirements);
                        718        if (options != null && options.containsKey("optimize_utilization") && 
                        719            (Boolean) options.get("optimize_utilization")) {
                        720            sortedDepartments.sort((a, b) -> Integer.compare(b.getSize(), a.getSize()));
                        721        }
                        722
                        723        List<DepartmentInfo> departments = new ArrayList<>();
                        724        long currentNetworkLong = networkLong;
                        725        int allocatedSpace = 0;
                        726
                        727        for (DepartmentRequirement dept : sortedDepartments) {
                        728            int requiredHosts = dept.getSize();
                        729            if (options != null && options.containsKey("reserve_space") && 
                        730                (Boolean) options.get("reserve_space")) {
                        731                requiredHosts += (int) Math.ceil(dept.getSize() * 0.2);
                        732            }
                        733
                        734            int requiredCIDR = 32 - (int) Math.ceil(Math.log(requiredHosts + 2) / Math.log(2)); // +2 for network and broadcast
                        735
                        736            if (requiredCIDR < networkCIDRBits) {
                        737                throw new IllegalArgumentException("部门 " + dept.getName() + " 需要的主机数超出可用空间");
                        738            }
                        739
                        740            String deptNetworkIP = longToIP(currentNetworkLong);
                        741            String deptSubnetMask = getSubnetMask(requiredCIDR);
                        742            int deptHosts = getUsableHosts(requiredCIDR);
                        743
                        744            String firstHost = getFirstHost(deptNetworkIP, requiredCIDR);
                        745            String lastHost = getLastHost(deptNetworkIP, requiredCIDR);
                        746
                        747            departments.add(new DepartmentInfo(
                        748                    dept.getName(),
                        749                    deptNetworkIP,
                        750                    deptSubnetMask,
                        751                    requiredCIDR,
                        752                    firstHost,
                        753                    lastHost,
                        754                    dept.getSize(),
                        755                    deptHosts
                        756            ));
                        757
                        758            allocatedSpace += deptHosts;
                        759            long subnetSize = (long) Math.pow(2, 32 - requiredCIDR);
                        760            currentNetworkLong += subnetSize;
                        761        }
                        762
                        763        int remainingSpace = totalSpace - allocatedSpace;
                        764        double utilization = (double) allocatedSpace / totalSpace * 100;
                        765
                        766        return new PlanningResult(
                        767                departments,
                        768                new PlanningSummary(totalSpace, allocatedSpace, remainingSpace, utilization, departments.size()),
                        769                String.format("网络规划完成,共分配 %d 个部门,地址利用率 %.2f%%,剩余空间 %d 个主机", 
                        770                            departments.size(), utilization, remainingSpace)
                        771        );
                        772    }
                        773
                        774    public static void main(String[] args) {
                        775        SubnetCalculator calculator = new SubnetCalculator();
                        776
                        777        System.out.println("=== 子网划分工具 - Java版本 ===");
                        778
                        779        // VLSM示例
                        780        System.out.println("\n--- VLSM子网划分示例 ---");
                        781        try {
                        782            List<SubnetRequirement> requirements = Arrays.asList(
                        783                    new SubnetRequirement("销售部", 50),
                        784                    new SubnetRequirement("技术部", 30),
                        785                    new SubnetRequirement("财务部", 10),
                        786                    new SubnetRequirement("人事部", 5)
                        787            );
                        788
                        789            Map<String, Object> options = new HashMap<>();
                        790            options.put("optimize_order", true);
                        791            options.put("include_network_broadcast", true);
                        792
                        793            VLSMResult vlsmResult = calculator.calculateVLSM("192.168.1.0/24", requirements, options);
                        794            System.out.println("VLSM结果:");
                        795            for (SubnetInfo subnet : vlsmResult.getSubnets()) {
                        796                System.out.printf("  %s: %s/%d (%s - %s)%n", 
                        797                                subnet.getName(), subnet.getNetworkAddress(), subnet.getCidr(),
                        798                                subnet.getFirstHost(), subnet.getLastHost());
                        799            }
                        800            System.out.printf("汇总: 原始网络=%s, 总子网数=%d, 总主机数=%d, 利用率=%.2f%%%n",
                        801                            vlsmResult.getSummary().getOriginalNetwork(),
                        802                            vlsmResult.getSummary().getTotalSubnets(),
                        803                            vlsmResult.getSummary().getTotalHosts(),
                        804                            vlsmResult.getSummary().getUtilization());
                        805        } catch (Exception e) {
                        806            System.err.println("VLSM错误: " + e.getMessage());
                        807        }
                        808
                        809        // 子网合并示例
                        810        System.out.println("\n--- 子网合并示例 ---");
                        811        try {
                        812            List<String> subnetList = Arrays.asList(
                        813                    "192.168.1.0/26",
                        814                    "192.168.1.64/26",
                        815                    "192.168.1.128/26",
                        816                    "192.168.1.192/26"
                        817            );
                        818
                        819            Map<String, Object> options = new HashMap<>();
                        820            options.put("merge_adjacent", true);
                        821            options.put("merge_contiguous", true);
                        822            options.put("validate_subnets", true);
                        823
                        824            MergeResult mergeResult = calculator.mergeSubnets(subnetList, options);
                        825            System.out.println("合并结果:");
                        826            for (MergedSubnet merged : mergeResult.getMergedSubnets()) {
                        827                System.out.printf("  %s (包含: %s)%n", merged.getNetwork(), 
                        828                                String.join(", ", merged.getOriginalSubnets()));
                        829            }
                        830            System.out.printf("汇总: 原子网数=%d, 合并后=%d, 减少=%d, 利用率=%.4f%%%n",
                        831                            mergeResult.getSummary().getOriginalCount(),
                        832                            mergeResult.getSummary().getMergedCount(),
                        833                            mergeResult.getSummary().getReduction(),
                        834                            mergeResult.getSummary().getUtilization());
                        835        } catch (Exception e) {
                        836            System.err.println("合并错误: " + e.getMessage());
                        837        }
                        838
                        839        // 超网计算示例
                        840        System.out.println("\n--- 超网计算示例 ---");
                        841        try {
                        842            SupernetResult supernetResult = calculator.calculateSupernet("192.168.1.10", "192.168.1.50", null);
                        843            System.out.printf("超网结果: %s/%d%n", supernetResult.getNetworkAddress(), supernetResult.getCidr());
                        844            System.out.printf("详细信息: %s%n", supernetResult.getDetails());
                        845        } catch (Exception e) {
                        846            System.err.println("超网错误: " + e.getMessage());
                        847        }
                        848
                        849        // 网络规划示例
                        850        System.out.println("\n--- 网络规划示例 ---");
                        851        try {
                        852            List<DepartmentRequirement> deptRequirements = Arrays.asList(
                        853                    new DepartmentRequirement("总部", 200),
                        854                    new DepartmentRequirement("分公司A", 100),
                        855                    new DepartmentRequirement("分公司B", 80),
                        856                    new DepartmentRequirement("研发中心", 150)
                        857            );
                        858
                        859            Map<String, Object> options = new HashMap<>();
                        860            options.put("optimize_utilization", true);
                        861            options.put("reserve_space", true);
                        862
                        863            PlanningResult planningResult = calculator.generateNetworkPlan("10.0.0.0/8", deptRequirements, options);
                        864            System.out.println("规划结果:");
                        865            for (DepartmentInfo dept : planningResult.getDepartments()) {
                        866                System.out.printf("  %s: %s/%d (%d 主机)%n", dept.getName(), 
                        867                                dept.getNetworkAddress(), dept.getCidr(), dept.getAllocatedHosts());
                        868            }
                        869            System.out.printf("汇总: 总空间=%d, 已分配=%d, 剩余=%d, 利用率=%.2f%%, 部门数=%d%n",
                        870                            planningResult.getSummary().getTotalSpace(),
                        871                            planningResult.getSummary().getAllocatedSpace(),
                        872                            planningResult.getSummary().getRemainingSpace(),
                        873                            planningResult.getSummary().getUtilization(),
                        874                            planningResult.getSummary().getDepartmentCount());
                        875        } catch (Exception e) {
                        876            System.err.println("规划错误: " + e.getMessage());
                        877        }
                        878    }
                        879}
                        
  • subnet_calculator (GO)
    subnet_calculator.go
      1package main
                          2
                          3import (
                          4	"fmt"
                          5	"math"
                          6	"net"
                          7	"regexp"
                          8	"sort"
                          9	"strconv"
                         10	"strings"
                         11)
                         12
                         13// SubnetCalculator 子网划分计算器结构体
                         14type SubnetCalculator struct {
                         15	ipRegex   *regexp.Regexp
                         16	cidrRegex *regexp.Regexp
                         17}
                         18
                         19// SubnetRequirement 子网需求结构体
                         20type SubnetRequirement struct {
                         21	Name  string `json:"name"`
                         22	Hosts int    `json:"hosts"`
                         23}
                         24
                         25// DepartmentRequirement 部门需求结构体
                         26type DepartmentRequirement struct {
                         27	Name string `json:"name"`
                         28	Size int    `json:"size"`
                         29}
                         30
                         31// VLSMResult VLSM计算结果结构体
                         32type VLSMResult struct {
                         33	Subnets []SubnetInfo `json:"subnets"`
                         34	Summary SummaryInfo  `json:"summary"`
                         35	Details string       `json:"details"`
                         36}
                         37
                         38// SubnetInfo 子网信息结构体
                         39type SubnetInfo struct {
                         40	Name             string `json:"name"`
                         41	NetworkAddress   string `json:"network_address"`
                         42	SubnetMask       string `json:"subnet_mask"`
                         43	CIDR             int    `json:"cidr"`
                         44	FirstHost        string `json:"first_host"`
                         45	LastHost         string `json:"last_host"`
                         46	BroadcastAddress string `json:"broadcast_address"`
                         47	UsableHosts      int    `json:"usable_hosts"`
                         48	RequiredHosts    int    `json:"required_hosts"`
                         49}
                         50
                         51// SummaryInfo 汇总信息结构体
                         52type SummaryInfo struct {
                         53	OriginalNetwork string  `json:"original_network"`
                         54	TotalSubnets    int     `json:"total_subnets"`
                         55	TotalHosts      int     `json:"total_hosts"`
                         56	Utilization     float64 `json:"utilization"`
                         57}
                         58
                         59// MergeResult 子网合并结果结构体
                         60type MergeResult struct {
                         61	MergedSubnets []MergedSubnet `json:"merged_subnets"`
                         62	Summary       MergeSummary   `json:"summary"`
                         63	Details       string         `json:"details"`
                         64}
                         65
                         66// MergedSubnet 合并后的子网结构体
                         67type MergedSubnet struct {
                         68	Network         string   `json:"network"`
                         69	OriginalSubnets []string `json:"original_subnets"`
                         70	HostCount       int      `json:"host_count"`
                         71}
                         72
                         73// MergeSummary 合并汇总信息结构体
                         74type MergeSummary struct {
                         75	OriginalCount int     `json:"original_count"`
                         76	MergedCount   int     `json:"merged_count"`
                         77	Reduction     int     `json:"reduction"`
                         78	TotalHosts    int     `json:"total_hosts"`
                         79	Utilization   float64 `json:"utilization"`
                         80}
                         81
                         82// SupernetResult 超网计算结果结构体
                         83type SupernetResult struct {
                         84	NetworkAddress   string `json:"network_address"`
                         85	SubnetMask       string `json:"subnet_mask"`
                         86	CIDR             int    `json:"cidr"`
                         87	BroadcastAddress string `json:"broadcast_address"`
                         88	FirstHost        string `json:"first_host"`
                         89	LastHost         string `json:"last_host"`
                         90	TotalHosts       int    `json:"total_hosts"`
                         91	StartIP          string `json:"start_ip"`
                         92	EndIP            string `json:"end_ip"`
                         93	Details          string `json:"details"`
                         94}
                         95
                         96// PlanningResult 网络规划结果结构体
                         97type PlanningResult struct {
                         98	Departments []DepartmentInfo `json:"departments"`
                         99	Summary     PlanningSummary  `json:"summary"`
                        100	Details     string           `json:"details"`
                        101}
                        102
                        103// DepartmentInfo 部门信息结构体
                        104type DepartmentInfo struct {
                        105	Name           string `json:"name"`
                        106	NetworkAddress string `json:"network_address"`
                        107	SubnetMask     string `json:"subnet_mask"`
                        108	CIDR           int    `json:"cidr"`
                        109	FirstHost      string `json:"first_host"`
                        110	LastHost       string `json:"last_host"`
                        111	AllocatedHosts int    `json:"allocated_hosts"`
                        112	TotalHosts     int    `json:"total_hosts"`
                        113}
                        114
                        115// PlanningSummary 规划汇总信息结构体
                        116type PlanningSummary struct {
                        117	TotalSpace      int     `json:"total_space"`
                        118	AllocatedSpace  int     `json:"allocated_space"`
                        119	RemainingSpace  int     `json:"remaining_space"`
                        120	Utilization     float64 `json:"utilization"`
                        121	DepartmentCount int     `json:"department_count"`
                        122}
                        123
                        124// NewSubnetCalculator 创建新的子网计算器
                        125func NewSubnetCalculator() *SubnetCalculator {
                        126	return &SubnetCalculator{
                        127		ipRegex:   regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`),
                        128		cidrRegex: regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]|[1-2][0-9]|3[0-2])$`),
                        129	}
                        130}
                        131
                        132// ValidateIP 验证IP地址格式
                        133func (c *SubnetCalculator) ValidateIP(ip string) bool {
                        134	return c.ipRegex.MatchString(ip)
                        135}
                        136
                        137// ValidateCIDR 验证CIDR格式
                        138func (c *SubnetCalculator) ValidateCIDR(cidr string) bool {
                        139	return c.cidrRegex.MatchString(cidr)
                        140}
                        141
                        142// IPToInt IP地址转换为整数
                        143func (c *SubnetCalculator) IPToInt(ip string) (uint32, error) {
                        144	if !c.ValidateIP(ip) {
                        145		return 0, fmt.Errorf("无效的IP地址格式")
                        146	}
                        147
                        148	parts := strings.Split(ip, ".")
                        149	var result uint32
                        150	for i, part := range parts {
                        151		num, err := strconv.Atoi(part)
                        152		if err != nil {
                        153			return 0, err
                        154		}
                        155		result |= uint32(num) << ((3 - i) * 8)
                        156	}
                        157	return result, nil
                        158}
                        159
                        160// IntToIP 整数转换为IP地址
                        161func (c *SubnetCalculator) IntToIP(ipInt uint32) string {
                        162	return fmt.Sprintf("%d.%d.%d.%d",
                        163		(ipInt>>24)&255,
                        164		(ipInt>>16)&255,
                        165		(ipInt>>8)&255,
                        166		ipInt&255)
                        167}
                        168
                        169// GetSubnetMask 获取子网掩码
                        170func (c *SubnetCalculator) GetSubnetMask(cidr int) string {
                        171	mask := uint32(0xFFFFFFFF) << (32 - cidr)
                        172	return c.IntToIP(mask)
                        173}
                        174
                        175// GetNetworkAddress 获取网络地址
                        176func (c *SubnetCalculator) GetNetworkAddress(ip string, cidr int) (string, error) {
                        177	ipInt, err := c.IPToInt(ip)
                        178	if err != nil {
                        179		return "", err
                        180	}
                        181	mask := uint32(0xFFFFFFFF) << (32 - cidr)
                        182	networkInt := ipInt & mask
                        183	return c.IntToIP(networkInt), nil
                        184}
                        185
                        186// GetBroadcastAddress 获取广播地址
                        187func (c *SubnetCalculator) GetBroadcastAddress(ip string, cidr int) (string, error) {
                        188	ipInt, err := c.IPToInt(ip)
                        189	if err != nil {
                        190		return "", err
                        191	}
                        192	mask := uint32(0xFFFFFFFF) << (32 - cidr)
                        193	broadcastInt := ipInt | ^mask
                        194	return c.IntToIP(broadcastInt), nil
                        195}
                        196
                        197// GetFirstHost 获取第一个可用主机地址
                        198func (c *SubnetCalculator) GetFirstHost(ip string, cidr int) (string, error) {
                        199	networkIP, err := c.GetNetworkAddress(ip, cidr)
                        200	if err != nil {
                        201		return "", err
                        202	}
                        203	networkInt, err := c.IPToInt(networkIP)
                        204	if err != nil {
                        205		return "", err
                        206	}
                        207	return c.IntToIP(networkInt + 1), nil
                        208}
                        209
                        210// GetLastHost 获取最后一个可用主机地址
                        211func (c *SubnetCalculator) GetLastHost(ip string, cidr int) (string, error) {
                        212	broadcastIP, err := c.GetBroadcastAddress(ip, cidr)
                        213	if err != nil {
                        214		return "", err
                        215	}
                        216	broadcastInt, err := c.IPToInt(broadcastIP)
                        217	if err != nil {
                        218		return "", err
                        219	}
                        220	return c.IntToIP(broadcastInt - 1), nil
                        221}
                        222
                        223// GetUsableHosts 计算可用主机数量
                        224func (c *SubnetCalculator) GetUsableHosts(cidr int) int {
                        225	return int(math.Pow(2, float64(32-cidr))) - 2
                        226}
                        227
                        228// ParseCIDR 解析CIDR格式
                        229func (c *SubnetCalculator) ParseCIDR(cidr string) (string, int, error) {
                        230	if !c.ValidateCIDR(cidr) {
                        231		return "", 0, fmt.Errorf("无效的CIDR格式")
                        232	}
                        233
                        234	parts := strings.Split(cidr, "/")
                        235	ip := parts[0]
                        236	maskBits, err := strconv.Atoi(parts[1])
                        237	if err != nil {
                        238		return "", 0, err
                        239	}
                        240	return ip, maskBits, nil
                        241}
                        242
                        243// CalculateVLSM VLSM子网划分
                        244func (c *SubnetCalculator) CalculateVLSM(networkCIDR string, subnetRequirements []SubnetRequirement, options map[string]interface{}) (*VLSMResult, error) {
                        245	networkIP, networkCIDRBits, err := c.ParseCIDR(networkCIDR)
                        246	if err != nil {
                        247		return nil, err
                        248	}
                        249
                        250	networkAddress, err := c.GetNetworkAddress(networkIP, networkCIDRBits)
                        251	if err != nil {
                        252		return nil, err
                        253	}
                        254
                        255	networkInt, err := c.IPToInt(networkAddress)
                        256	if err != nil {
                        257		return nil, err
                        258	}
                        259
                        260	totalHosts := c.GetUsableHosts(networkCIDRBits)
                        261
                        262	// 按主机数量排序(如果需要)
                        263	sortedRequirements := make([]SubnetRequirement, len(subnetRequirements))
                        264	copy(sortedRequirements, subnetRequirements)
                        265
                        266	if optimizeOrder, ok := options["optimize_order"].(bool); ok && optimizeOrder {
                        267		sort.Slice(sortedRequirements, func(i, j int) bool {
                        268			return sortedRequirements[i].Hosts > sortedRequirements[j].Hosts
                        269		})
                        270	}
                        271
                        272	// 计算每个子网需要的掩码位数
                        273	var subnets []SubnetInfo
                        274	currentNetworkInt := networkInt
                        275
                        276	for _, requirement := range sortedRequirements {
                        277		requiredHosts := requirement.Hosts
                        278		if includeNetworkBroadcast, ok := options["include_network_broadcast"].(bool); ok && includeNetworkBroadcast {
                        279			requiredHosts += 2
                        280		}
                        281
                        282		requiredCIDR := 32 - int(math.Ceil(math.Log2(float64(requiredHosts))))
                        283
                        284		if requiredCIDR < networkCIDRBits {
                        285			return nil, fmt.Errorf("子网 %s 需要的主机数超出可用空间", requirement.Name)
                        286		}
                        287
                        288		subnetNetworkIP := c.IntToIP(currentNetworkInt)
                        289		subnetMask := c.GetSubnetMask(requiredCIDR)
                        290		subnetHosts := c.GetUsableHosts(requiredCIDR)
                        291
                        292		firstHost, _ := c.GetFirstHost(subnetNetworkIP, requiredCIDR)
                        293		lastHost, _ := c.GetLastHost(subnetNetworkIP, requiredCIDR)
                        294		broadcastAddress, _ := c.GetBroadcastAddress(subnetNetworkIP, requiredCIDR)
                        295
                        296		subnets = append(subnets, SubnetInfo{
                        297			Name:             requirement.Name,
                        298			NetworkAddress:   subnetNetworkIP,
                        299			SubnetMask:       subnetMask,
                        300			CIDR:             requiredCIDR,
                        301			FirstHost:        firstHost,
                        302			LastHost:         lastHost,
                        303			BroadcastAddress: broadcastAddress,
                        304			UsableHosts:      subnetHosts,
                        305			RequiredHosts:    requirement.Hosts,
                        306		})
                        307
                        308		// 计算下一个子网的起始地址
                        309		subnetSize := uint32(math.Pow(2, float64(32-requiredCIDR)))
                        310		currentNetworkInt += subnetSize
                        311	}
                        312
                        313	// 计算汇总信息
                        314	totalRequiredHosts := 0
                        315	for _, req := range sortedRequirements {
                        316		totalRequiredHosts += req.Hosts
                        317	}
                        318	utilization := float64(totalRequiredHosts) / float64(totalHosts) * 100
                        319
                        320	return &VLSMResult{
                        321		Subnets: subnets,
                        322		Summary: SummaryInfo{
                        323			OriginalNetwork: networkCIDR,
                        324			TotalSubnets:    len(subnets),
                        325			TotalHosts:      totalRequiredHosts,
                        326			Utilization:     utilization,
                        327		},
                        328		Details: fmt.Sprintf("VLSM划分完成,共创建 %d 个子网,地址利用率 %.2f%%", len(subnets), utilization),
                        329	}, nil
                        330}
                        331
                        332// MergeSubnets 子网合并
                        333func (c *SubnetCalculator) MergeSubnets(subnetList []string, options map[string]interface{}) (*MergeResult, error) {
                        334	var subnets []struct {
                        335		Network    string
                        336		NetworkIP  string
                        337		CIDR       int
                        338		NetworkInt uint32
                        339		HostCount  int
                        340	}
                        341
                        342	// 解析子网列表
                        343	for _, subnetStr := range subnetList {
                        344		if !c.ValidateCIDR(subnetStr) {
                        345			if validateSubnets, ok := options["validate_subnets"].(bool); ok && validateSubnets {
                        346				return nil, fmt.Errorf("无效的子网格式: %s", subnetStr)
                        347			}
                        348			continue
                        349		}
                        350
                        351		ip, cidr, err := c.ParseCIDR(subnetStr)
                        352		if err != nil {
                        353			continue
                        354		}
                        355
                        356		networkIP, err := c.GetNetworkAddress(ip, cidr)
                        357		if err != nil {
                        358			continue
                        359		}
                        360
                        361		networkInt, err := c.IPToInt(networkIP)
                        362		if err != nil {
                        363			continue
                        364		}
                        365
                        366		subnets = append(subnets, struct {
                        367			Network    string
                        368			NetworkIP  string
                        369			CIDR       int
                        370			NetworkInt uint32
                        371			HostCount  int
                        372		}{
                        373			Network:    subnetStr,
                        374			NetworkIP:  networkIP,
                        375			CIDR:       cidr,
                        376			NetworkInt: networkInt,
                        377			HostCount:  c.GetUsableHosts(cidr),
                        378		})
                        379	}
                        380
                        381	if len(subnets) == 0 {
                        382		return nil, fmt.Errorf("没有有效的子网可以合并")
                        383	}
                        384
                        385	// 按网络地址排序
                        386	sort.Slice(subnets, func(i, j int) bool {
                        387		return subnets[i].NetworkInt < subnets[j].NetworkInt
                        388	})
                        389
                        390	var mergedSubnets []MergedSubnet
                        391	currentGroup := []struct {
                        392		Network    string
                        393		NetworkIP  string
                        394		CIDR       int
                        395		NetworkInt uint32
                        396		HostCount  int
                        397	}{subnets[0]}
                        398
                        399	for i := 1; i < len(subnets); i++ {
                        400		current := subnets[i]
                        401		last := currentGroup[len(currentGroup)-1]
                        402
                        403		// 检查是否相邻或连续
                        404		isAdjacent := false
                        405		isContiguous := false
                        406
                        407		if mergeAdjacent, ok := options["merge_adjacent"].(bool); ok && mergeAdjacent {
                        408			isAdjacent = c.areSubnetsAdjacent(last, current)
                        409		}
                        410
                        411		if mergeContiguous, ok := options["merge_contiguous"].(bool); ok && mergeContiguous {
                        412			isContiguous = c.areSubnetsContiguous(last, current)
                        413		}
                        414
                        415		if isAdjacent || isContiguous {
                        416			currentGroup = append(currentGroup, current)
                        417		} else {
                        418			// 合并当前组
                        419			if len(currentGroup) > 1 {
                        420				mergedSubnets = append(mergedSubnets, c.mergeSubnetGroup(currentGroup))
                        421			} else {
                        422				mergedSubnets = append(mergedSubnets, MergedSubnet{
                        423					Network:         currentGroup[0].Network,
                        424					OriginalSubnets: []string{currentGroup[0].Network},
                        425					HostCount:       currentGroup[0].HostCount,
                        426				})
                        427			}
                        428			currentGroup = []struct {
                        429				Network    string
                        430				NetworkIP  string
                        431				CIDR       int
                        432				NetworkInt uint32
                        433				HostCount  int
                        434			}{current}
                        435		}
                        436	}
                        437
                        438	// 处理最后一组
                        439	if len(currentGroup) > 1 {
                        440		mergedSubnets = append(mergedSubnets, c.mergeSubnetGroup(currentGroup))
                        441	} else {
                        442		mergedSubnets = append(mergedSubnets, MergedSubnet{
                        443			Network:         currentGroup[0].Network,
                        444			OriginalSubnets: []string{currentGroup[0].Network},
                        445			HostCount:       currentGroup[0].HostCount,
                        446		})
                        447	}
                        448
                        449	// 计算汇总信息
                        450	originalCount := len(subnets)
                        451	mergedCount := len(mergedSubnets)
                        452	reduction := originalCount - mergedCount
                        453	totalHosts := 0
                        454	for _, subnet := range mergedSubnets {
                        455		totalHosts += subnet.HostCount
                        456	}
                        457
                        458	return &MergeResult{
                        459		MergedSubnets: mergedSubnets,
                        460		Summary: MergeSummary{
                        461			OriginalCount: originalCount,
                        462			MergedCount:   mergedCount,
                        463			Reduction:     reduction,
                        464			TotalHosts:    totalHosts,
                        465			Utilization:   float64(totalHosts) / float64(0xFFFFFFFF) * 100,
                        466		},
                        467		Details: fmt.Sprintf("合并完成,从 %d 个子网合并为 %d 个,减少 %d 个", originalCount, mergedCount, reduction),
                        468	}, nil
                        469}
                        470
                        471// areSubnetsAdjacent 检查两个子网是否相邻
                        472func (c *SubnetCalculator) areSubnetsAdjacent(subnet1, subnet2 struct {
                        473	Network    string
                        474	NetworkIP  string
                        475	CIDR       int
                        476	NetworkInt uint32
                        477	HostCount  int
                        478}) bool {
                        479	broadcast1, _ := c.GetBroadcastAddress(subnet1.NetworkIP, subnet1.CIDR)
                        480	broadcast1Int, _ := c.IPToInt(broadcast1)
                        481	return subnet2.NetworkInt == broadcast1Int+1
                        482}
                        483
                        484// areSubnetsContiguous 检查两个子网是否连续
                        485func (c *SubnetCalculator) areSubnetsContiguous(subnet1, subnet2 struct {
                        486	Network    string
                        487	NetworkIP  string
                        488	CIDR       int
                        489	NetworkInt uint32
                        490	HostCount  int
                        491}) bool {
                        492	broadcast1, _ := c.GetBroadcastAddress(subnet1.NetworkIP, subnet1.CIDR)
                        493	broadcast1Int, _ := c.IPToInt(broadcast1)
                        494	return subnet2.NetworkInt <= broadcast1Int+1
                        495}
                        496
                        497// mergeSubnetGroup 合并子网组
                        498func (c *SubnetCalculator) mergeSubnetGroup(subnetGroup []struct {
                        499	Network    string
                        500	NetworkIP  string
                        501	CIDR       int
                        502	NetworkInt uint32
                        503	HostCount  int
                        504}) MergedSubnet {
                        505	first := subnetGroup[0]
                        506	last := subnetGroup[len(subnetGroup)-1]
                        507	lastBroadcast, _ := c.GetBroadcastAddress(last.NetworkIP, last.CIDR)
                        508	lastBroadcastInt, _ := c.IPToInt(lastBroadcast)
                        509
                        510	// 计算合并后的CIDR
                        511	rangeSize := lastBroadcastInt - first.NetworkInt + 1
                        512	mergedCIDR := 32 - int(math.Ceil(math.Log2(float64(rangeSize))))
                        513
                        514	mergedNetworkIP := c.IntToIP(first.NetworkInt)
                        515	mergedNetwork := fmt.Sprintf("%s/%d", mergedNetworkIP, mergedCIDR)
                        516	mergedHostCount := c.GetUsableHosts(mergedCIDR)
                        517
                        518	var originalSubnets []string
                        519	for _, subnet := range subnetGroup {
                        520		originalSubnets = append(originalSubnets, subnet.Network)
                        521	}
                        522
                        523	return MergedSubnet{
                        524		Network:         mergedNetwork,
                        525		OriginalSubnets: originalSubnets,
                        526		HostCount:       mergedHostCount,
                        527	}
                        528}
                        529
                        530// CalculateSupernet 超网计算
                        531func (c *SubnetCalculator) CalculateSupernet(startIP, endIP string, options map[string]interface{}) (*SupernetResult, error) {
                        532	if !c.ValidateIP(startIP) || !c.ValidateIP(endIP) {
                        533		return nil, fmt.Errorf("无效的IP地址格式")
                        534	}
                        535
                        536	startInt, err := c.IPToInt(startIP)
                        537	if err != nil {
                        538		return nil, err
                        539	}
                        540
                        541	endInt, err := c.IPToInt(endIP)
                        542	if err != nil {
                        543		return nil, err
                        544	}
                        545
                        546	if startInt > endInt {
                        547		return nil, fmt.Errorf("起始IP不能大于结束IP")
                        548	}
                        549
                        550	// 计算包含该范围的最小超网
                        551	rangeSize := endInt - startInt + 1
                        552	requiredCIDR := 32 - int(math.Ceil(math.Log2(float64(rangeSize))))
                        553
                        554	// 找到包含该范围的最小网络地址
                        555	mask := uint32(0xFFFFFFFF) << (32 - requiredCIDR)
                        556	networkInt := startInt & mask
                        557	networkIP := c.IntToIP(networkInt)
                        558
                        559	// 验证该网络是否包含整个范围
                        560	broadcastInt := networkInt | ^mask
                        561	if broadcastInt < endInt {
                        562		// 需要更大的网络
                        563		newCIDR := requiredCIDR - 1
                        564		newMask := uint32(0xFFFFFFFF) << (32 - newCIDR)
                        565		newNetworkInt := startInt & newMask
                        566		newNetworkIP := c.IntToIP(newNetworkInt)
                        567
                        568		return &SupernetResult{
                        569			NetworkAddress:   newNetworkIP,
                        570			SubnetMask:       c.GetSubnetMask(newCIDR),
                        571			CIDR:             newCIDR,
                        572			BroadcastAddress: c.IntToIP(newNetworkInt | ^newMask),
                        573			FirstHost:        c.IntToIP(newNetworkInt + 1),
                        574			LastHost:         c.IntToIP((newNetworkInt | ^newMask) - 1),
                        575			TotalHosts:       c.GetUsableHosts(newCIDR),
                        576			StartIP:          startIP,
                        577			EndIP:            endIP,
                        578			Details:          fmt.Sprintf("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, newNetworkIP, newCIDR),
                        579		}, nil
                        580	}
                        581
                        582	return &SupernetResult{
                        583		NetworkAddress:   networkIP,
                        584		SubnetMask:       c.GetSubnetMask(requiredCIDR),
                        585		CIDR:             requiredCIDR,
                        586		BroadcastAddress: c.IntToIP(broadcastInt),
                        587		FirstHost:        c.IntToIP(networkInt + 1),
                        588		LastHost:         c.IntToIP(broadcastInt - 1),
                        589		TotalHosts:       c.GetUsableHosts(requiredCIDR),
                        590		StartIP:          startIP,
                        591		EndIP:            endIP,
                        592		Details:          fmt.Sprintf("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, networkIP, requiredCIDR),
                        593	}, nil
                        594}
                        595
                        596// GenerateNetworkPlan 网络规划
                        597func (c *SubnetCalculator) GenerateNetworkPlan(addressSpace string, departmentRequirements []DepartmentRequirement, options map[string]interface{}) (*PlanningResult, error) {
                        598	networkIP, networkCIDRBits, err := c.ParseCIDR(addressSpace)
                        599	if err != nil {
                        600		return nil, err
                        601	}
                        602
                        603	networkAddress, err := c.GetNetworkAddress(networkIP, networkCIDRBits)
                        604	if err != nil {
                        605		return nil, err
                        606	}
                        607
                        608	networkInt, err := c.IPToInt(networkAddress)
                        609	if err != nil {
                        610		return nil, err
                        611	}
                        612
                        613	totalSpace := c.GetUsableHosts(networkCIDRBits)
                        614
                        615	// 按部门大小排序
                        616	sortedDepartments := make([]DepartmentRequirement, len(departmentRequirements))
                        617	copy(sortedDepartments, departmentRequirements)
                        618
                        619	if optimizeUtilization, ok := options["optimize_utilization"].(bool); ok && optimizeUtilization {
                        620		sort.Slice(sortedDepartments, func(i, j int) bool {
                        621			return sortedDepartments[i].Size > sortedDepartments[j].Size
                        622		})
                        623	}
                        624
                        625	var departments []DepartmentInfo
                        626	currentNetworkInt := networkInt
                        627	allocatedSpace := 0
                        628
                        629	for _, dept := range sortedDepartments {
                        630		requiredHosts := dept.Size
                        631		if reserveSpace, ok := options["reserve_space"].(bool); ok && reserveSpace {
                        632			requiredHosts += int(float64(dept.Size) * 0.2)
                        633		}
                        634
                        635		requiredCIDR := 32 - int(math.Ceil(math.Log2(float64(requiredHosts+2)))) // +2 for network and broadcast
                        636
                        637		if requiredCIDR < networkCIDRBits {
                        638			return nil, fmt.Errorf("部门 %s 需要的主机数超出可用空间", dept.Name)
                        639		}
                        640
                        641		deptNetworkIP := c.IntToIP(currentNetworkInt)
                        642		deptSubnetMask := c.GetSubnetMask(requiredCIDR)
                        643		deptHosts := c.GetUsableHosts(requiredCIDR)
                        644
                        645		firstHost, _ := c.GetFirstHost(deptNetworkIP, requiredCIDR)
                        646		lastHost, _ := c.GetLastHost(deptNetworkIP, requiredCIDR)
                        647
                        648		departments = append(departments, DepartmentInfo{
                        649			Name:           dept.Name,
                        650			NetworkAddress: deptNetworkIP,
                        651			SubnetMask:     deptSubnetMask,
                        652			CIDR:           requiredCIDR,
                        653			FirstHost:      firstHost,
                        654			LastHost:       lastHost,
                        655			AllocatedHosts: dept.Size,
                        656			TotalHosts:     deptHosts,
                        657		})
                        658
                        659		allocatedSpace += deptHosts
                        660		subnetSize := uint32(math.Pow(2, float64(32-requiredCIDR)))
                        661		currentNetworkInt += subnetSize
                        662	}
                        663
                        664	remainingSpace := totalSpace - allocatedSpace
                        665	utilization := float64(allocatedSpace) / float64(totalSpace) * 100
                        666
                        667	return &PlanningResult{
                        668		Departments: departments,
                        669		Summary: PlanningSummary{
                        670			TotalSpace:      totalSpace,
                        671			AllocatedSpace:  allocatedSpace,
                        672			RemainingSpace:  remainingSpace,
                        673			Utilization:     utilization,
                        674			DepartmentCount: len(departments),
                        675		},
                        676		Details: fmt.Sprintf("网络规划完成,共分配 %d 个部门,地址利用率 %.2f%%,剩余空间 %d 个主机", len(departments), utilization, remainingSpace),
                        677	}, nil
                        678}
                        679
                        680// GetSubnetInfo 获取子网详细信息(使用net包)
                        681func (c *SubnetCalculator) GetSubnetInfo(ip string, cidr int) (map[string]interface{}, error) {
                        682	_, network, err := net.ParseCIDR(fmt.Sprintf("%s/%d", ip, cidr))
                        683	if err != nil {
                        684		return nil, fmt.Errorf("无法解析子网信息: %v", err)
                        685	}
                        686
                        687	ones, bits := network.Mask.Size()
                        688	networkAddress := network.IP.String()
                        689
                        690	// 计算广播地址
                        691	broadcast := make(net.IP, len(network.IP))
                        692	copy(broadcast, network.IP)
                        693	for i := range broadcast {
                        694		broadcast[i] |= ^network.Mask[i]
                        695	}
                        696
                        697	// 计算第一个和最后一个主机地址
                        698	firstHost := make(net.IP, len(network.IP))
                        699	copy(firstHost, network.IP)
                        700	firstHost[len(firstHost)-1]++
                        701
                        702	lastHost := make(net.IP, len(broadcast))
                        703	copy(lastHost, broadcast)
                        704	lastHost[len(lastHost)-1]--
                        705
                        706	return map[string]interface{}{
                        707		"network_address":   networkAddress,
                        708		"broadcast_address": broadcast.String(),
                        709		"subnet_mask":       net.IP(network.Mask).String(),
                        710		"num_addresses":     int(math.Pow(2, float64(bits-ones))),
                        711		"usable_hosts":      int(math.Pow(2, float64(bits-ones))) - 2,
                        712		"first_host":        firstHost.String(),
                        713		"last_host":         lastHost.String(),
                        714	}, nil
                        715}
                        716
                        717func main() {
                        718	calculator := NewSubnetCalculator()
                        719
                        720	fmt.Println("=== 子网划分工具 - Go版本 ===")
                        721
                        722	// VLSM示例
                        723	fmt.Println("\n--- VLSM子网划分示例 ---")
                        724	vlsmResult, err := calculator.CalculateVLSM("192.168.1.0/24", []SubnetRequirement{
                        725		{Name: "销售部", Hosts: 50},
                        726		{Name: "技术部", Hosts: 30},
                        727		{Name: "财务部", Hosts: 10},
                        728		{Name: "人事部", Hosts: 5},
                        729	}, map[string]interface{}{
                        730		"optimize_order":            true,
                        731		"include_network_broadcast": true,
                        732	})
                        733	if err != nil {
                        734		fmt.Printf("VLSM错误: %v\n", err)
                        735	} else {
                        736		fmt.Println("VLSM结果:")
                        737		for _, subnet := range vlsmResult.Subnets {
                        738			fmt.Printf("  %s: %s/%d (%s - %s)\n", subnet.Name, subnet.NetworkAddress, subnet.CIDR, subnet.FirstHost, subnet.LastHost)
                        739		}
                        740		fmt.Printf("汇总: %+v\n", vlsmResult.Summary)
                        741	}
                        742
                        743	// 子网合并示例
                        744	fmt.Println("\n--- 子网合并示例 ---")
                        745	mergeResult, err := calculator.MergeSubnets([]string{
                        746		"192.168.1.0/26",
                        747		"192.168.1.64/26",
                        748		"192.168.1.128/26",
                        749		"192.168.1.192/26",
                        750	}, map[string]interface{}{
                        751		"merge_adjacent":   true,
                        752		"merge_contiguous": true,
                        753		"validate_subnets": true,
                        754	})
                        755	if err != nil {
                        756		fmt.Printf("合并错误: %v\n", err)
                        757	} else {
                        758		fmt.Println("合并结果:")
                        759		for _, merged := range mergeResult.MergedSubnets {
                        760			fmt.Printf("  %s (包含: %s)\n", merged.Network, strings.Join(merged.OriginalSubnets, ", "))
                        761		}
                        762		fmt.Printf("汇总: %+v\n", mergeResult.Summary)
                        763	}
                        764
                        765	// 超网计算示例
                        766	fmt.Println("\n--- 超网计算示例 ---")
                        767	supernetResult, err := calculator.CalculateSupernet("192.168.1.10", "192.168.1.50", nil)
                        768	if err != nil {
                        769		fmt.Printf("超网错误: %v\n", err)
                        770	} else {
                        771		fmt.Printf("超网结果: %s/%d\n", supernetResult.NetworkAddress, supernetResult.CIDR)
                        772		fmt.Printf("详细信息: %+v\n", supernetResult)
                        773	}
                        774
                        775	// 网络规划示例
                        776	fmt.Println("\n--- 网络规划示例 ---")
                        777	planningResult, err := calculator.GenerateNetworkPlan("10.0.0.0/8", []DepartmentRequirement{
                        778		{Name: "总部", Size: 200},
                        779		{Name: "分公司A", Size: 100},
                        780		{Name: "分公司B", Size: 80},
                        781		{Name: "研发中心", Size: 150},
                        782	}, map[string]interface{}{
                        783		"optimize_utilization": true,
                        784		"reserve_space":        true,
                        785	})
                        786	if err != nil {
                        787		fmt.Printf("规划错误: %v\n", err)
                        788	} else {
                        789		fmt.Println("规划结果:")
                        790		for _, dept := range planningResult.Departments {
                        791			fmt.Printf("  %s: %s/%d (%d 主机)\n", dept.Name, dept.NetworkAddress, dept.CIDR, dept.AllocatedHosts)
                        792		}
                        793		fmt.Printf("汇总: %+v\n", planningResult.Summary)
                        794	}
                        795}
                        
  • subnet_calculator (JAVA)
    subnet_calculator.java
      1import java.util.*;
                          2import java.util.regex.Pattern;
                          3import java.util.regex.Matcher;
                          4
                          5/**
                          6 * 子网划分工具 - Java版本
                          7 * 支持VLSM可变长子网掩码、子网合并、超网计算、网络规划等功能
                          8 */
                          9public class SubnetCalculator {
                         10    private static final Pattern IP_PATTERN = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
                         11    private static final Pattern CIDR_PATTERN = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/([0-9]|[1-2][0-9]|3[0-2])$");
                         12
                         13    // 子网需求类
                         14    public static class SubnetRequirement {
                         15        private String name;
                         16        private int hosts;
                         17
                         18        public SubnetRequirement(String name, int hosts) {
                         19            this.name = name;
                         20            this.hosts = hosts;
                         21        }
                         22
                         23        public String getName() { return name; }
                         24        public int getHosts() { return hosts; }
                         25    }
                         26
                         27    // 部门需求类
                         28    public static class DepartmentRequirement {
                         29        private String name;
                         30        private int size;
                         31
                         32        public DepartmentRequirement(String name, int size) {
                         33            this.name = name;
                         34            this.size = size;
                         35        }
                         36
                         37        public String getName() { return name; }
                         38        public int getSize() { return size; }
                         39    }
                         40
                         41    // VLSM结果类
                         42    public static class VLSMResult {
                         43        private List<SubnetInfo> subnets;
                         44        private SummaryInfo summary;
                         45        private String details;
                         46
                         47        public VLSMResult(List<SubnetInfo> subnets, SummaryInfo summary, String details) {
                         48            this.subnets = subnets;
                         49            this.summary = summary;
                         50            this.details = details;
                         51        }
                         52
                         53        public List<SubnetInfo> getSubnets() { return subnets; }
                         54        public SummaryInfo getSummary() { return summary; }
                         55        public String getDetails() { return details; }
                         56    }
                         57
                         58    // 子网信息类
                         59    public static class SubnetInfo {
                         60        private String name;
                         61        private String networkAddress;
                         62        private String subnetMask;
                         63        private int cidr;
                         64        private String firstHost;
                         65        private String lastHost;
                         66        private String broadcastAddress;
                         67        private int usableHosts;
                         68        private int requiredHosts;
                         69
                         70        public SubnetInfo(String name, String networkAddress, String subnetMask, int cidr,
                         71                         String firstHost, String lastHost, String broadcastAddress,
                         72                         int usableHosts, int requiredHosts) {
                         73            this.name = name;
                         74            this.networkAddress = networkAddress;
                         75            this.subnetMask = subnetMask;
                         76            this.cidr = cidr;
                         77            this.firstHost = firstHost;
                         78            this.lastHost = lastHost;
                         79            this.broadcastAddress = broadcastAddress;
                         80            this.usableHosts = usableHosts;
                         81            this.requiredHosts = requiredHosts;
                         82        }
                         83
                         84        // Getters
                         85        public String getName() { return name; }
                         86        public String getNetworkAddress() { return networkAddress; }
                         87        public String getSubnetMask() { return subnetMask; }
                         88        public int getCidr() { return cidr; }
                         89        public String getFirstHost() { return firstHost; }
                         90        public String getLastHost() { return lastHost; }
                         91        public String getBroadcastAddress() { return broadcastAddress; }
                         92        public int getUsableHosts() { return usableHosts; }
                         93        public int getRequiredHosts() { return requiredHosts; }
                         94    }
                         95
                         96    // 汇总信息类
                         97    public static class SummaryInfo {
                         98        private String originalNetwork;
                         99        private int totalSubnets;
                        100        private int totalHosts;
                        101        private double utilization;
                        102
                        103        public SummaryInfo(String originalNetwork, int totalSubnets, int totalHosts, double utilization) {
                        104            this.originalNetwork = originalNetwork;
                        105            this.totalSubnets = totalSubnets;
                        106            this.totalHosts = totalHosts;
                        107            this.utilization = utilization;
                        108        }
                        109
                        110        // Getters
                        111        public String getOriginalNetwork() { return originalNetwork; }
                        112        public int getTotalSubnets() { return totalSubnets; }
                        113        public int getTotalHosts() { return totalHosts; }
                        114        public double getUtilization() { return utilization; }
                        115    }
                        116
                        117    // 合并结果类
                        118    public static class MergeResult {
                        119        private List<MergedSubnet> mergedSubnets;
                        120        private MergeSummary summary;
                        121        private String details;
                        122
                        123        public MergeResult(List<MergedSubnet> mergedSubnets, MergeSummary summary, String details) {
                        124            this.mergedSubnets = mergedSubnets;
                        125            this.summary = summary;
                        126            this.details = details;
                        127        }
                        128
                        129        public List<MergedSubnet> getMergedSubnets() { return mergedSubnets; }
                        130        public MergeSummary getSummary() { return summary; }
                        131        public String getDetails() { return details; }
                        132    }
                        133
                        134    // 合并后的子网类
                        135    public static class MergedSubnet {
                        136        private String network;
                        137        private List<String> originalSubnets;
                        138        private int hostCount;
                        139
                        140        public MergedSubnet(String network, List<String> originalSubnets, int hostCount) {
                        141            this.network = network;
                        142            this.originalSubnets = originalSubnets;
                        143            this.hostCount = hostCount;
                        144        }
                        145
                        146        // Getters
                        147        public String getNetwork() { return network; }
                        148        public List<String> getOriginalSubnets() { return originalSubnets; }
                        149        public int getHostCount() { return hostCount; }
                        150    }
                        151
                        152    // 合并汇总信息类
                        153    public static class MergeSummary {
                        154        private int originalCount;
                        155        private int mergedCount;
                        156        private int reduction;
                        157        private int totalHosts;
                        158        private double utilization;
                        159
                        160        public MergeSummary(int originalCount, int mergedCount, int reduction, int totalHosts, double utilization) {
                        161            this.originalCount = originalCount;
                        162            this.mergedCount = mergedCount;
                        163            this.reduction = reduction;
                        164            this.totalHosts = totalHosts;
                        165            this.utilization = utilization;
                        166        }
                        167
                        168        // Getters
                        169        public int getOriginalCount() { return originalCount; }
                        170        public int getMergedCount() { return mergedCount; }
                        171        public int getReduction() { return reduction; }
                        172        public int getTotalHosts() { return totalHosts; }
                        173        public double getUtilization() { return utilization; }
                        174    }
                        175
                        176    // 超网结果类
                        177    public static class SupernetResult {
                        178        private String networkAddress;
                        179        private String subnetMask;
                        180        private int cidr;
                        181        private String broadcastAddress;
                        182        private String firstHost;
                        183        private String lastHost;
                        184        private int totalHosts;
                        185        private String startIP;
                        186        private String endIP;
                        187        private String details;
                        188
                        189        public SupernetResult(String networkAddress, String subnetMask, int cidr,
                        190                            String broadcastAddress, String firstHost, String lastHost,
                        191                            int totalHosts, String startIP, String endIP, String details) {
                        192            this.networkAddress = networkAddress;
                        193            this.subnetMask = subnetMask;
                        194            this.cidr = cidr;
                        195            this.broadcastAddress = broadcastAddress;
                        196            this.firstHost = firstHost;
                        197            this.lastHost = lastHost;
                        198            this.totalHosts = totalHosts;
                        199            this.startIP = startIP;
                        200            this.endIP = endIP;
                        201            this.details = details;
                        202        }
                        203
                        204        // Getters
                        205        public String getNetworkAddress() { return networkAddress; }
                        206        public String getSubnetMask() { return subnetMask; }
                        207        public int getCidr() { return cidr; }
                        208        public String getBroadcastAddress() { return broadcastAddress; }
                        209        public String getFirstHost() { return firstHost; }
                        210        public String getLastHost() { return lastHost; }
                        211        public int getTotalHosts() { return totalHosts; }
                        212        public String getStartIP() { return startIP; }
                        213        public String getEndIP() { return endIP; }
                        214        public String getDetails() { return details; }
                        215    }
                        216
                        217    // 规划结果类
                        218    public static class PlanningResult {
                        219        private List<DepartmentInfo> departments;
                        220        private PlanningSummary summary;
                        221        private String details;
                        222
                        223        public PlanningResult(List<DepartmentInfo> departments, PlanningSummary summary, String details) {
                        224            this.departments = departments;
                        225            this.summary = summary;
                        226            this.details = details;
                        227        }
                        228
                        229        public List<DepartmentInfo> getDepartments() { return departments; }
                        230        public PlanningSummary getSummary() { return summary; }
                        231        public String getDetails() { return details; }
                        232    }
                        233
                        234    // 部门信息类
                        235    public static class DepartmentInfo {
                        236        private String name;
                        237        private String networkAddress;
                        238        private String subnetMask;
                        239        private int cidr;
                        240        private String firstHost;
                        241        private String lastHost;
                        242        private int allocatedHosts;
                        243        private int totalHosts;
                        244
                        245        public DepartmentInfo(String name, String networkAddress, String subnetMask, int cidr,
                        246                            String firstHost, String lastHost, int allocatedHosts, int totalHosts) {
                        247            this.name = name;
                        248            this.networkAddress = networkAddress;
                        249            this.subnetMask = subnetMask;
                        250            this.cidr = cidr;
                        251            this.firstHost = firstHost;
                        252            this.lastHost = lastHost;
                        253            this.allocatedHosts = allocatedHosts;
                        254            this.totalHosts = totalHosts;
                        255        }
                        256
                        257        // Getters
                        258        public String getName() { return name; }
                        259        public String getNetworkAddress() { return networkAddress; }
                        260        public String getSubnetMask() { return subnetMask; }
                        261        public int getCidr() { return cidr; }
                        262        public String getFirstHost() { return firstHost; }
                        263        public String getLastHost() { return lastHost; }
                        264        public int getAllocatedHosts() { return allocatedHosts; }
                        265        public int getTotalHosts() { return totalHosts; }
                        266    }
                        267
                        268    // 规划汇总信息类
                        269    public static class PlanningSummary {
                        270        private int totalSpace;
                        271        private int allocatedSpace;
                        272        private int remainingSpace;
                        273        private double utilization;
                        274        private int departmentCount;
                        275
                        276        public PlanningSummary(int totalSpace, int allocatedSpace, int remainingSpace,
                        277                             double utilization, int departmentCount) {
                        278            this.totalSpace = totalSpace;
                        279            this.allocatedSpace = allocatedSpace;
                        280            this.remainingSpace = remainingSpace;
                        281            this.utilization = utilization;
                        282            this.departmentCount = departmentCount;
                        283        }
                        284
                        285        // Getters
                        286        public int getTotalSpace() { return totalSpace; }
                        287        public int getAllocatedSpace() { return allocatedSpace; }
                        288        public int getRemainingSpace() { return remainingSpace; }
                        289        public double getUtilization() { return utilization; }
                        290        public int getDepartmentCount() { return departmentCount; }
                        291    }
                        292
                        293    /**
                        294     * 验证IP地址格式
                        295     */
                        296    public boolean validateIP(String ip) {
                        297        return IP_PATTERN.matcher(ip).matches();
                        298    }
                        299
                        300    /**
                        301     * 验证CIDR格式
                        302     */
                        303    public boolean validateCIDR(String cidr) {
                        304        return CIDR_PATTERN.matcher(cidr).matches();
                        305    }
                        306
                        307    /**
                        308     * IP地址转换为长整数
                        309     */
                        310    public long ipToLong(String ip) throws IllegalArgumentException {
                        311        if (!validateIP(ip)) {
                        312            throw new IllegalArgumentException("无效的IP地址格式");
                        313        }
                        314
                        315        String[] parts = ip.split("\\.");
                        316        long result = 0;
                        317        for (int i = 0; i < 4; i++) {
                        318            result = result << 8 | Integer.parseInt(parts[i]);
                        319        }
                        320        return result;
                        321    }
                        322
                        323    /**
                        324     * 长整数转换为IP地址
                        325     */
                        326    public String longToIP(long ipLong) {
                        327        return String.format("%d.%d.%d.%d",
                        328                (ipLong >> 24) & 0xFF,
                        329                (ipLong >> 16) & 0xFF,
                        330                (ipLong >> 8) & 0xFF,
                        331                ipLong & 0xFF);
                        332    }
                        333
                        334    /**
                        335     * 获取子网掩码
                        336     */
                        337    public String getSubnetMask(int cidr) {
                        338        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        339        return longToIP(mask);
                        340    }
                        341
                        342    /**
                        343     * 获取网络地址
                        344     */
                        345    public String getNetworkAddress(String ip, int cidr) throws IllegalArgumentException {
                        346        long ipLong = ipToLong(ip);
                        347        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        348        long networkLong = ipLong & mask;
                        349        return longToIP(networkLong);
                        350    }
                        351
                        352    /**
                        353     * 获取广播地址
                        354     */
                        355    public String getBroadcastAddress(String ip, int cidr) throws IllegalArgumentException {
                        356        long ipLong = ipToLong(ip);
                        357        long mask = (0xFFFFFFFFL << (32 - cidr)) & 0xFFFFFFFFL;
                        358        long broadcastLong = ipLong | (~mask & 0xFFFFFFFFL);
                        359        return longToIP(broadcastLong);
                        360    }
                        361
                        362    /**
                        363     * 获取第一个可用主机地址
                        364     */
                        365    public String getFirstHost(String ip, int cidr) throws IllegalArgumentException {
                        366        String networkIP = getNetworkAddress(ip, cidr);
                        367        long networkLong = ipToLong(networkIP);
                        368        return longToIP(networkLong + 1);
                        369    }
                        370
                        371    /**
                        372     * 获取最后一个可用主机地址
                        373     */
                        374    public String getLastHost(String ip, int cidr) throws IllegalArgumentException {
                        375        String broadcastIP = getBroadcastAddress(ip, cidr);
                        376        long broadcastLong = ipToLong(broadcastIP);
                        377        return longToIP(broadcastLong - 1);
                        378    }
                        379
                        380    /**
                        381     * 计算可用主机数量
                        382     */
                        383    public int getUsableHosts(int cidr) {
                        384        return (int) (Math.pow(2, 32 - cidr) - 2);
                        385    }
                        386
                        387    /**
                        388     * 解析CIDR格式
                        389     */
                        390    public String[] parseCIDR(String cidr) throws IllegalArgumentException {
                        391        if (!validateCIDR(cidr)) {
                        392            throw new IllegalArgumentException("无效的CIDR格式");
                        393        }
                        394
                        395        String[] parts = cidr.split("/");
                        396        return new String[]{parts[0], parts[1]};
                        397    }
                        398
                        399    /**
                        400     * VLSM子网划分
                        401     */
                        402    public VLSMResult calculateVLSM(String networkCIDR, List<SubnetRequirement> subnetRequirements,
                        403                                  Map<String, Object> options) throws IllegalArgumentException {
                        404        String[] parsed = parseCIDR(networkCIDR);
                        405        String networkIP = parsed[0];
                        406        int networkCIDRBits = Integer.parseInt(parsed[1]);
                        407
                        408        String networkAddress = getNetworkAddress(networkIP, networkCIDRBits);
                        409        long networkLong = ipToLong(networkAddress);
                        410        int totalHosts = getUsableHosts(networkCIDRBits);
                        411
                        412        // 按主机数量排序(如果需要)
                        413        List<SubnetRequirement> sortedRequirements = new ArrayList<>(subnetRequirements);
                        414        if (options != null && options.containsKey("optimize_order") && 
                        415            (Boolean) options.get("optimize_order")) {
                        416            sortedRequirements.sort((a, b) -> Integer.compare(b.getHosts(), a.getHosts()));
                        417        }
                        418
                        419        // 计算每个子网需要的掩码位数
                        420        List<SubnetInfo> subnets = new ArrayList<>();
                        421        long currentNetworkLong = networkLong;
                        422
                        423        for (SubnetRequirement requirement : sortedRequirements) {
                        424            int requiredHosts = requirement.getHosts();
                        425            if (options != null && options.containsKey("include_network_broadcast") && 
                        426                (Boolean) options.get("include_network_broadcast")) {
                        427                requiredHosts += 2;
                        428            }
                        429
                        430            int requiredCIDR = 32 - (int) Math.ceil(Math.log(requiredHosts) / Math.log(2));
                        431
                        432            if (requiredCIDR < networkCIDRBits) {
                        433                throw new IllegalArgumentException("子网 " + requirement.getName() + " 需要的主机数超出可用空间");
                        434            }
                        435
                        436            String subnetNetworkIP = longToIP(currentNetworkLong);
                        437            String subnetMask = getSubnetMask(requiredCIDR);
                        438            int subnetHosts = getUsableHosts(requiredCIDR);
                        439
                        440            String firstHost = getFirstHost(subnetNetworkIP, requiredCIDR);
                        441            String lastHost = getLastHost(subnetNetworkIP, requiredCIDR);
                        442            String broadcastAddress = getBroadcastAddress(subnetNetworkIP, requiredCIDR);
                        443
                        444            subnets.add(new SubnetInfo(
                        445                    requirement.getName(),
                        446                    subnetNetworkIP,
                        447                    subnetMask,
                        448                    requiredCIDR,
                        449                    firstHost,
                        450                    lastHost,
                        451                    broadcastAddress,
                        452                    subnetHosts,
                        453                    requirement.getHosts()
                        454            ));
                        455
                        456            // 计算下一个子网的起始地址
                        457            long subnetSize = (long) Math.pow(2, 32 - requiredCIDR);
                        458            currentNetworkLong += subnetSize;
                        459        }
                        460
                        461        // 计算汇总信息
                        462        int totalRequiredHosts = sortedRequirements.stream().mapToInt(SubnetRequirement::getHosts).sum();
                        463        double utilization = (double) totalRequiredHosts / totalHosts * 100;
                        464
                        465        return new VLSMResult(
                        466                subnets,
                        467                new SummaryInfo(networkCIDR, subnets.size(), totalRequiredHosts, utilization),
                        468                String.format("VLSM划分完成,共创建 %d 个子网,地址利用率 %.2f%%", subnets.size(), utilization)
                        469        );
                        470    }
                        471
                        472    /**
                        473     * 子网合并
                        474     */
                        475    public MergeResult mergeSubnets(List<String> subnetList, Map<String, Object> options) 
                        476            throws IllegalArgumentException {
                        477        List<SubnetData> subnets = new ArrayList<>();
                        478
                        479        // 解析子网列表
                        480        for (String subnetStr : subnetList) {
                        481            if (!validateCIDR(subnetStr)) {
                        482                if (options != null && options.containsKey("validate_subnets") && 
                        483                    (Boolean) options.get("validate_subnets")) {
                        484                    throw new IllegalArgumentException("无效的子网格式: " + subnetStr);
                        485                }
                        486                continue;
                        487            }
                        488
                        489            String[] parsed = parseCIDR(subnetStr);
                        490            String ip = parsed[0];
                        491            int cidr = Integer.parseInt(parsed[1]);
                        492
                        493            String networkIP = getNetworkAddress(ip, cidr);
                        494            long networkLong = ipToLong(networkIP);
                        495
                        496            subnets.add(new SubnetData(subnetStr, networkIP, cidr, networkLong, getUsableHosts(cidr)));
                        497        }
                        498
                        499        if (subnets.isEmpty()) {
                        500            throw new IllegalArgumentException("没有有效的子网可以合并");
                        501        }
                        502
                        503        // 按网络地址排序
                        504        subnets.sort(Comparator.comparingLong(SubnetData::getNetworkLong));
                        505
                        506        List<MergedSubnet> mergedSubnets = new ArrayList<>();
                        507        List<SubnetData> currentGroup = new ArrayList<>();
                        508        currentGroup.add(subnets.get(0));
                        509
                        510        for (int i = 1; i < subnets.size(); i++) {
                        511            SubnetData current = subnets.get(i);
                        512            SubnetData last = currentGroup.get(currentGroup.size() - 1);
                        513
                        514            // 检查是否相邻或连续
                        515            boolean isAdjacent = false;
                        516            boolean isContiguous = false;
                        517
                        518            if (options != null && options.containsKey("merge_adjacent") && 
                        519                (Boolean) options.get("merge_adjacent")) {
                        520                isAdjacent = areSubnetsAdjacent(last, current);
                        521            }
                        522
                        523            if (options != null && options.containsKey("merge_contiguous") && 
                        524                (Boolean) options.get("merge_contiguous")) {
                        525                isContiguous = areSubnetsContiguous(last, current);
                        526            }
                        527
                        528            if (isAdjacent || isContiguous) {
                        529                currentGroup.add(current);
                        530            } else {
                        531                // 合并当前组
                        532                if (currentGroup.size() > 1) {
                        533                    mergedSubnets.add(mergeSubnetGroup(currentGroup));
                        534                } else {
                        535                    List<String> originalSubnets = new ArrayList<>();
                        536                    originalSubnets.add(currentGroup.get(0).getNetwork());
                        537                    mergedSubnets.add(new MergedSubnet(
                        538                            currentGroup.get(0).getNetwork(),
                        539                            originalSubnets,
                        540                            currentGroup.get(0).getHostCount()
                        541                    ));
                        542                }
                        543                currentGroup = new ArrayList<>();
                        544                currentGroup.add(current);
                        545            }
                        546        }
                        547
                        548        // 处理最后一组
                        549        if (currentGroup.size() > 1) {
                        550            mergedSubnets.add(mergeSubnetGroup(currentGroup));
                        551        } else {
                        552            List<String> originalSubnets = new ArrayList<>();
                        553            originalSubnets.add(currentGroup.get(0).getNetwork());
                        554            mergedSubnets.add(new MergedSubnet(
                        555                    currentGroup.get(0).getNetwork(),
                        556                    originalSubnets,
                        557                    currentGroup.get(0).getHostCount()
                        558            ));
                        559        }
                        560
                        561        // 计算汇总信息
                        562        int originalCount = subnets.size();
                        563        int mergedCount = mergedSubnets.size();
                        564        int reduction = originalCount - mergedCount;
                        565        int totalHosts = mergedSubnets.stream().mapToInt(MergedSubnet::getHostCount).sum();
                        566
                        567        return new MergeResult(
                        568                mergedSubnets,
                        569                new MergeSummary(originalCount, mergedCount, reduction, totalHosts, 
                        570                               (double) totalHosts / 0xFFFFFFFFL * 100),
                        571                String.format("合并完成,从 %d 个子网合并为 %d 个,减少 %d 个", originalCount, mergedCount, reduction)
                        572        );
                        573    }
                        574
                        575    // 子网数据内部类
                        576    private static class SubnetData {
                        577        private String network;
                        578        private String networkIP;
                        579        private int cidr;
                        580        private long networkLong;
                        581        private int hostCount;
                        582
                        583        public SubnetData(String network, String networkIP, int cidr, long networkLong, int hostCount) {
                        584            this.network = network;
                        585            this.networkIP = networkIP;
                        586            this.cidr = cidr;
                        587            this.networkLong = networkLong;
                        588            this.hostCount = hostCount;
                        589        }
                        590
                        591        public String getNetwork() { return network; }
                        592        public String getNetworkIP() { return networkIP; }
                        593        public int getCidr() { return cidr; }
                        594        public long getNetworkLong() { return networkLong; }
                        595        public int getHostCount() { return hostCount; }
                        596    }
                        597
                        598    /**
                        599     * 检查两个子网是否相邻
                        600     */
                        601    private boolean areSubnetsAdjacent(SubnetData subnet1, SubnetData subnet2) {
                        602        String broadcast1 = getBroadcastAddress(subnet1.getNetworkIP(), subnet1.getCidr());
                        603        long broadcast1Long = ipToLong(broadcast1);
                        604        return subnet2.getNetworkLong() == broadcast1Long + 1;
                        605    }
                        606
                        607    /**
                        608     * 检查两个子网是否连续
                        609     */
                        610    private boolean areSubnetsContiguous(SubnetData subnet1, SubnetData subnet2) {
                        611        String broadcast1 = getBroadcastAddress(subnet1.getNetworkIP(), subnet1.getCidr());
                        612        long broadcast1Long = ipToLong(broadcast1);
                        613        return subnet2.getNetworkLong() <= broadcast1Long + 1;
                        614    }
                        615
                        616    /**
                        617     * 合并子网组
                        618     */
                        619    private MergedSubnet mergeSubnetGroup(List<SubnetData> subnetGroup) {
                        620        SubnetData first = subnetGroup.get(0);
                        621        SubnetData last = subnetGroup.get(subnetGroup.size() - 1);
                        622        String lastBroadcast = getBroadcastAddress(last.getNetworkIP(), last.getCidr());
                        623        long lastBroadcastLong = ipToLong(lastBroadcast);
                        624
                        625        // 计算合并后的CIDR
                        626        long rangeSize = lastBroadcastLong - first.getNetworkLong() + 1;
                        627        int mergedCIDR = 32 - (int) Math.ceil(Math.log(rangeSize) / Math.log(2));
                        628
                        629        String mergedNetworkIP = longToIP(first.getNetworkLong());
                        630        String mergedNetwork = mergedNetworkIP + "/" + mergedCIDR;
                        631        int mergedHostCount = getUsableHosts(mergedCIDR);
                        632
                        633        List<String> originalSubnets = new ArrayList<>();
                        634        for (SubnetData subnet : subnetGroup) {
                        635            originalSubnets.add(subnet.getNetwork());
                        636        }
                        637
                        638        return new MergedSubnet(mergedNetwork, originalSubnets, mergedHostCount);
                        639    }
                        640
                        641    /**
                        642     * 超网计算
                        643     */
                        644    public SupernetResult calculateSupernet(String startIP, String endIP, Map<String, Object> options) 
                        645            throws IllegalArgumentException {
                        646        if (!validateIP(startIP) || !validateIP(endIP)) {
                        647            throw new IllegalArgumentException("无效的IP地址格式");
                        648        }
                        649
                        650        long startLong = ipToLong(startIP);
                        651        long endLong = ipToLong(endIP);
                        652
                        653        if (startLong > endLong) {
                        654            throw new IllegalArgumentException("起始IP不能大于结束IP");
                        655        }
                        656
                        657        // 计算包含该范围的最小超网
                        658        long rangeSize = endLong - startLong + 1;
                        659        int requiredCIDR = 32 - (int) Math.ceil(Math.log(rangeSize) / Math.log(2));
                        660
                        661        // 找到包含该范围的最小网络地址
                        662        long mask = (0xFFFFFFFFL << (32 - requiredCIDR)) & 0xFFFFFFFFL;
                        663        long networkLong = startLong & mask;
                        664        String networkIP = longToIP(networkLong);
                        665
                        666        // 验证该网络是否包含整个范围
                        667        long broadcastLong = networkLong | (~mask & 0xFFFFFFFFL);
                        668        if (broadcastLong < endLong) {
                        669            // 需要更大的网络
                        670            int newCIDR = requiredCIDR - 1;
                        671            long newMask = (0xFFFFFFFFL << (32 - newCIDR)) & 0xFFFFFFFFL;
                        672            long newNetworkLong = startLong & newMask;
                        673            String newNetworkIP = longToIP(newNetworkLong);
                        674
                        675            return new SupernetResult(
                        676                    newNetworkIP,
                        677                    getSubnetMask(newCIDR),
                        678                    newCIDR,
                        679                    longToIP(newNetworkLong | (~newMask & 0xFFFFFFFFL)),
                        680                    longToIP(newNetworkLong + 1),
                        681                    longToIP((newNetworkLong | (~newMask & 0xFFFFFFFFL)) - 1),
                        682                    getUsableHosts(newCIDR),
                        683                    startIP,
                        684                    endIP,
                        685                    String.format("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, newNetworkIP, newCIDR)
                        686            );
                        687        }
                        688
                        689        return new SupernetResult(
                        690                networkIP,
                        691                getSubnetMask(requiredCIDR),
                        692                requiredCIDR,
                        693                longToIP(broadcastLong),
                        694                longToIP(networkLong + 1),
                        695                longToIP(broadcastLong - 1),
                        696                getUsableHosts(requiredCIDR),
                        697                startIP,
                        698                endIP,
                        699                String.format("计算得到包含范围 %s-%s 的最小超网 %s/%d", startIP, endIP, networkIP, requiredCIDR)
                        700        );
                        701    }
                        702
                        703    /**
                        704     * 网络规划
                        705     */
                        706    public PlanningResult generateNetworkPlan(String addressSpace, List<DepartmentRequirement> departmentRequirements,
                        707                                            Map<String, Object> options) throws IllegalArgumentException {
                        708        String[] parsed = parseCIDR(addressSpace);
                        709        String networkIP = parsed[0];
                        710        int networkCIDRBits = Integer.parseInt(parsed[1]);
                        711
                        712        String networkAddress = getNetworkAddress(networkIP, networkCIDRBits);
                        713        long networkLong = ipToLong(networkAddress);
                        714        int totalSpace = getUsableHosts(networkCIDRBits);
                        715
                        716        // 按部门大小排序
                        717        List<DepartmentRequirement> sortedDepartments = new ArrayList<>(departmentRequirements);
                        718        if (options != null && options.containsKey("optimize_utilization") && 
                        719            (Boolean) options.get("optimize_utilization")) {
                        720            sortedDepartments.sort((a, b) -> Integer.compare(b.getSize(), a.getSize()));
                        721        }
                        722
                        723        List<DepartmentInfo> departments = new ArrayList<>();
                        724        long currentNetworkLong = networkLong;
                        725        int allocatedSpace = 0;
                        726
                        727        for (DepartmentRequirement dept : sortedDepartments) {
                        728            int requiredHosts = dept.getSize();
                        729            if (options != null && options.containsKey("reserve_space") && 
                        730                (Boolean) options.get("reserve_space")) {
                        731                requiredHosts += (int) Math.ceil(dept.getSize() * 0.2);
                        732            }
                        733
                        734            int requiredCIDR = 32 - (int) Math.ceil(Math.log(requiredHosts + 2) / Math.log(2)); // +2 for network and broadcast
                        735
                        736            if (requiredCIDR < networkCIDRBits) {
                        737                throw new IllegalArgumentException("部门 " + dept.getName() + " 需要的主机数超出可用空间");
                        738            }
                        739
                        740            String deptNetworkIP = longToIP(currentNetworkLong);
                        741            String deptSubnetMask = getSubnetMask(requiredCIDR);
                        742            int deptHosts = getUsableHosts(requiredCIDR);
                        743
                        744            String firstHost = getFirstHost(deptNetworkIP, requiredCIDR);
                        745            String lastHost = getLastHost(deptNetworkIP, requiredCIDR);
                        746
                        747            departments.add(new DepartmentInfo(
                        748                    dept.getName(),
                        749                    deptNetworkIP,
                        750                    deptSubnetMask,
                        751                    requiredCIDR,
                        752                    firstHost,
                        753                    lastHost,
                        754                    dept.getSize(),
                        755                    deptHosts
                        756            ));
                        757
                        758            allocatedSpace += deptHosts;
                        759            long subnetSize = (long) Math.pow(2, 32 - requiredCIDR);
                        760            currentNetworkLong += subnetSize;
                        761        }
                        762
                        763        int remainingSpace = totalSpace - allocatedSpace;
                        764        double utilization = (double) allocatedSpace / totalSpace * 100;
                        765
                        766        return new PlanningResult(
                        767                departments,
                        768                new PlanningSummary(totalSpace, allocatedSpace, remainingSpace, utilization, departments.size()),
                        769                String.format("网络规划完成,共分配 %d 个部门,地址利用率 %.2f%%,剩余空间 %d 个主机", 
                        770                            departments.size(), utilization, remainingSpace)
                        771        );
                        772    }
                        773
                        774    public static void main(String[] args) {
                        775        SubnetCalculator calculator = new SubnetCalculator();
                        776
                        777        System.out.println("=== 子网划分工具 - Java版本 ===");
                        778
                        779        // VLSM示例
                        780        System.out.println("\n--- VLSM子网划分示例 ---");
                        781        try {
                        782            List<SubnetRequirement> requirements = Arrays.asList(
                        783                    new SubnetRequirement("销售部", 50),
                        784                    new SubnetRequirement("技术部", 30),
                        785                    new SubnetRequirement("财务部", 10),
                        786                    new SubnetRequirement("人事部", 5)
                        787            );
                        788
                        789            Map<String, Object> options = new HashMap<>();
                        790            options.put("optimize_order", true);
                        791            options.put("include_network_broadcast", true);
                        792
                        793            VLSMResult vlsmResult = calculator.calculateVLSM("192.168.1.0/24", requirements, options);
                        794            System.out.println("VLSM结果:");
                        795            for (SubnetInfo subnet : vlsmResult.getSubnets()) {
                        796                System.out.printf("  %s: %s/%d (%s - %s)%n", 
                        797                                subnet.getName(), subnet.getNetworkAddress(), subnet.getCidr(),
                        798                                subnet.getFirstHost(), subnet.getLastHost());
                        799            }
                        800            System.out.printf("汇总: 原始网络=%s, 总子网数=%d, 总主机数=%d, 利用率=%.2f%%%n",
                        801                            vlsmResult.getSummary().getOriginalNetwork(),
                        802                            vlsmResult.getSummary().getTotalSubnets(),
                        803                            vlsmResult.getSummary().getTotalHosts(),
                        804                            vlsmResult.getSummary().getUtilization());
                        805        } catch (Exception e) {
                        806            System.err.println("VLSM错误: " + e.getMessage());
                        807        }
                        808
                        809        // 子网合并示例
                        810        System.out.println("\n--- 子网合并示例 ---");
                        811        try {
                        812            List<String> subnetList = Arrays.asList(
                        813                    "192.168.1.0/26",
                        814                    "192.168.1.64/26",
                        815                    "192.168.1.128/26",
                        816                    "192.168.1.192/26"
                        817            );
                        818
                        819            Map<String, Object> options = new HashMap<>();
                        820            options.put("merge_adjacent", true);
                        821            options.put("merge_contiguous", true);
                        822            options.put("validate_subnets", true);
                        823
                        824            MergeResult mergeResult = calculator.mergeSubnets(subnetList, options);
                        825            System.out.println("合并结果:");
                        826            for (MergedSubnet merged : mergeResult.getMergedSubnets()) {
                        827                System.out.printf("  %s (包含: %s)%n", merged.getNetwork(), 
                        828                                String.join(", ", merged.getOriginalSubnets()));
                        829            }
                        830            System.out.printf("汇总: 原子网数=%d, 合并后=%d, 减少=%d, 利用率=%.4f%%%n",
                        831                            mergeResult.getSummary().getOriginalCount(),
                        832                            mergeResult.getSummary().getMergedCount(),
                        833                            mergeResult.getSummary().getReduction(),
                        834                            mergeResult.getSummary().getUtilization());
                        835        } catch (Exception e) {
                        836            System.err.println("合并错误: " + e.getMessage());
                        837        }
                        838
                        839        // 超网计算示例
                        840        System.out.println("\n--- 超网计算示例 ---");
                        841        try {
                        842            SupernetResult supernetResult = calculator.calculateSupernet("192.168.1.10", "192.168.1.50", null);
                        843            System.out.printf("超网结果: %s/%d%n", supernetResult.getNetworkAddress(), supernetResult.getCidr());
                        844            System.out.printf("详细信息: %s%n", supernetResult.getDetails());
                        845        } catch (Exception e) {
                        846            System.err.println("超网错误: " + e.getMessage());
                        847        }
                        848
                        849        // 网络规划示例
                        850        System.out.println("\n--- 网络规划示例 ---");
                        851        try {
                        852            List<DepartmentRequirement> deptRequirements = Arrays.asList(
                        853                    new DepartmentRequirement("总部", 200),
                        854                    new DepartmentRequirement("分公司A", 100),
                        855                    new DepartmentRequirement("分公司B", 80),
                        856                    new DepartmentRequirement("研发中心", 150)
                        857            );
                        858
                        859            Map<String, Object> options = new HashMap<>();
                        860            options.put("optimize_utilization", true);
                        861            options.put("reserve_space", true);
                        862
                        863            PlanningResult planningResult = calculator.generateNetworkPlan("10.0.0.0/8", deptRequirements, options);
                        864            System.out.println("规划结果:");
                        865            for (DepartmentInfo dept : planningResult.getDepartments()) {
                        866                System.out.printf("  %s: %s/%d (%d 主机)%n", dept.getName(), 
                        867                                dept.getNetworkAddress(), dept.getCidr(), dept.getAllocatedHosts());
                        868            }
                        869            System.out.printf("汇总: 总空间=%d, 已分配=%d, 剩余=%d, 利用率=%.2f%%, 部门数=%d%n",
                        870                            planningResult.getSummary().getTotalSpace(),
                        871                            planningResult.getSummary().getAllocatedSpace(),
                        872                            planningResult.getSummary().getRemainingSpace(),
                        873                            planningResult.getSummary().getUtilization(),
                        874                            planningResult.getSummary().getDepartmentCount());
                        875        } catch (Exception e) {
                        876            System.err.println("规划错误: " + e.getMessage());
                        877        }
                        878    }
                        879}
                        
  • subnet_calculator (JS)
    subnet_calculator.js
      1/**
                          2 * 子网划分工具 - JavaScript版本
                          3 * 支持VLSM可变长子网掩码、子网合并、超网计算、网络规划等功能
                          4 */
                          5class SubnetCalculator {
                          6    constructor() {
                          7        this.ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
                          8        this.cidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]|[1-2][0-9]|3[0-2])$/;
                          9    }
                         10
                         11    /**
                         12     * 验证IP地址格式
                         13     */
                         14    validateIP(ip) {
                         15        return this.ipRegex.test(ip);
                         16    }
                         17
                         18    /**
                         19     * 验证CIDR格式
                         20     */
                         21    validateCIDR(cidr) {
                         22        return this.cidrRegex.test(cidr);
                         23    }
                         24
                         25    /**
                         26     * IP地址转换为整数
                         27     */
                         28    ipToInt(ip) {
                         29        if (!this.validateIP(ip)) {
                         30            throw new Error('无效的IP地址格式');
                         31        }
                         32        
                         33        const parts = ip.split('.').map(Number);
                         34        return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
                         35    }
                         36
                         37    /**
                         38     * 整数转换为IP地址
                         39     */
                         40    intToIP(int) {
                         41        return [
                         42            (int >>> 24) & 255,
                         43            (int >>> 16) & 255,
                         44            (int >>> 8) & 255,
                         45            int & 255
                         46        ].join('.');
                         47    }
                         48
                         49    /**
                         50     * 获取子网掩码
                         51     */
                         52    getSubnetMask(cidr) {
                         53        const mask = (0xFFFFFFFF << (32 - cidr)) >>> 0;
                         54        return this.intToIP(mask);
                         55    }
                         56
                         57    /**
                         58     * 获取网络地址
                         59     */
                         60    getNetworkAddress(ip, cidr) {
                         61        const ipInt = this.ipToInt(ip);
                         62        const mask = (0xFFFFFFFF << (32 - cidr)) >>> 0;
                         63        const networkInt = ipInt & mask;
                         64        return this.intToIP(networkInt);
                         65    }
                         66
                         67    /**
                         68     * 获取广播地址
                         69     */
                         70    getBroadcastAddress(ip, cidr) {
                         71        const ipInt = this.ipToInt(ip);
                         72        const mask = (0xFFFFFFFF << (32 - cidr)) >>> 0;
                         73        const broadcastInt = ipInt | (~mask >>> 0);
                         74        return this.intToIP(broadcastInt);
                         75    }
                         76
                         77    /**
                         78     * 获取第一个可用主机地址
                         79     */
                         80    getFirstHost(ip, cidr) {
                         81        const networkInt = this.ipToInt(this.getNetworkAddress(ip, cidr));
                         82        return this.intToIP(networkInt + 1);
                         83    }
                         84
                         85    /**
                         86     * 获取最后一个可用主机地址
                         87     */
                         88    getLastHost(ip, cidr) {
                         89        const broadcastInt = this.ipToInt(this.getBroadcastAddress(ip, cidr));
                         90        return this.intToIP(broadcastInt - 1);
                         91    }
                         92
                         93    /**
                         94     * 计算可用主机数量
                         95     */
                         96    getUsableHosts(cidr) {
                         97        return Math.pow(2, 32 - cidr) - 2;
                         98    }
                         99
                        100    /**
                        101     * 解析CIDR格式
                        102     */
                        103    parseCIDR(cidr) {
                        104        if (!this.validateCIDR(cidr)) {
                        105            throw new Error('无效的CIDR格式');
                        106        }
                        107        
                        108        const [ip, maskBits] = cidr.split('/');
                        109        return {
                        110            ip: ip,
                        111            cidr: parseInt(maskBits),
                        112            subnetMask: this.getSubnetMask(parseInt(maskBits))
                        113        };
                        114    }
                        115
                        116    /**
                        117     * VLSM子网划分
                        118     */
                        119    calculateVLSM(networkCIDR, subnetRequirements, options = {}) {
                        120        const { ip: networkIP, cidr: networkCIDR } = this.parseCIDR(networkCIDR);
                        121        const networkInt = this.ipToInt(this.getNetworkAddress(networkIP, networkCIDR));
                        122        const totalHosts = this.getUsableHosts(networkCIDR);
                        123        
                        124        // 按主机数量排序(如果需要)
                        125        let sortedRequirements = [...subnetRequirements];
                        126        if (options.optimizeOrder) {
                        127            sortedRequirements.sort((a, b) => b.hosts - a.hosts);
                        128        }
                        129        
                        130        // 计算每个子网需要的掩码位数
                        131        const subnets = [];
                        132        let currentNetworkInt = networkInt;
                        133        
                        134        for (const requirement of sortedRequirements) {
                        135            const requiredHosts = requirement.hosts + (options.includeNetworkBroadcast ? 2 : 0);
                        136            const requiredCIDR = 32 - Math.ceil(Math.log2(requiredHosts));
                        137            
                        138            if (requiredCIDR < networkCIDR) {
                        139                throw new Error(`子网 ${requirement.name} 需要的主机数超出可用空间`);
                        140            }
                        141            
                        142            const subnetNetworkIP = this.intToIP(currentNetworkInt);
                        143            const subnetMask = this.getSubnetMask(requiredCIDR);
                        144            const subnetHosts = this.getUsableHosts(requiredCIDR);
                        145            
                        146            subnets.push({
                        147                name: requirement.name,
                        148                networkAddress: subnetNetworkIP,
                        149                subnetMask: subnetMask,
                        150                cidr: requiredCIDR,
                        151                firstHost: this.getFirstHost(subnetNetworkIP, requiredCIDR),
                        152                lastHost: this.getLastHost(subnetNetworkIP, requiredCIDR),
                        153                broadcastAddress: this.getBroadcastAddress(subnetNetworkIP, requiredCIDR),
                        154                usableHosts: subnetHosts,
                        155                requiredHosts: requirement.hosts
                        156            });
                        157            
                        158            // 计算下一个子网的起始地址
                        159            const subnetSize = Math.pow(2, 32 - requiredCIDR);
                        160            currentNetworkInt += subnetSize;
                        161        }
                        162        
                        163        // 计算汇总信息
                        164        const totalRequiredHosts = sortedRequirements.reduce((sum, req) => sum + req.hosts, 0);
                        165        const utilization = ((totalRequiredHosts / totalHosts) * 100).toFixed(2);
                        166        
                        167        return {
                        168            subnets: subnets,
                        169            summary: {
                        170                originalNetwork: networkCIDR,
                        171                totalSubnets: subnets.length,
                        172                totalHosts: totalRequiredHosts,
                        173                utilization: utilization
                        174            },
                        175            details: `VLSM划分完成,共创建 ${subnets.length} 个子网,地址利用率 ${utilization}%`
                        176        };
                        177    }
                        178
                        179    /**
                        180     * 子网合并
                        181     */
                        182    mergeSubnets(subnetList, options = {}) {
                        183        const subnets = [];
                        184        
                        185        // 解析子网列表
                        186        for (const subnetStr of subnetList) {
                        187            if (!this.validateCIDR(subnetStr)) {
                        188                if (options.validateSubnets) {
                        189                    throw new Error(`无效的子网格式: ${subnetStr}`);
                        190                }
                        191                continue;
                        192            }
                        193            
                        194            const { ip, cidr } = this.parseCIDR(subnetStr);
                        195            const networkIP = this.getNetworkAddress(ip, cidr);
                        196            subnets.push({
                        197                network: subnetStr,
                        198                networkIP: networkIP,
                        199                cidr: cidr,
                        200                networkInt: this.ipToInt(networkIP),
                        201                hostCount: this.getUsableHosts(cidr)
                        202            });
                        203        }
                        204        
                        205        if (subnets.length === 0) {
                        206            throw new Error('没有有效的子网可以合并');
                        207        }
                        208        
                        209        // 按网络地址排序
                        210        subnets.sort((a, b) => a.networkInt - b.networkInt);
                        211        
                        212        const mergedSubnets = [];
                        213        let currentGroup = [subnets[0]];
                        214        
                        215        for (let i = 1; i < subnets.length; i++) {
                        216            const current = subnets[i];
                        217            const last = currentGroup[currentGroup.length - 1];
                        218            
                        219            // 检查是否相邻或连续
                        220            const isAdjacent = options.mergeAdjacent && 
                        221                this.areSubnetsAdjacent(last, current);
                        222            const isContiguous = options.mergeContiguous && 
                        223                this.areSubnetsContiguous(last, current);
                        224            
                        225            if (isAdjacent || isContiguous) {
                        226                currentGroup.push(current);
                        227            } else {
                        228                // 合并当前组
                        229                if (currentGroup.length > 1) {
                        230                    mergedSubnets.push(this.mergeSubnetGroup(currentGroup));
                        231                } else {
                        232                    mergedSubnets.push({
                        233                        network: currentGroup[0].network,
                        234                        originalSubnets: [currentGroup[0].network],
                        235                        hostCount: currentGroup[0].hostCount
                        236                    });
                        237                }
                        238                currentGroup = [current];
                        239            }
                        240        }
                        241        
                        242        // 处理最后一组
                        243        if (currentGroup.length > 1) {
                        244            mergedSubnets.push(this.mergeSubnetGroup(currentGroup));
                        245        } else {
                        246            mergedSubnets.push({
                        247                network: currentGroup[0].network,
                        248                originalSubnets: [currentGroup[0].network],
                        249                hostCount: currentGroup[0].hostCount
                        250            });
                        251        }
                        252        
                        253        // 计算汇总信息
                        254        const originalCount = subnets.length;
                        255        const mergedCount = mergedSubnets.length;
                        256        const reduction = originalCount - mergedCount;
                        257        const totalHosts = mergedSubnets.reduce((sum, subnet) => sum + subnet.hostCount, 0);
                        258        
                        259        return {
                        260            mergedSubnets: mergedSubnets,
                        261            summary: {
                        262                originalCount: originalCount,
                        263                mergedCount: mergedCount,
                        264                reduction: reduction,
                        265                totalHosts: totalHosts,
                        266                utilization: ((totalHosts / (Math.pow(2, 32) - 1)) * 100).toFixed(4)
                        267            },
                        268            details: `合并完成,从 ${originalCount} 个子网合并为 ${mergedCount} 个,减少 ${reduction} 个`
                        269        };
                        270    }
                        271
                        272    /**
                        273     * 检查两个子网是否相邻
                        274     */
                        275    areSubnetsAdjacent(subnet1, subnet2) {
                        276        const broadcast1 = this.ipToInt(this.getBroadcastAddress(subnet1.networkIP, subnet1.cidr));
                        277        const network2 = subnet2.networkInt;
                        278        return network2 === broadcast1 + 1;
                        279    }
                        280
                        281    /**
                        282     * 检查两个子网是否连续
                        283     */
                        284    areSubnetsContiguous(subnet1, subnet2) {
                        285        const broadcast1 = this.ipToInt(this.getBroadcastAddress(subnet1.networkIP, subnet1.cidr));
                        286        const network2 = subnet2.networkInt;
                        287        return network2 <= broadcast1 + 1;
                        288    }
                        289
                        290    /**
                        291     * 合并子网组
                        292     */
                        293    mergeSubnetGroup(subnetGroup) {
                        294        const first = subnetGroup[0];
                        295        const last = subnetGroup[subnetGroup.length - 1];
                        296        const lastBroadcast = this.ipToInt(this.getBroadcastAddress(last.networkIP, last.cidr));
                        297        
                        298        // 计算合并后的CIDR
                        299        const range = lastBroadcast - first.networkInt + 1;
                        300        const mergedCIDR = 32 - Math.ceil(Math.log2(range));
                        301        
                        302        const mergedNetworkIP = this.intToIP(first.networkInt);
                        303        const mergedNetwork = `${mergedNetworkIP}/${mergedCIDR}`;
                        304        const mergedHostCount = this.getUsableHosts(mergedCIDR);
                        305        
                        306        return {
                        307            network: mergedNetwork,
                        308            originalSubnets: subnetGroup.map(s => s.network),
                        309            hostCount: mergedHostCount
                        310        };
                        311    }
                        312
                        313    /**
                        314     * 超网计算
                        315     */
                        316    calculateSupernet(startIP, endIP, options = {}) {
                        317        if (!this.validateIP(startIP) || !this.validateIP(endIP)) {
                        318            throw new Error('无效的IP地址格式');
                        319        }
                        320        
                        321        const startInt = this.ipToInt(startIP);
                        322        const endInt = this.ipToInt(endIP);
                        323        
                        324        if (startInt > endInt) {
                        325            throw new Error('起始IP不能大于结束IP');
                        326        }
                        327        
                        328        // 计算包含该范围的最小超网
                        329        const range = endInt - startInt + 1;
                        330        const requiredCIDR = 32 - Math.ceil(Math.log2(range));
                        331        
                        332        // 找到包含该范围的最小网络地址
                        333        const mask = (0xFFFFFFFF << (32 - requiredCIDR)) >>> 0;
                        334        const networkInt = startInt & mask;
                        335        const networkIP = this.intToIP(networkInt);
                        336        
                        337        // 验证该网络是否包含整个范围
                        338        const broadcastInt = networkInt | (~mask >>> 0);
                        339        if (broadcastInt < endInt) {
                        340            // 需要更大的网络
                        341            const newCIDR = requiredCIDR - 1;
                        342            const newMask = (0xFFFFFFFF << (32 - newCIDR)) >>> 0;
                        343            const newNetworkInt = startInt & newMask;
                        344            const newNetworkIP = this.intToIP(newNetworkInt);
                        345            
                        346            return {
                        347                networkAddress: newNetworkIP,
                        348                subnetMask: this.getSubnetMask(newCIDR),
                        349                cidr: newCIDR,
                        350                networkAddress: newNetworkIP,
                        351                broadcastAddress: this.intToIP(newNetworkInt | (~newMask >>> 0)),
                        352                firstHost: this.intToIP(newNetworkInt + 1),
                        353                lastHost: this.intToIP((newNetworkInt | (~newMask >>> 0)) - 1),
                        354                totalHosts: this.getUsableHosts(newCIDR),
                        355                startIP: startIP,
                        356                endIP: endIP,
                        357                details: `计算得到包含范围 ${startIP}-${endIP} 的最小超网 ${newNetworkIP}/${newCIDR}`
                        358            };
                        359        }
                        360        
                        361        return {
                        362            networkAddress: networkIP,
                        363            subnetMask: this.getSubnetMask(requiredCIDR),
                        364            cidr: requiredCIDR,
                        365            networkAddress: networkIP,
                        366            broadcastAddress: this.intToIP(broadcastInt),
                        367            firstHost: this.intToIP(networkInt + 1),
                        368            lastHost: this.intToIP(broadcastInt - 1),
                        369            totalHosts: this.getUsableHosts(requiredCIDR),
                        370            startIP: startIP,
                        371            endIP: endIP,
                        372            details: `计算得到包含范围 ${startIP}-${endIP} 的最小超网 ${networkIP}/${requiredCIDR}`
                        373        };
                        374    }
                        375
                        376    /**
                        377     * 网络规划
                        378     */
                        379    generateNetworkPlan(addressSpace, departmentRequirements, options = {}) {
                        380        const { ip: networkIP, cidr: networkCIDR } = this.parseCIDR(addressSpace);
                        381        const networkInt = this.ipToInt(this.getNetworkAddress(networkIP, networkCIDR));
                        382        const totalSpace = this.getUsableHosts(networkCIDR);
                        383        
                        384        // 按部门大小排序
                        385        let sortedDepartments = [...departmentRequirements];
                        386        if (options.optimizeUtilization) {
                        387            sortedDepartments.sort((a, b) => b.size - a.size);
                        388        }
                        389        
                        390        const departments = [];
                        391        let currentNetworkInt = networkInt;
                        392        let allocatedSpace = 0;
                        393        
                        394        for (const dept of sortedDepartments) {
                        395            const requiredHosts = dept.size + (options.reserveSpace ? Math.ceil(dept.size * 0.2) : 0);
                        396            const requiredCIDR = 32 - Math.ceil(Math.log2(requiredHosts + 2)); // +2 for network and broadcast
                        397            
                        398            if (requiredCIDR < networkCIDR) {
                        399                throw new Error(`部门 ${dept.name} 需要的主机数超出可用空间`);
                        400            }
                        401            
                        402            const deptNetworkIP = this.intToIP(currentNetworkInt);
                        403            const deptSubnetMask = this.getSubnetMask(requiredCIDR);
                        404            const deptHosts = this.getUsableHosts(requiredCIDR);
                        405            
                        406            departments.push({
                        407                name: dept.name,
                        408                networkAddress: deptNetworkIP,
                        409                subnetMask: deptSubnetMask,
                        410                cidr: requiredCIDR,
                        411                firstHost: this.getFirstHost(deptNetworkIP, requiredCIDR),
                        412                lastHost: this.getLastHost(deptNetworkIP, requiredCIDR),
                        413                allocatedHosts: dept.size,
                        414                totalHosts: deptHosts
                        415            });
                        416            
                        417            allocatedSpace += deptHosts;
                        418            const subnetSize = Math.pow(2, 32 - requiredCIDR);
                        419            currentNetworkInt += subnetSize;
                        420        }
                        421        
                        422        const remainingSpace = totalSpace - allocatedSpace;
                        423        const utilization = ((allocatedSpace / totalSpace) * 100).toFixed(2);
                        424        
                        425        return {
                        426            departments: departments,
                        427            summary: {
                        428                totalSpace: totalSpace,
                        429                allocatedSpace: allocatedSpace,
                        430                remainingSpace: remainingSpace,
                        431                utilization: utilization,
                        432                departmentCount: departments.length
                        433            },
                        434            details: `网络规划完成,共分配 ${departments.length} 个部门,地址利用率 ${utilization}%,剩余空间 ${remainingSpace} 个主机`
                        435        };
                        436    }
                        437}
                        438
                        439// 使用示例
                        440const calculator = new SubnetCalculator();
                        441
                        442// VLSM示例
                        443console.log('=== VLSM子网划分示例 ===');
                        444try {
                        445    const vlsmResult = calculator.calculateVLSM('192.168.1.0/24', [
                        446        { name: '销售部', hosts: 50 },
                        447        { name: '技术部', hosts: 30 },
                        448        { name: '财务部', hosts: 10 },
                        449        { name: '人事部', hosts: 5 }
                        450    ]);
                        451    console.log('VLSM结果:', JSON.stringify(vlsmResult, null, 2));
                        452} catch (error) {
                        453    console.error('VLSM错误:', error.message);
                        454}
                        455
                        456// 子网合并示例
                        457console.log('\n=== 子网合并示例 ===');
                        458try {
                        459    const mergeResult = calculator.mergeSubnets([
                        460        '192.168.1.0/26',
                        461        '192.168.1.64/26',
                        462        '192.168.1.128/26',
                        463        '192.168.1.192/26'
                        464    ]);
                        465    console.log('合并结果:', JSON.stringify(mergeResult, null, 2));
                        466} catch (error) {
                        467    console.error('合并错误:', error.message);
                        468}
                        469
                        470// 超网计算示例
                        471console.log('\n=== 超网计算示例 ===');
                        472try {
                        473    const supernetResult = calculator.calculateSupernet('192.168.1.10', '192.168.1.50');
                        474    console.log('超网结果:', JSON.stringify(supernetResult, null, 2));
                        475} catch (error) {
                        476    console.error('超网错误:', error.message);
                        477}
                        478
                        479// 网络规划示例
                        480console.log('\n=== 网络规划示例 ===');
                        481try {
                        482    const planningResult = calculator.generateNetworkPlan('10.0.0.0/8', [
                        483        { name: '总部', size: 200 },
                        484        { name: '分公司A', size: 100 },
                        485        { name: '分公司B', size: 80 },
                        486        { name: '研发中心', size: 150 }
                        487    ]);
                        488    console.log('规划结果:', JSON.stringify(planningResult, null, 2));
                        489} catch (error) {
                        490    console.error('规划错误:', error.message);
                        491}
                        
  • subnet_calculator (PHP)
    subnet_calculator.php
      1<?php
                          2/**
                          3 * 子网划分工具 - PHP版本
                          4 * 支持VLSM可变长子网掩码、子网合并、超网计算、网络规划等功能
                          5 */
                          6class SubnetCalculator {
                          7    private $ipRegex;
                          8    private $cidrRegex;
                          9    
                         10    public function __construct() {
                         11        $this->ipRegex = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
                         12        $this->cidrRegex = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]|[1-2][0-9]|3[0-2])$/';
                         13    }
                         14    
                         15    /**
                         16     * 验证IP地址格式
                         17     */
                         18    public function validateIP($ip) {
                         19        return preg_match($this->ipRegex, $ip);
                         20    }
                         21    
                         22    /**
                         23     * 验证CIDR格式
                         24     */
                         25    public function validateCIDR($cidr) {
                         26        return preg_match($this->cidrRegex, $cidr);
                         27    }
                         28    
                         29    /**
                         30     * IP地址转换为整数
                         31     */
                         32    public function ipToInt($ip) {
                         33        if (!$this->validateIP($ip)) {
                         34            throw new Exception('无效的IP地址格式');
                         35        }
                         36        
                         37        $parts = explode('.', $ip);
                         38        return ($parts[0] << 24) + ($parts[1] << 16) + ($parts[2] << 8) + $parts[3];
                         39    }
                         40    
                         41    /**
                         42     * 整数转换为IP地址
                         43     */
                         44    public function intToIP($ipInt) {
                         45        return sprintf('%d.%d.%d.%d',
                         46            ($ipInt >> 24) & 255,
                         47            ($ipInt >> 16) & 255,
                         48            ($ipInt >> 8) & 255,
                         49            $ipInt & 255
                         50        );
                         51    }
                         52    
                         53    /**
                         54     * 获取子网掩码
                         55     */
                         56    public function getSubnetMask($cidr) {
                         57        $mask = (0xFFFFFFFF << (32 - $cidr)) & 0xFFFFFFFF;
                         58        return $this->intToIP($mask);
                         59    }
                         60    
                         61    /**
                         62     * 获取网络地址
                         63     */
                         64    public function getNetworkAddress($ip, $cidr) {
                         65        $ipInt = $this->ipToInt($ip);
                         66        $mask = (0xFFFFFFFF << (32 - $cidr)) & 0xFFFFFFFF;
                         67        $networkInt = $ipInt & $mask;
                         68        return $this->intToIP($networkInt);
                         69    }
                         70    
                         71    /**
                         72     * 获取广播地址
                         73     */
                         74    public function getBroadcastAddress($ip, $cidr) {
                         75        $ipInt = $this->ipToInt($ip);
                         76        $mask = (0xFFFFFFFF << (32 - $cidr)) & 0xFFFFFFFF;
                         77        $broadcastInt = $ipInt | (~$mask & 0xFFFFFFFF);
                         78        return $this->intToIP($broadcastInt);
                         79    }
                         80    
                         81    /**
                         82     * 获取第一个可用主机地址
                         83     */
                         84    public function getFirstHost($ip, $cidr) {
                         85        $networkIP = $this->getNetworkAddress($ip, $cidr);
                         86        $networkInt = $this->ipToInt($networkIP);
                         87        return $this->intToIP($networkInt + 1);
                         88    }
                         89    
                         90    /**
                         91     * 获取最后一个可用主机地址
                         92     */
                         93    public function getLastHost($ip, $cidr) {
                         94        $broadcastIP = $this->getBroadcastAddress($ip, $cidr);
                         95        $broadcastInt = $this->ipToInt($broadcastIP);
                         96        return $this->intToIP($broadcastInt - 1);
                         97    }
                         98    
                         99    /**
                        100     * 计算可用主机数量
                        101     */
                        102    public function getUsableHosts($cidr) {
                        103        return pow(2, 32 - $cidr) - 2;
                        104    }
                        105    
                        106    /**
                        107     * 解析CIDR格式
                        108     */
                        109    public function parseCIDR($cidr) {
                        110        if (!$this->validateCIDR($cidr)) {
                        111            throw new Exception('无效的CIDR格式');
                        112        }
                        113        
                        114        $parts = explode('/', $cidr);
                        115        return [
                        116            'ip' => $parts[0],
                        117            'cidr' => (int)$parts[1],
                        118            'subnet_mask' => $this->getSubnetMask((int)$parts[1])
                        119        ];
                        120    }
                        121    
                        122    /**
                        123     * VLSM子网划分
                        124     */
                        125    public function calculateVLSM($networkCIDR, $subnetRequirements, $options = []) {
                        126        $parsed = $this->parseCIDR($networkCIDR);
                        127        $networkIP = $parsed['ip'];
                        128        $networkCIDRBits = $parsed['cidr'];
                        129        
                        130        $networkAddress = $this->getNetworkAddress($networkIP, $networkCIDRBits);
                        131        $networkInt = $this->ipToInt($networkAddress);
                        132        $totalHosts = $this->getUsableHosts($networkCIDRBits);
                        133        
                        134        // 按主机数量排序(如果需要)
                        135        $sortedRequirements = $subnetRequirements;
                        136        if (isset($options['optimize_order']) && $options['optimize_order']) {
                        137            usort($sortedRequirements, function($a, $b) {
                        138                return $b['hosts'] - $a['hosts'];
                        139            });
                        140        }
                        141        
                        142        // 计算每个子网需要的掩码位数
                        143        $subnets = [];
                        144        $currentNetworkInt = $networkInt;
                        145        
                        146        foreach ($sortedRequirements as $requirement) {
                        147            $requiredHosts = $requirement['hosts'];
                        148            if (isset($options['include_network_broadcast']) && $options['include_network_broadcast']) {
                        149                $requiredHosts += 2;
                        150            }
                        151            
                        152            $requiredCIDR = 32 - ceil(log($requiredHosts, 2));
                        153            
                        154            if ($requiredCIDR < $networkCIDRBits) {
                        155                throw new Exception("子网 {$requirement['name']} 需要的主机数超出可用空间");
                        156            }
                        157            
                        158            $subnetNetworkIP = $this->intToIP($currentNetworkInt);
                        159            $subnetMask = $this->getSubnetMask($requiredCIDR);
                        160            $subnetHosts = $this->getUsableHosts($requiredCIDR);
                        161            
                        162            $firstHost = $this->getFirstHost($subnetNetworkIP, $requiredCIDR);
                        163            $lastHost = $this->getLastHost($subnetNetworkIP, $requiredCIDR);
                        164            $broadcastAddress = $this->getBroadcastAddress($subnetNetworkIP, $requiredCIDR);
                        165            
                        166            $subnets[] = [
                        167                'name' => $requirement['name'],
                        168                'network_address' => $subnetNetworkIP,
                        169                'subnet_mask' => $subnetMask,
                        170                'cidr' => $requiredCIDR,
                        171                'first_host' => $firstHost,
                        172                'last_host' => $lastHost,
                        173                'broadcast_address' => $broadcastAddress,
                        174                'usable_hosts' => $subnetHosts,
                        175                'required_hosts' => $requirement['hosts']
                        176            ];
                        177            
                        178            // 计算下一个子网的起始地址
                        179            $subnetSize = pow(2, 32 - $requiredCIDR);
                        180            $currentNetworkInt += $subnetSize;
                        181        }
                        182        
                        183        // 计算汇总信息
                        184        $totalRequiredHosts = array_sum(array_column($sortedRequirements, 'hosts'));
                        185        $utilization = round(($totalRequiredHosts / $totalHosts) * 100, 2);
                        186        
                        187        return [
                        188            'subnets' => $subnets,
                        189            'summary' => [
                        190                'original_network' => $networkCIDR,
                        191                'total_subnets' => count($subnets),
                        192                'total_hosts' => $totalRequiredHosts,
                        193                'utilization' => $utilization
                        194            ],
                        195            'details' => "VLSM划分完成,共创建 " . count($subnets) . " 个子网,地址利用率 {$utilization}%"
                        196        ];
                        197    }
                        198    
                        199    /**
                        200     * 子网合并
                        201     */
                        202    public function mergeSubnets($subnetList, $options = []) {
                        203        $subnets = [];
                        204        
                        205        // 解析子网列表
                        206        foreach ($subnetList as $subnetStr) {
                        207            if (!$this->validateCIDR($subnetStr)) {
                        208                if (isset($options['validate_subnets']) && $options['validate_subnets']) {
                        209                    throw new Exception("无效的子网格式: {$subnetStr}");
                        210                }
                        211                continue;
                        212            }
                        213            
                        214            $parsed = $this->parseCIDR($subnetStr);
                        215            $networkIP = $this->getNetworkAddress($parsed['ip'], $parsed['cidr']);
                        216            $networkInt = $this->ipToInt($networkIP);
                        217            
                        218            $subnets[] = [
                        219                'network' => $subnetStr,
                        220                'network_ip' => $networkIP,
                        221                'cidr' => $parsed['cidr'],
                        222                'network_int' => $networkInt,
                        223                'host_count' => $this->getUsableHosts($parsed['cidr'])
                        224            ];
                        225        }
                        226        
                        227        if (empty($subnets)) {
                        228            throw new Exception('没有有效的子网可以合并');
                        229        }
                        230        
                        231        // 按网络地址排序
                        232        usort($subnets, function($a, $b) {
                        233            return $a['network_int'] - $b['network_int'];
                        234        });
                        235        
                        236        $mergedSubnets = [];
                        237        $currentGroup = [$subnets[0]];
                        238        
                        239        for ($i = 1; $i < count($subnets); $i++) {
                        240            $current = $subnets[$i];
                        241            $last = $currentGroup[count($currentGroup) - 1];
                        242            
                        243            // 检查是否相邻或连续
                        244            $isAdjacent = false;
                        245            $isContiguous = false;
                        246            
                        247            if (isset($options['merge_adjacent']) && $options['merge_adjacent']) {
                        248                $isAdjacent = $this->areSubnetsAdjacent($last, $current);
                        249            }
                        250            
                        251            if (isset($options['merge_contiguous']) && $options['merge_contiguous']) {
                        252                $isContiguous = $this->areSubnetsContiguous($last, $current);
                        253            }
                        254            
                        255            if ($isAdjacent || $isContiguous) {
                        256                $currentGroup[] = $current;
                        257            } else {
                        258                // 合并当前组
                        259                if (count($currentGroup) > 1) {
                        260                    $mergedSubnets[] = $this->mergeSubnetGroup($currentGroup);
                        261                } else {
                        262                    $mergedSubnets[] = [
                        263                        'network' => $currentGroup[0]['network'],
                        264                        'original_subnets' => [$currentGroup[0]['network']],
                        265                        'host_count' => $currentGroup[0]['host_count']
                        266                    ];
                        267                }
                        268                $currentGroup = [$current];
                        269            }
                        270        }
                        271        
                        272        // 处理最后一组
                        273        if (count($currentGroup) > 1) {
                        274            $mergedSubnets[] = $this->mergeSubnetGroup($currentGroup);
                        275        } else {
                        276            $mergedSubnets[] = [
                        277                'network' => $currentGroup[0]['network'],
                        278                'original_subnets' => [$currentGroup[0]['network']],
                        279                'host_count' => $currentGroup[0]['host_count']
                        280            ];
                        281        }
                        282        
                        283        // 计算汇总信息
                        284        $originalCount = count($subnets);
                        285        $mergedCount = count($mergedSubnets);
                        286        $reduction = $originalCount - $mergedCount;
                        287        $totalHosts = array_sum(array_column($mergedSubnets, 'host_count'));
                        288        
                        289        return [
                        290            'merged_subnets' => $mergedSubnets,
                        291            'summary' => [
                        292                'original_count' => $originalCount,
                        293                'merged_count' => $mergedCount,
                        294                'reduction' => $reduction,
                        295                'total_hosts' => $totalHosts,
                        296                'utilization' => round(($totalHosts / (pow(2, 32) - 1)) * 100, 4)
                        297            ],
                        298            'details' => "合并完成,从 {$originalCount} 个子网合并为 {$mergedCount} 个,减少 {$reduction} 个"
                        299        ];
                        300    }
                        301    
                        302    /**
                        303     * 检查两个子网是否相邻
                        304     */
                        305    private function areSubnetsAdjacent($subnet1, $subnet2) {
                        306        $broadcast1 = $this->ipToInt($this->getBroadcastAddress($subnet1['network_ip'], $subnet1['cidr']));
                        307        $network2 = $subnet2['network_int'];
                        308        return $network2 == $broadcast1 + 1;
                        309    }
                        310    
                        311    /**
                        312     * 检查两个子网是否连续
                        313     */
                        314    private function areSubnetsContiguous($subnet1, $subnet2) {
                        315        $broadcast1 = $this->ipToInt($this->getBroadcastAddress($subnet1['network_ip'], $subnet1['cidr']));
                        316        $network2 = $subnet2['network_int'];
                        317        return $network2 <= $broadcast1 + 1;
                        318    }
                        319    
                        320    /**
                        321     * 合并子网组
                        322     */
                        323    private function mergeSubnetGroup($subnetGroup) {
                        324        $first = $subnetGroup[0];
                        325        $last = $subnetGroup[count($subnetGroup) - 1];
                        326        $lastBroadcast = $this->ipToInt($this->getBroadcastAddress($last['network_ip'], $last['cidr']));
                        327        
                        328        // 计算合并后的CIDR
                        329        $rangeSize = $lastBroadcast - $first['network_int'] + 1;
                        330        $mergedCIDR = 32 - ceil(log($rangeSize, 2));
                        331        
                        332        $mergedNetworkIP = $this->intToIP($first['network_int']);
                        333        $mergedNetwork = "{$mergedNetworkIP}/{$mergedCIDR}";
                        334        $mergedHostCount = $this->getUsableHosts($mergedCIDR);
                        335        
                        336        $originalSubnets = array_column($subnetGroup, 'network');
                        337        
                        338        return [
                        339            'network' => $mergedNetwork,
                        340            'original_subnets' => $originalSubnets,
                        341            'host_count' => $mergedHostCount
                        342        ];
                        343    }
                        344    
                        345    /**
                        346     * 超网计算
                        347     */
                        348    public function calculateSupernet($startIP, $endIP, $options = []) {
                        349        if (!$this->validateIP($startIP) || !$this->validateIP($endIP)) {
                        350            throw new Exception('无效的IP地址格式');
                        351        }
                        352        
                        353        $startInt = $this->ipToInt($startIP);
                        354        $endInt = $this->ipToInt($endIP);
                        355        
                        356        if ($startInt > $endInt) {
                        357            throw new Exception('起始IP不能大于结束IP');
                        358        }
                        359        
                        360        // 计算包含该范围的最小超网
                        361        $rangeSize = $endInt - $startInt + 1;
                        362        $requiredCIDR = 32 - ceil(log($rangeSize, 2));
                        363        
                        364        // 找到包含该范围的最小网络地址
                        365        $mask = (0xFFFFFFFF << (32 - $requiredCIDR)) & 0xFFFFFFFF;
                        366        $networkInt = $startInt & $mask;
                        367        $networkIP = $this->intToIP($networkInt);
                        368        
                        369        // 验证该网络是否包含整个范围
                        370        $broadcastInt = $networkInt | (~$mask & 0xFFFFFFFF);
                        371        if ($broadcastInt < $endInt) {
                        372            // 需要更大的网络
                        373            $newCIDR = $requiredCIDR - 1;
                        374            $newMask = (0xFFFFFFFF << (32 - $newCIDR)) & 0xFFFFFFFF;
                        375            $newNetworkInt = $startInt & $newMask;
                        376            $newNetworkIP = $this->intToIP($newNetworkInt);
                        377            
                        378            return [
                        379                'network_address' => $newNetworkIP,
                        380                'subnet_mask' => $this->getSubnetMask($newCIDR),
                        381                'cidr' => $newCIDR,
                        382                'broadcast_address' => $this->intToIP($newNetworkInt | (~$newMask & 0xFFFFFFFF)),
                        383                'first_host' => $this->intToIP($newNetworkInt + 1),
                        384                'last_host' => $this->intToIP(($newNetworkInt | (~$newMask & 0xFFFFFFFF)) - 1),
                        385                'total_hosts' => $this->getUsableHosts($newCIDR),
                        386                'start_ip' => $startIP,
                        387                'end_ip' => $endIP,
                        388                'details' => "计算得到包含范围 {$startIP}-{$endIP} 的最小超网 {$newNetworkIP}/{$newCIDR}"
                        389            ];
                        390        }
                        391        
                        392        return [
                        393            'network_address' => $networkIP,
                        394            'subnet_mask' => $this->getSubnetMask($requiredCIDR),
                        395            'cidr' => $requiredCIDR,
                        396            'broadcast_address' => $this->intToIP($broadcastInt),
                        397            'first_host' => $this->intToIP($networkInt + 1),
                        398            'last_host' => $this->intToIP($broadcastInt - 1),
                        399            'total_hosts' => $this->getUsableHosts($requiredCIDR),
                        400            'start_ip' => $startIP,
                        401            'end_ip' => $endIP,
                        402            'details' => "计算得到包含范围 {$startIP}-{$endIP} 的最小超网 {$networkIP}/{$requiredCIDR}"
                        403        ];
                        404    }
                        405    
                        406    /**
                        407     * 网络规划
                        408     */
                        409    public function generateNetworkPlan($addressSpace, $departmentRequirements, $options = []) {
                        410        $parsed = $this->parseCIDR($addressSpace);
                        411        $networkIP = $parsed['ip'];
                        412        $networkCIDRBits = $parsed['cidr'];
                        413        
                        414        $networkAddress = $this->getNetworkAddress($networkIP, $networkCIDRBits);
                        415        $networkInt = $this->ipToInt($networkAddress);
                        416        $totalSpace = $this->getUsableHosts($networkCIDRBits);
                        417        
                        418        // 按部门大小排序
                        419        $sortedDepartments = $departmentRequirements;
                        420        if (isset($options['optimize_utilization']) && $options['optimize_utilization']) {
                        421            usort($sortedDepartments, function($a, $b) {
                        422                return $b['size'] - $a['size'];
                        423            });
                        424        }
                        425        
                        426        $departments = [];
                        427        $currentNetworkInt = $networkInt;
                        428        $allocatedSpace = 0;
                        429        
                        430        foreach ($sortedDepartments as $dept) {
                        431            $requiredHosts = $dept['size'];
                        432            if (isset($options['reserve_space']) && $options['reserve_space']) {
                        433                $requiredHosts += ceil($dept['size'] * 0.2);
                        434            }
                        435            
                        436            $requiredCIDR = 32 - ceil(log($requiredHosts + 2, 2)); // +2 for network and broadcast
                        437            
                        438            if ($requiredCIDR < $networkCIDRBits) {
                        439                throw new Exception("部门 {$dept['name']} 需要的主机数超出可用空间");
                        440            }
                        441            
                        442            $deptNetworkIP = $this->intToIP($currentNetworkInt);
                        443            $deptSubnetMask = $this->getSubnetMask($requiredCIDR);
                        444            $deptHosts = $this->getUsableHosts($requiredCIDR);
                        445            
                        446            $firstHost = $this->getFirstHost($deptNetworkIP, $requiredCIDR);
                        447            $lastHost = $this->getLastHost($deptNetworkIP, $requiredCIDR);
                        448            
                        449            $departments[] = [
                        450                'name' => $dept['name'],
                        451                'network_address' => $deptNetworkIP,
                        452                'subnet_mask' => $deptSubnetMask,
                        453                'cidr' => $requiredCIDR,
                        454                'first_host' => $firstHost,
                        455                'last_host' => $lastHost,
                        456                'allocated_hosts' => $dept['size'],
                        457                'total_hosts' => $deptHosts
                        458            ];
                        459            
                        460            $allocatedSpace += $deptHosts;
                        461            $subnetSize = pow(2, 32 - $requiredCIDR);
                        462            $currentNetworkInt += $subnetSize;
                        463        }
                        464        
                        465        $remainingSpace = $totalSpace - $allocatedSpace;
                        466        $utilization = round(($allocatedSpace / $totalSpace) * 100, 2);
                        467        
                        468        return [
                        469            'departments' => $departments,
                        470            'summary' => [
                        471                'total_space' => $totalSpace,
                        472                'allocated_space' => $allocatedSpace,
                        473                'remaining_space' => $remainingSpace,
                        474                'utilization' => $utilization,
                        475                'department_count' => count($departments)
                        476            ],
                        477            'details' => "网络规划完成,共分配 " . count($departments) . " 个部门,地址利用率 {$utilization}%,剩余空间 {$remainingSpace} 个主机"
                        478        ];
                        479    }
                        480    
                        481    /**
                        482     * 获取子网详细信息(使用PHP内置函数)
                        483     */
                        484    public function getSubnetInfo($ip, $cidr) {
                        485        try {
                        486            $network = "{$ip}/{$cidr}";
                        487            $networkInt = ip2long($ip);
                        488            $mask = (0xFFFFFFFF << (32 - $cidr)) & 0xFFFFFFFF;
                        489            $networkAddress = long2ip($networkInt & $mask);
                        490            $broadcastAddress = long2ip($networkInt | (~$mask & 0xFFFFFFFF));
                        491            
                        492            return [
                        493                'network_address' => $networkAddress,
                        494                'broadcast_address' => $broadcastAddress,
                        495                'subnet_mask' => long2ip($mask),
                        496                'num_addresses' => pow(2, 32 - $cidr),
                        497                'usable_hosts' => pow(2, 32 - $cidr) - 2,
                        498                'first_host' => long2ip(($networkInt & $mask) + 1),
                        499                'last_host' => long2ip(($networkInt | (~$mask & 0xFFFFFFFF)) - 1)
                        500            ];
                        501        } catch (Exception $e) {
                        502            throw new Exception("无法解析子网信息: " . $e->getMessage());
                        503        }
                        504    }
                        505}
                        506
                        507// 使用示例
                        508function main() {
                        509    $calculator = new SubnetCalculator();
                        510    
                        511    echo "=== 子网划分工具 - PHP版本 ===\n";
                        512    
                        513    // VLSM示例
                        514    echo "\n--- VLSM子网划分示例 ---\n";
                        515    try {
                        516        $vlsmResult = $calculator->calculateVLSM('192.168.1.0/24', [
                        517            ['name' => '销售部', 'hosts' => 50],
                        518            ['name' => '技术部', 'hosts' => 30],
                        519            ['name' => '财务部', 'hosts' => 10],
                        520            ['name' => '人事部', 'hosts' => 5]
                        521        ], [
                        522            'optimize_order' => true,
                        523            'include_network_broadcast' => true
                        524        ]);
                        525        
                        526        echo "VLSM结果:\n";
                        527        foreach ($vlsmResult['subnets'] as $subnet) {
                        528            echo "  {$subnet['name']}: {$subnet['network_address']}/{$subnet['cidr']} ({$subnet['first_host']} - {$subnet['last_host']})\n";
                        529        }
                        530        echo "汇总: 原始网络={$vlsmResult['summary']['original_network']}, 总子网数={$vlsmResult['summary']['total_subnets']}, 总主机数={$vlsmResult['summary']['total_hosts']}, 利用率={$vlsmResult['summary']['utilization']}%\n";
                        531    } catch (Exception $e) {
                        532        echo "VLSM错误: " . $e->getMessage() . "\n";
                        533    }
                        534    
                        535    // 子网合并示例
                        536    echo "\n--- 子网合并示例 ---\n";
                        537    try {
                        538        $mergeResult = $calculator->mergeSubnets([
                        539            '192.168.1.0/26',
                        540            '192.168.1.64/26',
                        541            '192.168.1.128/26',
                        542            '192.168.1.192/26'
                        543        ], [
                        544            'merge_adjacent' => true,
                        545            'merge_contiguous' => true,
                        546            'validate_subnets' => true
                        547        ]);
                        548        
                        549        echo "合并结果:\n";
                        550        foreach ($mergeResult['merged_subnets'] as $merged) {
                        551            echo "  {$merged['network']} (包含: " . implode(', ', $merged['original_subnets']) . ")\n";
                        552        }
                        553        echo "汇总: 原子网数={$mergeResult['summary']['original_count']}, 合并后={$mergeResult['summary']['merged_count']}, 减少={$mergeResult['summary']['reduction']}, 利用率={$mergeResult['summary']['utilization']}%\n";
                        554    } catch (Exception $e) {
                        555        echo "合并错误: " . $e->getMessage() . "\n";
                        556    }
                        557    
                        558    // 超网计算示例
                        559    echo "\n--- 超网计算示例 ---\n";
                        560    try {
                        561        $supernetResult = $calculator->calculateSupernet('192.168.1.10', '192.168.1.50');
                        562        echo "超网结果: {$supernetResult['network_address']}/{$supernetResult['cidr']}\n";
                        563        echo "详细信息: {$supernetResult['details']}\n";
                        564    } catch (Exception $e) {
                        565        echo "超网错误: " . $e->getMessage() . "\n";
                        566    }
                        567    
                        568    // 网络规划示例
                        569    echo "\n--- 网络规划示例 ---\n";
                        570    try {
                        571        $planningResult = $calculator->generateNetworkPlan('10.0.0.0/8', [
                        572            ['name' => '总部', 'size' => 200],
                        573            ['name' => '分公司A', 'size' => 100],
                        574            ['name' => '分公司B', 'size' => 80],
                        575            ['name' => '研发中心', 'size' => 150]
                        576        ], [
                        577            'optimize_utilization' => true,
                        578            'reserve_space' => true
                        579        ]);
                        580        
                        581        echo "规划结果:\n";
                        582        foreach ($planningResult['departments'] as $dept) {
                        583            echo "  {$dept['name']}: {$dept['network_address']}/{$dept['cidr']} ({$dept['allocated_hosts']} 主机)\n";
                        584        }
                        585        echo "汇总: 总空间={$planningResult['summary']['total_space']}, 已分配={$planningResult['summary']['allocated_space']}, 剩余={$planningResult['summary']['remaining_space']}, 利用率={$planningResult['summary']['utilization']}%, 部门数={$planningResult['summary']['department_count']}\n";
                        586    } catch (Exception $e) {
                        587        echo "规划错误: " . $e->getMessage() . "\n";
                        588    }
                        589}
                        590
                        591// 如果直接运行此文件,则执行主函数
                        592if (basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])) {
                        593    main();
                        594}
                        595?>
                        
  • subnet_calculator (PY)
    subnet_calculator.py
      1#!/usr/bin/env python3
                          2# -*- coding: utf-8 -*-
                          3"""
                          4子网划分工具 - Python版本
                          5支持VLSM可变长子网掩码、子网合并、超网计算、网络规划等功能
                          6"""
                          7import re
                          8import ipaddress
                          9from typing import Dict, List, Tuple, Optional, Union
                         10import math
                         11
                         12
                         13class SubnetCalculator:
                         14    """子网划分计算器类"""
                         15    
                         16    def __init__(self):
                         17        self.ip_regex = re.compile(r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$')
                         18        self.cidr_regex = re.compile(r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]|[1-2][0-9]|3[0-2])$')
                         19    
                         20    def validate_ip(self, ip: str) -> bool:
                         21        """验证IP地址格式"""
                         22        return bool(self.ip_regex.match(ip))
                         23    
                         24    def validate_cidr(self, cidr: str) -> bool:
                         25        """验证CIDR格式"""
                         26        return bool(self.cidr_regex.match(cidr))
                         27    
                         28    def ip_to_int(self, ip: str) -> int:
                         29        """IP地址转换为整数"""
                         30        if not self.validate_ip(ip):
                         31            raise ValueError('无效的IP地址格式')
                         32        
                         33        parts = [int(part) for part in ip.split('.')]
                         34        return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3]
                         35    
                         36    def int_to_ip(self, ip_int: int) -> str:
                         37        """整数转换为IP地址"""
                         38        return '.'.join([
                         39            str((ip_int >> 24) & 255),
                         40            str((ip_int >> 16) & 255),
                         41            str((ip_int >> 8) & 255),
                         42            str(ip_int & 255)
                         43        ])
                         44    
                         45    def get_subnet_mask(self, cidr: int) -> str:
                         46        """获取子网掩码"""
                         47        mask = (0xFFFFFFFF << (32 - cidr)) & 0xFFFFFFFF
                         48        return self.int_to_ip(mask)
                         49    
                         50    def get_network_address(self, ip: str, cidr: int) -> str:
                         51        """获取网络地址"""
                         52        ip_int = self.ip_to_int(ip)
                         53        mask = (0xFFFFFFFF << (32 - cidr)) & 0xFFFFFFFF
                         54        network_int = ip_int & mask
                         55        return self.int_to_ip(network_int)
                         56    
                         57    def get_broadcast_address(self, ip: str, cidr: int) -> str:
                         58        """获取广播地址"""
                         59        ip_int = self.ip_to_int(ip)
                         60        mask = (0xFFFFFFFF << (32 - cidr)) & 0xFFFFFFFF
                         61        broadcast_int = ip_int | (~mask & 0xFFFFFFFF)
                         62        return self.int_to_ip(broadcast_int)
                         63    
                         64    def get_first_host(self, ip: str, cidr: int) -> str:
                         65        """获取第一个可用主机地址"""
                         66        network_int = self.ip_to_int(self.get_network_address(ip, cidr))
                         67        return self.int_to_ip(network_int + 1)
                         68    
                         69    def get_last_host(self, ip: str, cidr: int) -> str:
                         70        """获取最后一个可用主机地址"""
                         71        broadcast_int = self.ip_to_int(self.get_broadcast_address(ip, cidr))
                         72        return self.int_to_ip(broadcast_int - 1)
                         73    
                         74    def get_usable_hosts(self, cidr: int) -> int:
                         75        """计算可用主机数量"""
                         76        return 2 ** (32 - cidr) - 2
                         77    
                         78    def parse_cidr(self, cidr: str) -> Dict[str, Union[str, int]]:
                         79        """解析CIDR格式"""
                         80        if not self.validate_cidr(cidr):
                         81            raise ValueError('无效的CIDR格式')
                         82        
                         83        ip, mask_bits = cidr.split('/')
                         84        return {
                         85            'ip': ip,
                         86            'cidr': int(mask_bits),
                         87            'subnet_mask': self.get_subnet_mask(int(mask_bits))
                         88        }
                         89    
                         90    def calculate_vlsm(self, network_cidr: str, subnet_requirements: List[Dict], 
                         91                      options: Optional[Dict] = None) -> Dict:
                         92        """VLSM子网划分"""
                         93        if options is None:
                         94            options = {}
                         95        
                         96        parsed = self.parse_cidr(network_cidr)
                         97        network_ip = parsed['ip']
                         98        network_cidr_bits = parsed['cidr']
                         99        
                        100        network_int = self.ip_to_int(self.get_network_address(network_ip, network_cidr_bits))
                        101        total_hosts = self.get_usable_hosts(network_cidr_bits)
                        102        
                        103        # 按主机数量排序(如果需要)
                        104        sorted_requirements = sorted(subnet_requirements, 
                        105                                   key=lambda x: x['hosts'], 
                        106                                   reverse=options.get('optimize_order', True))
                        107        
                        108        # 计算每个子网需要的掩码位数
                        109        subnets = []
                        110        current_network_int = network_int
                        111        
                        112        for requirement in sorted_requirements:
                        113            required_hosts = requirement['hosts'] + (2 if options.get('include_network_broadcast', True) else 0)
                        114            required_cidr = 32 - math.ceil(math.log2(required_hosts))
                        115            
                        116            if required_cidr < network_cidr_bits:
                        117                raise ValueError(f"子网 {requirement['name']} 需要的主机数超出可用空间")
                        118            
                        119            subnet_network_ip = self.int_to_ip(current_network_int)
                        120            subnet_mask = self.get_subnet_mask(required_cidr)
                        121            subnet_hosts = self.get_usable_hosts(required_cidr)
                        122            
                        123            subnets.append({
                        124                'name': requirement['name'],
                        125                'network_address': subnet_network_ip,
                        126                'subnet_mask': subnet_mask,
                        127                'cidr': required_cidr,
                        128                'first_host': self.get_first_host(subnet_network_ip, required_cidr),
                        129                'last_host': self.get_last_host(subnet_network_ip, required_cidr),
                        130                'broadcast_address': self.get_broadcast_address(subnet_network_ip, required_cidr),
                        131                'usable_hosts': subnet_hosts,
                        132                'required_hosts': requirement['hosts']
                        133            })
                        134            
                        135            # 计算下一个子网的起始地址
                        136            subnet_size = 2 ** (32 - required_cidr)
                        137            current_network_int += subnet_size
                        138        
                        139        # 计算汇总信息
                        140        total_required_hosts = sum(req['hosts'] for req in sorted_requirements)
                        141        utilization = round((total_required_hosts / total_hosts) * 100, 2)
                        142        
                        143        return {
                        144            'subnets': subnets,
                        145            'summary': {
                        146                'original_network': network_cidr,
                        147                'total_subnets': len(subnets),
                        148                'total_hosts': total_required_hosts,
                        149                'utilization': utilization
                        150            },
                        151            'details': f"VLSM划分完成,共创建 {len(subnets)} 个子网,地址利用率 {utilization}%"
                        152        }
                        153    
                        154    def merge_subnets(self, subnet_list: List[str], options: Optional[Dict] = None) -> Dict:
                        155        """子网合并"""
                        156        if options is None:
                        157            options = {}
                        158        
                        159        subnets = []
                        160        
                        161        # 解析子网列表
                        162        for subnet_str in subnet_list:
                        163            if not self.validate_cidr(subnet_str):
                        164                if options.get('validate_subnets', True):
                        165                    raise ValueError(f"无效的子网格式: {subnet_str}")
                        166                continue
                        167            
                        168            parsed = self.parse_cidr(subnet_str)
                        169            network_ip = self.get_network_address(parsed['ip'], parsed['cidr'])
                        170            subnets.append({
                        171                'network': subnet_str,
                        172                'network_ip': network_ip,
                        173                'cidr': parsed['cidr'],
                        174                'network_int': self.ip_to_int(network_ip),
                        175                'host_count': self.get_usable_hosts(parsed['cidr'])
                        176            })
                        177        
                        178        if not subnets:
                        179            raise ValueError('没有有效的子网可以合并')
                        180        
                        181        # 按网络地址排序
                        182        subnets.sort(key=lambda x: x['network_int'])
                        183        
                        184        merged_subnets = []
                        185        current_group = [subnets[0]]
                        186        
                        187        for i in range(1, len(subnets)):
                        188            current = subnets[i]
                        189            last = current_group[-1]
                        190            
                        191            # 检查是否相邻或连续
                        192            is_adjacent = (options.get('merge_adjacent', True) and 
                        193                          self._are_subnets_adjacent(last, current))
                        194            is_contiguous = (options.get('merge_contiguous', True) and 
                        195                           self._are_subnets_contiguous(last, current))
                        196            
                        197            if is_adjacent or is_contiguous:
                        198                current_group.append(current)
                        199            else:
                        200                # 合并当前组
                        201                if len(current_group) > 1:
                        202                    merged_subnets.append(self._merge_subnet_group(current_group))
                        203                else:
                        204                    merged_subnets.append({
                        205                        'network': current_group[0]['network'],
                        206                        'original_subnets': [current_group[0]['network']],
                        207                        'host_count': current_group[0]['host_count']
                        208                    })
                        209                current_group = [current]
                        210        
                        211        # 处理最后一组
                        212        if len(current_group) > 1:
                        213            merged_subnets.append(self._merge_subnet_group(current_group))
                        214        else:
                        215            merged_subnets.append({
                        216                'network': current_group[0]['network'],
                        217                'original_subnets': [current_group[0]['network']],
                        218                'host_count': current_group[0]['host_count']
                        219            })
                        220        
                        221        # 计算汇总信息
                        222        original_count = len(subnets)
                        223        merged_count = len(merged_subnets)
                        224        reduction = original_count - merged_count
                        225        total_hosts = sum(subnet['host_count'] for subnet in merged_subnets)
                        226        
                        227        return {
                        228            'merged_subnets': merged_subnets,
                        229            'summary': {
                        230                'original_count': original_count,
                        231                'merged_count': merged_count,
                        232                'reduction': reduction,
                        233                'total_hosts': total_hosts,
                        234                'utilization': round((total_hosts / (2**32 - 1)) * 100, 4)
                        235            },
                        236            'details': f"合并完成,从 {original_count} 个子网合并为 {merged_count} 个,减少 {reduction} 个"
                        237        }
                        238    
                        239    def _are_subnets_adjacent(self, subnet1: Dict, subnet2: Dict) -> bool:
                        240        """检查两个子网是否相邻"""
                        241        broadcast1 = self.ip_to_int(self.get_broadcast_address(subnet1['network_ip'], subnet1['cidr']))
                        242        network2 = subnet2['network_int']
                        243        return network2 == broadcast1 + 1
                        244    
                        245    def _are_subnets_contiguous(self, subnet1: Dict, subnet2: Dict) -> bool:
                        246        """检查两个子网是否连续"""
                        247        broadcast1 = self.ip_to_int(self.get_broadcast_address(subnet1['network_ip'], subnet1['cidr']))
                        248        network2 = subnet2['network_int']
                        249        return network2 <= broadcast1 + 1
                        250    
                        251    def _merge_subnet_group(self, subnet_group: List[Dict]) -> Dict:
                        252        """合并子网组"""
                        253        first = subnet_group[0]
                        254        last = subnet_group[-1]
                        255        last_broadcast = self.ip_to_int(self.get_broadcast_address(last['network_ip'], last['cidr']))
                        256        
                        257        # 计算合并后的CIDR
                        258        range_size = last_broadcast - first['network_int'] + 1
                        259        merged_cidr = 32 - math.ceil(math.log2(range_size))
                        260        
                        261        merged_network_ip = self.int_to_ip(first['network_int'])
                        262        merged_network = f"{merged_network_ip}/{merged_cidr}"
                        263        merged_host_count = self.get_usable_hosts(merged_cidr)
                        264        
                        265        return {
                        266            'network': merged_network,
                        267            'original_subnets': [s['network'] for s in subnet_group],
                        268            'host_count': merged_host_count
                        269        }
                        270    
                        271    def calculate_supernet(self, start_ip: str, end_ip: str, 
                        272                          options: Optional[Dict] = None) -> Dict:
                        273        """超网计算"""
                        274        if options is None:
                        275            options = {}
                        276        
                        277        if not self.validate_ip(start_ip) or not self.validate_ip(end_ip):
                        278            raise ValueError('无效的IP地址格式')
                        279        
                        280        start_int = self.ip_to_int(start_ip)
                        281        end_int = self.ip_to_int(end_ip)
                        282        
                        283        if start_int > end_int:
                        284            raise ValueError('起始IP不能大于结束IP')
                        285        
                        286        # 计算包含该范围的最小超网
                        287        range_size = end_int - start_int + 1
                        288        required_cidr = 32 - math.ceil(math.log2(range_size))
                        289        
                        290        # 找到包含该范围的最小网络地址
                        291        mask = (0xFFFFFFFF << (32 - required_cidr)) & 0xFFFFFFFF
                        292        network_int = start_int & mask
                        293        network_ip = self.int_to_ip(network_int)
                        294        
                        295        # 验证该网络是否包含整个范围
                        296        broadcast_int = network_int | (~mask & 0xFFFFFFFF)
                        297        if broadcast_int < end_int:
                        298            # 需要更大的网络
                        299            new_cidr = required_cidr - 1
                        300            new_mask = (0xFFFFFFFF << (32 - new_cidr)) & 0xFFFFFFFF
                        301            new_network_int = start_int & new_mask
                        302            new_network_ip = self.int_to_ip(new_network_int)
                        303            
                        304            return {
                        305                'network_address': new_network_ip,
                        306                'subnet_mask': self.get_subnet_mask(new_cidr),
                        307                'cidr': new_cidr,
                        308                'broadcast_address': self.int_to_ip(new_network_int | (~new_mask & 0xFFFFFFFF)),
                        309                'first_host': self.int_to_ip(new_network_int + 1),
                        310                'last_host': self.int_to_ip((new_network_int | (~new_mask & 0xFFFFFFFF)) - 1),
                        311                'total_hosts': self.get_usable_hosts(new_cidr),
                        312                'start_ip': start_ip,
                        313                'end_ip': end_ip,
                        314                'details': f"计算得到包含范围 {start_ip}-{end_ip} 的最小超网 {new_network_ip}/{new_cidr}"
                        315            }
                        316        
                        317        return {
                        318            'network_address': network_ip,
                        319            'subnet_mask': self.get_subnet_mask(required_cidr),
                        320            'cidr': required_cidr,
                        321            'broadcast_address': self.int_to_ip(broadcast_int),
                        322            'first_host': self.int_to_ip(network_int + 1),
                        323            'last_host': self.int_to_ip(broadcast_int - 1),
                        324            'total_hosts': self.get_usable_hosts(required_cidr),
                        325            'start_ip': start_ip,
                        326            'end_ip': end_ip,
                        327            'details': f"计算得到包含范围 {start_ip}-{end_ip} 的最小超网 {network_ip}/{required_cidr}"
                        328        }
                        329    
                        330    def generate_network_plan(self, address_space: str, department_requirements: List[Dict], 
                        331                            options: Optional[Dict] = None) -> Dict:
                        332        """网络规划"""
                        333        if options is None:
                        334            options = {}
                        335        
                        336        parsed = self.parse_cidr(address_space)
                        337        network_ip = parsed['ip']
                        338        network_cidr_bits = parsed['cidr']
                        339        
                        340        network_int = self.ip_to_int(self.get_network_address(network_ip, network_cidr_bits))
                        341        total_space = self.get_usable_hosts(network_cidr_bits)
                        342        
                        343        # 按部门大小排序
                        344        sorted_departments = sorted(department_requirements, 
                        345                                  key=lambda x: x['size'], 
                        346                                  reverse=options.get('optimize_utilization', True))
                        347        
                        348        departments = []
                        349        current_network_int = network_int
                        350        allocated_space = 0
                        351        
                        352        for dept in sorted_departments:
                        353            required_hosts = dept['size'] + (math.ceil(dept['size'] * 0.2) if options.get('reserve_space', True) else 0)
                        354            required_cidr = 32 - math.ceil(math.log2(required_hosts + 2))  # +2 for network and broadcast
                        355            
                        356            if required_cidr < network_cidr_bits:
                        357                raise ValueError(f"部门 {dept['name']} 需要的主机数超出可用空间")
                        358            
                        359            dept_network_ip = self.int_to_ip(current_network_int)
                        360            dept_subnet_mask = self.get_subnet_mask(required_cidr)
                        361            dept_hosts = self.get_usable_hosts(required_cidr)
                        362            
                        363            departments.append({
                        364                'name': dept['name'],
                        365                'network_address': dept_network_ip,
                        366                'subnet_mask': dept_subnet_mask,
                        367                'cidr': required_cidr,
                        368                'first_host': self.get_first_host(dept_network_ip, required_cidr),
                        369                'last_host': self.get_last_host(dept_network_ip, required_cidr),
                        370                'allocated_hosts': dept['size'],
                        371                'total_hosts': dept_hosts
                        372            })
                        373            
                        374            allocated_space += dept_hosts
                        375            subnet_size = 2 ** (32 - required_cidr)
                        376            current_network_int += subnet_size
                        377        
                        378        remaining_space = total_space - allocated_space
                        379        utilization = round((allocated_space / total_space) * 100, 2)
                        380        
                        381        return {
                        382            'departments': departments,
                        383            'summary': {
                        384                'total_space': total_space,
                        385                'allocated_space': allocated_space,
                        386                'remaining_space': remaining_space,
                        387                'utilization': utilization,
                        388                'department_count': len(departments)
                        389            },
                        390            'details': f"网络规划完成,共分配 {len(departments)} 个部门,地址利用率 {utilization}%,剩余空间 {remaining_space} 个主机"
                        391        }
                        392    
                        393    def get_subnet_info(self, ip: str, cidr: int) -> Dict:
                        394        """获取子网详细信息(使用ipaddress模块)"""
                        395        try:
                        396            network = ipaddress.IPv4Network(f"{ip}/{cidr}", strict=False)
                        397            return {
                        398                'network_address': str(network.network_address),
                        399                'broadcast_address': str(network.broadcast_address),
                        400                'subnet_mask': str(network.netmask),
                        401                'num_addresses': network.num_addresses,
                        402                'usable_hosts': network.num_addresses - 2,
                        403                'first_host': str(network.network_address + 1),
                        404                'last_host': str(network.broadcast_address - 1)
                        405            }
                        406        except Exception as e:
                        407            raise ValueError(f"无法解析子网信息: {e}")
                        408
                        409
                        410def main():
                        411    """主函数 - 演示各种功能"""
                        412    calculator = SubnetCalculator()
                        413    
                        414    print("=== 子网划分工具 - Python版本 ===")
                        415    
                        416    # VLSM示例
                        417    print("\n--- VLSM子网划分示例 ---")
                        418    try:
                        419        vlsm_result = calculator.calculate_vlsm('192.168.1.0/24', [
                        420            {'name': '销售部', 'hosts': 50},
                        421            {'name': '技术部', 'hosts': 30},
                        422            {'name': '财务部', 'hosts': 10},
                        423            {'name': '人事部', 'hosts': 5}
                        424        ])
                        425        print("VLSM结果:")
                        426        for subnet in vlsm_result['subnets']:
                        427            print(f"  {subnet['name']}: {subnet['network_address']}/{subnet['cidr']} "
                        428                  f"({subnet['first_host']} - {subnet['last_host']})")
                        429        print(f"汇总: {vlsm_result['summary']}")
                        430    except Exception as e:
                        431        print(f"VLSM错误: {e}")
                        432    
                        433    # 子网合并示例
                        434    print("\n--- 子网合并示例 ---")
                        435    try:
                        436        merge_result = calculator.merge_subnets([
                        437            '192.168.1.0/26',
                        438            '192.168.1.64/26',
                        439            '192.168.1.128/26',
                        440            '192.168.1.192/26'
                        441        ])
                        442        print("合并结果:")
                        443        for merged in merge_result['merged_subnets']:
                        444            print(f"  {merged['network']} (包含: {', '.join(merged['original_subnets'])})")
                        445        print(f"汇总: {merge_result['summary']}")
                        446    except Exception as e:
                        447        print(f"合并错误: {e}")
                        448    
                        449    # 超网计算示例
                        450    print("\n--- 超网计算示例 ---")
                        451    try:
                        452        supernet_result = calculator.calculate_supernet('192.168.1.10', '192.168.1.50')
                        453        print(f"超网结果: {supernet_result['network_address']}/{supernet_result['cidr']}")
                        454        print(f"详细信息: {supernet_result}")
                        455    except Exception as e:
                        456        print(f"超网错误: {e}")
                        457    
                        458    # 网络规划示例
                        459    print("\n--- 网络规划示例 ---")
                        460    try:
                        461        planning_result = calculator.generate_network_plan('10.0.0.0/8', [
                        462            {'name': '总部', 'size': 200},
                        463            {'name': '分公司A', 'size': 100},
                        464            {'name': '分公司B', 'size': 80},
                        465            {'name': '研发中心', 'size': 150}
                        466        ])
                        467        print("规划结果:")
                        468        for dept in planning_result['departments']:
                        469            print(f"  {dept['name']}: {dept['network_address']}/{dept['cidr']} "
                        470                  f"({dept['allocated_hosts']} 主机)")
                        471        print(f"汇总: {planning_result['summary']}")
                        472    except Exception as e:
                        473        print(f"规划错误: {e}")
                        474
                        475
                        476if __name__ == "__main__":
                        477    main()