縱向冗餘檢查法(Longitudinal Redundancy Check, LRC)是對傳送資料的每個位元組的前後位置做連續的互斥或(XOR)運算後,以產生一個新的LRC位元組,此新的LRC位元組與資料同時傳送出去。在接收時,將接收資料的前後位置及LRC位元組做互斥或(XOR)運算後,所得的新的LRC位元組應為零,則代表資料是正確的,否則是錯誤的。
LRC 碼產生(資料發送端)
1.輸入資料: 在輸入框中輸入您要傳輸的 16 進制資料,每個位元組用空格隔開 。
範例輸入: 25 51 3B 52
2.開始模擬: 點擊 「LRC 碼產生 (開始模擬)」 按鈕。
3.逐步運算: 重複點擊 「執行下一步驟 (XOR)」 按鈕 。
每一步都會將前次 LRC 累加器的二進制值與下一個資料位元組的二進制值進行 XOR 運算 。
4. LRC 碼: 運算完成後,輸出區域會顯示最終 LRC 碼的 16 進制和二進制表示 。
LRC 檢查(資料接收端)
1.輸入資料: 在輸入框中輸入接收到的所有資料(包括原始資料和 LRC 碼本身),用空格隔開 。
範例輸入 (資料正確): 25 51 3B 52 1D
範例輸入 (資料錯誤): 23 51 3B 52 1D
2. 開始檢查: 點擊 「LRC 檢查 (開始驗證)」 按鈕。
3. 逐步運算: 重複點擊 「執行下一步驟 (XOR)」 按鈕 。
程式將連續對所有接收到的位元組進行 XOR 運算 。
4.檢查結果:
如果最終結果(新的 LRC 位元組)為 00,則表示資料正確 。
如果最終結果 非零 (例如 06),則表示接收到的資料有錯誤發生 。
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
# --- I. LRC 核心計算邏輯 ---
def hex_to_binary(hex_str):
"""將 16 進制字串轉換為 8 位元的二進制字串。"""
return bin(int(hex_str, 16))[2:].zfill(8)
def binary_to_hex(binary_str):
"""將 8 位元的二進制字串轉換為 16 進制字串。"""
return hex(int(binary_str, 2))[2:].zfill(2).upper()
def xor_binary_8bit(bin1, bin2):
"""執行兩個 8 位元二進制字串的互斥或 (XOR) 運算。"""
result = []
for b1, b2 in zip(bin1, bin2):
result.append('1' if b1 != b2 else '0')
return "".join(result)
class LRC_Simulator:
def __init__(self, hex_data_list, mode="GENERATE"):
# hex_data_list 是一個包含多個 16 進制字串的列表 (例如 ['25', '51', '3B', '52'])
self.hex_data_list = hex_data_list
self.mode = mode # GENERATE or CHECK
# 將所有 16 進制數據轉換為二進制
self.bin_data_list = [hex_to_binary(h) for h in hex_data_list]
self.current_index = 0
self.max_steps = len(self.bin_data_list)
# 初始 LRC 累加器為第一個數據位元組
if self.max_steps > 0:
self.accumulator = self.bin_data_list[0]
self.current_hex_operand = self.hex_data_list[0]
else:
self.accumulator = '00000000'
self.current_hex_operand = '00'
def perform_next_step(self):
"""執行一步 LRC (XOR 運算)"""
if self.current_index >= self.max_steps:
# 計算結束
final_bin = self.accumulator
final_hex = binary_to_hex(final_bin)
if self.mode == "GENERATE":
return "DONE", f"----------------------------------------\n🌟 LRC 碼產生完成!\n🌟 LRC= {final_hex} ({final_bin})\n----------------------------------------"
else: # CHECK mode
result_msg = "✅ 資料正確 (餘數為 00)" if final_hex == "00" else f"❌ 資料錯誤 (餘數為 {final_hex})"
return "DONE", f"----------------------------------------\n🌟 LRC 檢查完成!\n🌟 最終 LRC= {final_hex} ({final_bin})\n{result_msg}\n----------------------------------------"
# 第一步 (i=0) 只是初始化,不執行 XOR
if self.current_index == 0 and self.max_steps > 0:
log_entry = f"初始化: LRC 累加器設定為第一個資料位元組\n"
log_entry += f" LRC (Hex): {self.current_hex_operand}\n"
log_entry += f" LRC (Bin): {self.accumulator}\n"
self.current_index += 1
return "STEP", log_entry
# 執行 XOR 步驟 (從第二個數據位元組開始)
i = self.current_index
previous_bin = self.accumulator
previous_hex = binary_to_hex(previous_bin)
current_operand_bin = self.bin_data_list[i]
self.current_hex_operand = self.hex_data_list[i]
# 執行 XOR 運算
self.accumulator = xor_binary_8bit(previous_bin, current_operand_bin)
log_entry = f"步驟 {i} (資料位元組 {self.current_hex_operand}H):\n"
log_entry += f" 前次 LRC (Bin): {previous_bin}\n"
log_entry += f" XOR 運算元 (Bin): {current_operand_bin}\n"
log_entry += f" XOR 結果 (Bin): {self.accumulator}\n"
log_entry += f" XOR 結果 (Hex): {binary_to_hex(self.accumulator)}\n"
log_entry += "----------------------------------------\n"
self.current_index += 1
return "STEP", log_entry
# --- II. Tkinter 介面邏輯 ---
class LRC_App:
def __init__(self, master):
self.master = master
master.title("LRC 縱向冗餘檢查 - 逐步模擬")
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="輸入參數 (16 進制)", padding="10")
input_frame.pack(fill='x', pady=5)
ttk.Label(input_frame, text="16 進制資料 (Byte 之間用空格分隔):").grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.data_entry = ttk.Entry(input_frame, width=50)
self.data_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
self.data_entry.insert(0, "25 51 3B 52") # 範例資料
# --- 控制按鈕區 ---
button_frame = ttk.Frame(main_frame)
button_frame.pack(fill='x', pady=5)
self.start_gen_button = ttk.Button(button_frame, text="LRC 碼產生 (開始模擬)", command=lambda: self.start_simulation("GENERATE"))
self.start_gen_button.pack(side='left', padx=5, expand=True)
self.start_check_button = ttk.Button(button_frame, text="LRC 檢查 (開始驗證)", command=lambda: self.start_simulation("CHECK"))
self.start_check_button.pack(side='left', padx=5, expand=True)
self.next_step_button = ttk.Button(button_frame, text="執行下一步驟 (XOR)", 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="LRC 運算過程輸出 (二進制)", 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, "請輸入 16 進制資料 (Byte 間用空格分隔),然後點擊「LRC 碼產生」或「LRC 檢查」開始。")
def validate_hex_input(self, input_str):
"""驗證輸入是否為合法的 16 進制位元組序列 (每 Byte 必須是 2 個字元)。"""
hex_list = input_str.upper().split()
if not hex_list:
return None, "輸入不能為空。"
for h in hex_list:
if len(h) != 2 or not all(c in '0123456789ABCDEF' for c in h):
return None, f"'{h}' 格式錯誤。每個 Byte 必須是 2 個 16 進制字元。"
return hex_list, None
def start_simulation(self, mode):
"""初始化並開始 LRC 模擬"""
input_data = self.data_entry.get().strip()
hex_data_list, error = self.validate_hex_input(input_data)
if error:
messagebox.showerror("輸入錯誤", error)
return
try:
# 初始化模擬器
self.simulator = LRC_Simulator(hex_data_list, mode)
self.is_running = True
# 更新按鈕狀態
self.start_gen_button.config(state=tk.DISABLED)
self.start_check_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)
op_mode = "LRC 碼產生模式" if mode == "GENERATE" else "LRC 檢查模式 (Data + LRC)"
self.output_text.insert(tk.END, f"--- {op_mode} ---\n")
self.output_text.insert(tk.END, f"輸入資料 (Hex): {input_data}\n")
self.output_text.insert(tk.END, f"總共 {len(hex_data_list)} 個位元組需要運算。\n")
self.output_text.insert(tk.END, "----------------------------------------\n")
# 執行第一步 (初始化)
self.perform_step()
except Exception as e:
messagebox.showerror("錯誤", f"初始化錯誤: {e}")
self.reset_simulation()
def perform_step(self):
"""執行一步 LRC 計算並更新輸出"""
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
# 顯示完成訊息
if self.simulator.mode == "GENERATE":
messagebox.showinfo("模擬結束", "LRC 碼產生完成!")
else:
messagebox.showinfo("檢查結束", "LRC 檢查完成!")
def reset_simulation(self):
"""重置所有狀態"""
self.simulator = None
self.is_running = False
# 更新按鈕狀態
self.start_gen_button.config(state=tk.NORMAL)
self.start_check_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, "模擬已重置。請輸入 16 進制資料 (Byte 間用空格分隔),然後點擊「LRC 碼產生」或「LRC 檢查」開始。")
if __name__ == "__main__":
root = tk.Tk()
app = LRC_App(root)
root.mainloop()


沒有留言:
張貼留言