循環冗餘檢查法(Cyclic Redundancy Check, CRC)
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
# --- I. CRC 核心計算邏輯 (與前面提供的相同) ---
def xor_operation(a, b):
"""執行二進制字串的互斥或 (XOR) 運算。"""
result = []
for bit_a, bit_b in zip(a, b):
result.append('1' if bit_a != bit_b else '0')
return "".join(result)
class CRC_Simulator:
def __init__(self, data_bits, generator_bits):
self.data_bits = data_bits
self.generator_bits = generator_bits
self.k = len(generator_bits)
self.zeros_to_pad = self.k - 1
self.dividend = data_bits + '0' * self.zeros_to_pad
# 初始化模擬狀態
self.current_index = 0
self.current_remainder = list(self.dividend[:self.k])
self.max_steps = len(self.dividend) - self.k + 1
def get_initial_info(self):
"""返回初始設定資訊"""
info = f"✅ 生成多項式 G(x) = {self.generator_bits} (位元數 k = {self.k})\n"
info += f"✅ 原始資料 (Data): {self.data_bits}\n"
info += f"✅ 補 {self.zeros_to_pad} 個 0,被除數 (Dividend): {self.dividend}\n"
info += "----------------------------------------\n"
return info
def perform_next_step(self):
"""執行一步 CRC 除法 (XOR 運算)"""
if self.current_index >= self.max_steps:
return "DONE", f"🌟 最終 CRC 碼 (餘數 Remainder): {''.join(self.current_remainder)}\n🌟 傳送資料 (Data + CRC): {self.data_bits + ''.join(self.current_remainder)}"
i = self.current_index
current_block_str = "".join(self.current_remainder)
log_entry = f"步驟 {i+1}:\n"
log_entry += f" 當前區塊: {current_block_str}\n"
if self.current_remainder[0] == '1':
# 首位為 '1',與生成多項式進行 XOR
division_bits = self.generator_bits
xor_result = xor_operation(current_block_str, division_bits)
log_entry += f" 除數 (G(x)): {division_bits}\n"
else:
# 首位為 '0',與 00...0 進行 XOR
division_bits = '0' * self.k
xor_result = xor_operation(current_block_str, division_bits)
log_entry += f" 除數 (0...0): {division_bits}\n"
log_entry += f" 餘數 XOR: {xor_result}\n"
# 準備下一輪的餘數:取 XOR 結果的第二位到最後一位
next_remainder_partial = list(xor_result[1:])
# 從被除數中引入下一個位元 (如果還有)
if i + self.k < len(self.dividend):
next_remainder_partial.append(self.dividend[i + self.k])
self.current_remainder = next_remainder_partial
log_entry += f" 下一區塊: {''.join(self.current_remainder)}\n"
log_entry += "----------------------------------------\n"
self.current_index += 1
return "STEP", log_entry
# --- II. Tkinter 介面邏輯 ---
class CRC_App:
def __init__(self, master):
self.master = master
master.title("CRC 循環冗餘校驗 - 逐步模擬")
# 初始化模擬器
self.simulator = None
self.is_running = False
# --- 設定主框架 ---
main_frame = ttk.Frame(master, padding="10")
main_frame.pack(fill='both', expand=True)
# --- 輸入區 ---
input_frame = ttk.LabelFrame(main_frame, text="輸入參數", padding="10")
input_frame.pack(fill='x', pady=5)
# 資料輸入
ttk.Label(input_frame, text="資料 (Data) 二進制:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.data_entry = ttk.Entry(input_frame, width=30)
self.data_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
self.data_entry.insert(0, "10101010") # 範例資料
# 多項式輸入
ttk.Label(input_frame, text="多項式 (G(x)) 二進制:").grid(row=1, column=0, padx=5, pady=5, sticky='w')
self.gen_entry = ttk.Entry(input_frame, width=30)
self.gen_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w')
self.gen_entry.insert(0, "10111") # 範例多項式 (X^4+X^2+X+1)
# --- 控制按鈕區 ---
button_frame = ttk.Frame(main_frame)
button_frame.pack(fill='x', pady=5)
self.start_button = ttk.Button(button_frame, text="開始模擬", command=self.start_simulation)
self.start_button.pack(side='left', padx=5, expand=True)
self.next_step_button = ttk.Button(button_frame, text="執行下一步驟 (Clock)", command=self.perform_step, state=tk.DISABLED)
self.next_step_button.pack(side='left', padx=5, expand=True)
self.reset_button = ttk.Button(button_frame, text="重置", command=self.reset_simulation, state=tk.DISABLED)
self.reset_button.pack(side='left', padx=5, expand=True)
# --- 輸出區 (ScrolledText 用於顯示逐步結果) ---
output_frame = ttk.LabelFrame(main_frame, text="CRC 計算過程輸出", padding="10")
output_frame.pack(fill='both', expand=True, pady=5)
self.output_text = scrolledtext.ScrolledText(output_frame, wrap=tk.WORD, width=60, height=20, font=('Consolas', 10))
self.output_text.pack(fill='both', expand=True)
self.output_text.insert(tk.END, "請輸入資料和多項式,然後點擊「開始模擬」按鈕。")
def validate_binary(self, binary_str):
"""驗證輸入是否為非空的二進制字串"""
if not binary_str:
return False
return all(c in '01' for c in binary_str)
def start_simulation(self):
"""初始化並開始 CRC 模擬"""
data = self.data_entry.get().strip()
gen = self.gen_entry.get().strip()
# 輸入驗證
if not self.validate_binary(data) or not self.validate_binary(gen):
messagebox.showerror("輸入錯誤", "資料和生成多項式必須是非空且僅包含 0 和 1 的二進制數字。")
return
if len(data) < len(gen):
messagebox.showwarning("警告", "通常生成多項式 (G(x)) 的位元數應小於或等於資料位元數。")
try:
# 初始化模擬器
self.simulator = CRC_Simulator(data, gen)
self.is_running = True
# 更新按鈕狀態
self.start_button.config(state=tk.DISABLED)
self.next_step_button.config(state=tk.NORMAL)
self.reset_button.config(state=tk.NORMAL)
# 清空並顯示初始資訊
self.output_text.delete(1.0, tk.END)
self.output_text.insert(tk.END, self.simulator.get_initial_info())
except Exception as e:
messagebox.showerror("錯誤", f"初始化錯誤: {e}")
self.reset_simulation()
def perform_step(self):
"""執行一步 CRC 計算並更新輸出"""
if not self.is_running or not self.simulator:
return
status, log = self.simulator.perform_next_step()
self.output_text.insert(tk.END, log)
self.output_text.see(tk.END) # 滾動到最新輸出
if status == "DONE":
self.next_step_button.config(state=tk.DISABLED)
self.is_running = False
messagebox.showinfo("模擬結束", "CRC 計算完成!請查看輸出結果。")
def reset_simulation(self):
"""重置所有狀態"""
self.simulator = None
self.is_running = False
# 更新按鈕狀態
self.start_button.config(state=tk.NORMAL)
self.next_step_button.config(state=tk.DISABLED)
self.reset_button.config(state=tk.DISABLED)
# 清空輸出
self.output_text.delete(1.0, tk.END)
self.output_text.insert(tk.END, "模擬已重置。請輸入新的資料和多項式,然後點擊「開始模擬」。")
if __name__ == "__main__":
root = tk.Tk()
app = CRC_App(root)
root.mainloop()




沒有留言:
張貼留言