🧮
CIDR表記を計算するツールをPythonで作ってみた
算数苦手な人のために
IP CIDRを計算する方法がさっぱりわからない🤦
計算してくれるサイトはあるようだ。
でも知らなかったので、Pythonで作ってみた。ipaddress --- IPv4/IPv6 操作ライブラリを使用して作成してみました。標準のモジュールとして入っているみたい?
pip installは不要!
example
サンプルコードはこちら。実行するとGUIが表示される。ここに、イチ・クニなんとかって入力します。
main.py
import ipaddress
from typing import List, Dict
import tkinter as tk
from tkinter import ttk, messagebox
class IPCalculator:
def __init__(self):
self.window = tk.Tk()
self.window.title("IPアドレス計算ツール")
self.window.geometry("600x800")
# メインフレーム
main_frame = ttk.Frame(self.window, padding="10")
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
# 入力フィールド
ttk.Label(main_frame, text="IPアドレス:").grid(row=0, column=0, sticky=tk.W, pady=5)
self.ip_entry = ttk.Entry(main_frame, width=20)
self.ip_entry.grid(row=0, column=1, sticky=tk.W, pady=5)
self.ip_entry.insert(0, "192.168.1.0")
ttk.Label(main_frame, text="CIDR:").grid(row=1, column=0, sticky=tk.W, pady=5)
self.cidr_combo = ttk.Combobox(main_frame, values=[str(i) for i in range(24, 33)], width=5)
self.cidr_combo.grid(row=1, column=1, sticky=tk.W, pady=5)
self.cidr_combo.set("24")
ttk.Label(main_frame, text="分割数:").grid(row=2, column=0, sticky=tk.W, pady=5)
self.subnet_combo = ttk.Combobox(main_frame, values=["2", "4", "8", "16"], width=5)
self.subnet_combo.grid(row=2, column=1, sticky=tk.W, pady=5)
self.subnet_combo.set("4")
# 計算ボタン
calc_button = ttk.Button(main_frame, text="計算する", command=self.calculate)
calc_button.grid(row=3, column=0, columnspan=2, pady=10)
# 結果表示エリア
self.result_text = tk.Text(main_frame, height=20, width=60)
self.result_text.grid(row=4, column=0, columnspan=2, pady=5)
def calculate_subnets(self, ip_str: str, current_cidr: int, subnet_count: int) -> List[Dict[str, str]]:
try:
# IPネットワークオブジェクトの作成
network = ipaddress.ip_network(f"{ip_str}/{current_cidr}", strict=False)
# 必要なビット数を計算
required_bits = (subnet_count - 1).bit_length()
new_prefix = current_cidr + required_bits
if new_prefix > 32:
raise ValueError("分割数が大きすぎます")
# サブネットの計算
subnets = list(network.subnets(prefixlen_diff=required_bits))
result = []
for i, subnet in enumerate(subnets[:subnet_count]):
subnet_info = {
"network": str(subnet),
"first_host": str(list(subnet.hosts())[0]) if subnet.num_addresses > 2 else "N/A",
"last_host": str(list(subnet.hosts())[-1]) if subnet.num_addresses > 2 else "N/A",
"broadcast": str(subnet.broadcast_address) if subnet.num_addresses > 1 else "N/A",
"num_addresses": subnet.num_addresses,
"mask": str(subnet.netmask)
}
result.append(subnet_info)
return result
except ValueError as e:
raise ValueError(f"無効な入力: {str(e)}")
def calculate(self):
try:
ip_str = self.ip_entry.get()
current_cidr = int(self.cidr_combo.get())
subnet_count = int(self.subnet_combo.get())
results = self.calculate_subnets(ip_str, current_cidr, subnet_count)
# 結果の表示
self.result_text.delete(1.0, tk.END)
for i, subnet in enumerate(results, 1):
self.result_text.insert(tk.END, f"\nサブネット {i}:\n")
self.result_text.insert(tk.END, f"ネットワーク: {subnet['network']}\n")
self.result_text.insert(tk.END, f"サブネットマスク: {subnet['mask']}\n")
self.result_text.insert(tk.END, f"使用可能アドレス数: {subnet['num_addresses'] - 2}\n")
if subnet['first_host'] != "N/A":
self.result_text.insert(tk.END, f"最初のホスト: {subnet['first_host']}\n")
self.result_text.insert(tk.END, f"最後のホスト: {subnet['last_host']}\n")
self.result_text.insert(tk.END, f"ブロードキャスト: {subnet['broadcast']}\n")
self.result_text.insert(tk.END, "-" * 50 + "\n")
except ValueError as e:
messagebox.showerror("エラー", str(e))
def run(self):
self.window.mainloop()
if __name__ == "__main__":
calculator = IPCalculator()
calculator.run()
こんなGUIが表示されます。
試しにAWS公式のサイトに記載されているIP Adressを4つのサブネットに分けてもらった。
クラス C
クラス C の IPv4 アドレスには 24 のネットワークプレフィックスビットがあります。例えば、192.168.1.100 を考えてみましょう。ここで、192.168.1 はネットワークアドレスで、100 はホストアドレスです。
実行結果
サブネット 1:
ネットワーク: 192.168.1.0/26
サブネットマスク: 255.255.255.192
使用可能アドレス数: 62
最初のホスト: 192.168.1.1
最後のホスト: 192.168.1.62
ブロードキャスト: 192.168.1.63
--------------------------------------------------
サブネット 2:
ネットワーク: 192.168.1.64/26
サブネットマスク: 255.255.255.192
使用可能アドレス数: 62
最初のホスト: 192.168.1.65
最後のホスト: 192.168.1.126
ブロードキャスト: 192.168.1.127
--------------------------------------------------
サブネット 3:
ネットワーク: 192.168.1.128/26
サブネットマスク: 255.255.255.192
使用可能アドレス数: 62
最初のホスト: 192.168.1.129
最後のホスト: 192.168.1.190
ブロードキャスト: 192.168.1.191
--------------------------------------------------
サブネット 4:
ネットワーク: 192.168.1.192/26
サブネットマスク: 255.255.255.192
使用可能アドレス数: 62
最初のホスト: 192.168.1.193
最後のホスト: 192.168.1.254
ブロードキャスト: 192.168.1.255
--------------------------------------------------
最後に
計算が苦手な人はツールを使いましょう。そのために作られたのだと思う💦
Discussion