【子网掩码计算器:Python + Tkinter 实现】

子网掩码计算器:Python + Tkinter 实现

  • 引言
    • 代码功能概述
    • 代码实现思路
      • 1. 界面设计
      • 2. 功能实现
      • 3. 事件处理
  • 子网掩码计算器实现步骤
    • 1. 导入必要的库
    • 2. 定义主窗口类 SubnetCalculatorApp
    • 3. 创建菜单栏
    • 4. 创建界面组件
    • 5. 判断 IP 地址类别
    • 6. 计算子网信息
    • 7. 其他功能函数
    • 代码运行效果
    • 总结

引言

在网络工程和网络管理领域,子网掩码的计算是一项基础且重要的工作。通过子网掩码,我们可以将一个大的网络划分为多个小的子网,从而提高网络的安全性和可管理性。今天,我们将介绍一个使用 Python 和 Tkinter 库实现的子网掩码计算器,它可以帮助我们快速计算子网信息,并且支持历史记录的查看和导出。

代码功能概述

这个子网掩码计算器具有以下主要功能:

  • 输入验证:验证用户输入的 IP 地址和子网掩码 / CIDR 是否有效。
  • 子网计算:根据输入的 IP 地址和子网掩码 / CIDR 计算网络地址、广播地址、可用 IP 数、可用 IP 范围等信息。
  • IP 地址分类:判断输入的 IP 地址属于 A、B、C、D、E 类中的哪一类,以及是公网地址还是私有地址。
  • 结果显示:将计算结果显示在界面上,并支持复制结果到剪贴板。
  • 历史记录:保存最近 5 条计算结果,并支持查看和导出历史记录。

代码实现思路

1. 界面设计

  • 使用 Tkinter 库创建一个图形用户界面(GUI),包括输入框、按钮、标签和表格等组件。
  • 通过布局管理器(如 pack 和 grid)将这些组件排列在合适的位置。

2. 功能实现

  • 输入验证:编写函数 validate_ipvalidate_mask 来验证 IP 地址和子网掩码的格式是否正确。
  • 子网计算
    • 编写函数 ip_to_intint_to_ip 来实现 IP 地址和 32 位整数之间的转换。
    • 根据子网掩码计算网络地址、广播地址等信息。
  • IP 地址分类:编写函数 get_ip_class 来判断 IP 地址的类别。
  • 历史记录管理
    • 使用列表 self.history 来存储最近 5 条计算结果。
    • 提供查看和导出历史记录的功能。

3. 事件处理

  • 为每个按钮绑定相应的事件处理函数,例如:
    • 点击 “计算” 按钮时调用 calculate 函数进行子网计算。
    • 点击 “保存当前结果” 按钮时调用 save_current_result 函数保存结果。

子网掩码计算器实现步骤

1. 导入必要的库

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import csv
from datetime import datetime

这里导入了 Tkinter 库用于创建 GUI,csv 库用于处理 CSV 文件,datetime 库用于记录时间。

2. 定义主窗口类 SubnetCalculatorApp

class SubnetCalculatorApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("子网掩码计算器")
        self.geometry("650x470")  # 调整窗口大小
        self.resizable(False, False)
        self.history = []  # 存储最近5条历史记录
        self.create_widgets()
        self.create_menu()

init 方法中,我们初始化了主窗口的标题、大小、是否可调整大小属性,并创建了一个空的历史记录列表。然后,我们调用了 create_widgets 和 create_menu 方法来创建界面组件和菜单栏。

3. 创建菜单栏

def create_menu(self):
    """创建菜单栏"""
    menubar = tk.Menu(self)

    # 历史记录菜单
    history_menu = tk.Menu(menubar, tearoff=0)
    history_menu.add_command(label="查看历史记录", command=self.show_history)
    history_menu.add_command(label="导出历史记录...", command=self.export_history)
    menubar.add_cascade(label="历史记录", menu=history_menu)

    self.config(menu=menubar)

在 create_menu 方法中,我们创建了一个菜单栏,并为其添加了一个名为“历史记录”的子菜单。该子菜单包含两个选项:“查看历史记录”和“导出历史记录…”。当用户点击这些选项时,将分别调用 show_history 和 export_history 方法。最后,我们将菜单栏设置到主窗口中。

4. 创建界面组件

def create_widgets(self):
    """创建界面组件"""
    # 输入区域
    input_frame = ttk.Frame(self)
    input_frame.pack(padx=10, pady=10, fill=tk.X)

    ttk.Label(input_frame, text="IP地址:").grid(row=0, column=0, sticky=tk.W)
    self.ip_entry = ttk.Entry(input_frame, width=20)
    self.ip_entry.grid(row=0, column=1, padx=5)

    ttk.Label(input_frame, text="子网掩码/CIDR:").grid(row=1, column=0, sticky=tk.W)
    self.mask_entry = ttk.Entry(input_frame, width=20)
    self.mask_entry.grid(row=1, column=1, padx=5)

    ttk.Button(input_frame, text="计算", command=self.calculate).grid(row=2, column=0, columnspan=2, pady=10)

    # 结果区域
    result_frame = ttk.LabelFrame(self, text="计算结果")
    result_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)

    result_labels = [
        ("网络地址:", "network"),
        ("广播地址:", "broadcast"),
        ("可用IP数:", "hosts"),
        ("可用IP范围:", "range"),
        ("CIDR表示:", "cidr"),
        ("子网掩码:", "mask"),
        ("IP版本:", "version"),
        ("网络类别:", "class")  # 新增网络类别
    ]

    for i, (label, _) in enumerate(result_labels):
        ttk.Label(result_frame, text=label).grid(row=i, column=0, sticky=tk.W, padx=5, pady=2)
        setattr(self, f"result_{label.split(':')[0]}", ttk.Label(result_frame, text=""))
        getattr(self, f"result_{label.split(':')[0]}").grid(row=i, column=1, sticky=tk.W, padx=5, pady=2)

    # 按钮区域
    button_frame = ttk.Frame(self)
    button_frame.pack(pady=5)

    ttk.Button(button_frame, text="保存当前结果", command=self.save_current_result).pack(side=tk.LEFT, padx=5)
    ttk.Button(button_frame, text="复制结果", command=self.copy_results).pack(side=tk.LEFT, padx=5)
    ttk.Button(button_frame, text="清除输入", command=self.clear_inputs).pack(side=tk.LEFT, padx=5)

这段代码创建了输入区域、结果区域和按钮区域,并为每个组件设置了相应的布局和事件处理函数。

5. 判断 IP 地址类别

def get_ip_class(self, ip_str):
    """判断IP地址类别"""
    first_octet = int(ip_str.split('.')[0])
    if 1 <= first_octet <= 126:
        return "A类(公网地址)" if first_octet != 10 else "A类(私有地址)"
    elif 128 <= first_octet <= 191:
        if first_octet == 172 and 16 <= int(ip_str.split('.')[1]) <= 31:
            return "B类(私有地址)"
        return "B类(公网地址)"
    elif 192 <= first_octet <= 223:
        if first_octet == 192 and int(ip_str.split('.')[1]) == 168:
            return "C类(私有地址)"
        return "C类(公网地址)"
    elif 224 <= first_octet <= 239:
        return "D类(组播地址)"
    elif 240 <= first_octet <= 255:
        return "E类(保留地址)"
    elif first_octet == 127:
        return "环回地址"
    return "未知类别"

这个函数根据 IP 地址的第一个八位组判断其类别,并区分公网地址和私有地址。

6. 计算子网信息

def calculate(self):
    """计算子网信息"""
    try:
        ip_str = self.ip_entry.get().strip()
        mask_str = self.mask_entry.get().strip().lstrip('/')

        if not self.validate_ip(ip_str):
            raise ValueError("无效的IP地址格式")

        # 获取网络类别
        ip_class = self.get_ip_class(ip_str)

        ip_int = self.ip_to_int(ip_str)
        mask_int, cidr = self.parse_mask(mask_str, ip_int)
        subnet_mask = self.int_to_ip(mask_int)

        network_int = ip_int & mask_int
        broadcast_int = network_int | (~mask_int & 0xFFFFFFFF)
        hosts_count = max(broadcast_int - network_int - 1, 0)

        # 更新结果
        self.result_网络地址.config(text=self.int_to_ip(network_int))
        self.result_广播地址.config(text=self.int_to_ip(broadcast_int))
        self.result_可用IP数.config(text=f"{hosts_count} 个")
        self.result_CIDR表示.config(text=f"/{cidr}")
        self.result_子网掩码.config(text=subnet_mask)
        self.result_IP版本.config(text="IPv4")
        self.result_网络类别.config(text=ip_class)  # 显示网络类别

        if hosts_count > 0:
            first_ip = self.int_to_ip(network_int + 1)
            last_ip = self.int_to_ip(broadcast_int - 1)
            self.result_可用IP范围.config(text=f"{first_ip} - {last_ip}")
        else:
            self.result_可用IP范围.config(text="无可用IP")

    except Exception as e:
        messagebox.showerror("错误", str(e))

在 calculate 函数中,首先验证输入的 IP 地址和子网掩码 / CIDR 是否有效,然后进行子网计算,并将结果显示在界面上。

7. 其他功能函数

代码中还包含了清空输入框、复制结果、保存当前结果、查看历史记录和导出历史记录等功能函数,这些函数的实现逻辑都比较简单,这里就不再详细介绍了。

代码运行效果

运行代码后,会弹出一个子网掩码计算器的窗口,界面如下:
在这里插入图片描述

用户可以在输入框中输入 IP 地址和子网掩码 / CIDR,点击 “计算” 按钮即可得到计算结果。点击 “保存当前结果” 按钮可以将结果保存到 CSV 文件中,点击 “复制结果” 按钮可以将结果复制到剪贴板。通过菜单栏中的 “历史记录” 菜单可以查看和导出最近 5 条计算结果。

总结

通过这个子网掩码计算器的实现,我们学习了如何使用 Python 和 Tkinter 库创建一个简单的 GUI 应用程序。同时,我们也掌握了子网计算的基本原理和 IP 地址分类的方法。希望这篇博客对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980618.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【第十节】C++设计模式(结构型模式)-Flyweight( 享元)模式

目录 一、问题背景 二、模式选择 三、代码实现 四、总结讨论 一、问题背景 享元模式&#xff08;Flyweight Pattern&#xff09;在对象存储优化中的应用 在面向对象系统的设计与实现中&#xff0c;创建对象是最常见的操作之一。然而&#xff0c;如果一个应用程序使用了过多…

macOS - 使用 tmux

文章目录 安装 tmux使用更多快捷键说明 安装 tmux brew install tmux使用 在终端输入 tmux 进入 tmux 界面&#xff0c;然后 输入 Control Option B 进入交互模式 输入 % 左右分栏&#xff0c;" 上下分割 上一个窗格&#xff1a;{&#xff0c;下一个&#xff1a;} PS…

【洛谷贪心算法题】P1094纪念品分组

该题运用贪心算法&#xff0c;核心思想是在每次分组时&#xff0c;尽可能让价格较小和较大的纪念品组合在一起&#xff0c;以达到最少分组的目的。 【算法思路】 输入处理&#xff1a;首先读取纪念品的数量n和价格上限w&#xff0c;然后依次读取每件纪念品的价格&#xff0c;…

16. LangChain实战项目2——易速鲜花内部问答系统

需求简介 易束鲜花企业内部知识库如下&#xff1a; 本实战项目设计一个内部问答系统&#xff0c;基于这些内部知识&#xff0c;回答内部员工的提问。 在前面课程的基础上&#xff0c;需要安装的依赖包如下&#xff1a; pip install docx2txt pip install qdrant-client pip i…

Minio搭建并在SpringBoot中使用完成用户头像的上传

Minio使用搭建并上传用户头像到服务器操作,学习笔记 Minio介绍 minio官网 MinIO是一个开源的分布式对象存储服务器&#xff0c;支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发&#xff0c;拥有轻量级、高性能、易部署等特点&#xff0c;并且可以自由…

Spring AI:让AI应用开发更简单

文章目录 引言什么是Spring AI&#xff1f;核心特性 Spring AI的核心组件ChatClient&#xff1a;聊天模型示例代码图示 ImageClient&#xff1a;图像生成示例代码图示 Prompt Templates&#xff1a;提示词模板示例代码 Spring AI的优势示例项目&#xff1a;智能机票助手代码实现…

【C】链式二叉树算法题1 -- 单值二叉树

leetcode链接https://leetcode.cn/problems/univalued-binary-tree/description/ 1 题目描述 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1…

什么是最终一致性,它对后端系统的意义是什么

最终一致性(Eventual Consistency)是分布式系统中的一种一致性模型。与传统的强一致性模型不同,最终一致性并不要求系统在任何时刻都保持一致,而是保证在足够的时间后,所有节点的数据最终会达到一致的状态。换句话说,系统允许短时间内出现数据的不一致性,但最终会通过某…

掌握大模型高效任务流搭建(一):构建LangChain任务流

前言&#xff1a; 在LangChain框架中&#xff0c;“链”占据着核心地位。它允许我们将众多任务模块串联起来&#xff0c;构建出富有弹性的任务流。借助这种链式结构&#xff0c;我们能够处理复杂的逻辑&#xff0c;并实现任务的自动化。在实际场景里&#xff0c;链式操作极大地…

目标检测——数据处理

1. Mosaic 数据增强 Mosaic 数据增强步骤: (1). 选择四个图像&#xff1a; 从数据集中随机选择四张图像。这四张图像是用来组合成一个新图像的基础。 (2) 确定拼接位置&#xff1a; 设计一个新的画布(输入size的2倍)&#xff0c;在指定范围内找出一个随机点&#xff08;如…

塑造网络安全的关键事件

注&#xff1a;本文为 “网络安全” 相关文章合辑。 机翻&#xff0c;未校。 Timeline of Cyber Security: Key Events that Shaped the Field 网络安全时间表&#xff1a;塑造该领域的关键事件 October 29, 2023 Cyberattacks are an everyday threat, always changing. T…

题解 | 牛客周赛82 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 判断字符串第一个字符和第三个字符是否相等 import java.io.*; import java.math.*; import java.u…

Redis 高可用性:如何让你的缓存一直在线,稳定运行?

&#x1f3af; 引言&#xff1a;Redis的高可用性为啥这么重要&#xff1f; 在现代高可用系统中&#xff0c;Redis 是一款不可或缺的分布式缓存与数据库系统。无论是提升访问速度&#xff0c;还是实现数据的高效持久化&#xff0c;Redis 都能轻松搞定。可是&#xff0c;当你把 …

uniapp-原生android插件开发摘要

uni-app在App侧的原生扩展插件&#xff0c;支持使用java、object-c等原生语言编写&#xff0c;从HBuilderX 3.6起&#xff0c;新增支持了使用uts来开发原生插件。 基础项目 UniPlugin-Hello-AS工程请在App离线SDK中查找 基础项目(App离线SDK)已经配置好了自定义插件所需要的…

【定昌Linux系统】部署了java程序,设置开启启动

将代码上传到相应的目录&#xff0c;并且配置了一个.sh的启动脚本文件 文件内容&#xff1a; #!/bin/bash# 指定JAR文件的路径&#xff08;如果JAR文件在当前目录&#xff0c;可以直接使用文件名&#xff09; JAR_FILE"/usr/local/java/xs_luruan_client/lib/xs_luruan_…

SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…

Unity小功能实现:鼠标点击移动物体

1、功能描述 当玩家点击鼠标时&#xff0c;场景中的物体会移动到鼠标点击的位置。这个功能可以用于控制角色移动、放置物体等场景。 2、实现步骤 创建Unity项目&#xff1a;首先&#xff0c;打开Unity并创建一个新的3D项目。 添加3D物体&#xff1a;在场景中创建一个3D物体&am…

游戏引擎学习第127天

仓库:https://gitee.com/mrxiao_com/2d_game_3 为本周设定阶段 我们目前的渲染器已经实现了令人惊讶的优化&#xff0c;经过过去两周的优化工作后&#xff0c;渲染器在1920x1080分辨率下稳定地运行在60帧每秒。这个结果是意料之外的&#xff0c;因为我们没有预计会达到这样的…

Opencv 图像基本操作

1.1 数据读取-图像 opencv读取的格式是BGR而不是RGB import cv2 import matplotlib.pyplot as plt import numpy as np %matplotlib inline # 在Notebook的输出单元格内嵌入绘制的图形&#xff0c;而不在新窗口中显示img cv2.imread(cat.jpg) # cv2.IMREAD_COLOR&#xff1a…

【微知】ssh如何指定免密的2种简单方式?(vim ~/.ssh/authorized_keys、ssh-copy-id)

背景 ssh通过存储公钥到远端服务器&#xff0c;可以完成本端访问远端服务器的时候免密。免密原理是本端使用私钥&#xff0c;远端公钥&#xff0c;远端可以进行鉴权 方法1&#xff1a; vim ~/.ssh/authorized_keys 将本地电脑的pub的key直接copy到远端 ~/.ssh/authorized_ke…