RFID 綜合運營中央控制台 (Integrated Console)
這套系統已經涵蓋了從物理層 (Anti-collision)、傳輸層 (Cipher)、網路層 (Nonce/Auth) 到應用層 (ERP/Payment/Kill) 的所有精華。
這是一個巨大的工程,我們將把之前開發的所有核心模組:抗碰撞掃描 (Anti-collision)、串流加密 (Stream Cipher)、動態挑戰 (Nonce Challenge)、後端數據庫 (Backend DB) 以及 標籤銷毀 (Kill Command) 全部整合進一個專業的「RFID 運營中央控制台」。
這個控制台分為三個邏輯層:
物理/傳輸層:負責掃描與處理訊號碰撞。
安全層:負責密鑰管理與隨機數驗證。
應用/隱私層:負責帳務處理與結帳後的標籤自毀。
import tkinter as tk
from tkinter import ttk, messagebox
import random
import time
from threading import Thread, Event
# ================= 核心安全引擎 =================
class RFIDSecurityEngine:
@staticmethod
def stream_cipher(data_hex, key_hex, nonce_hex=None):
try:
# 若有 Nonce 則先進行混合 (防重播)
val = int(data_hex.replace(" ", ""), 16)
if nonce_hex:
val ^= int(nonce_hex.replace(" ", ""), 16)
clean_hex = hex(val)[2:].upper()
bin_data = bin(int(clean_hex, 16))[2:].zfill(len(clean_hex)*4)
bin_key = bin(int(key_hex, 16))[2:].zfill(16)
# LSFR 邏輯
state = [int(b) for b in bin_key[:8]]
keystream = []
for _ in range(len(bin_data)):
out = state[-1]
feedback = state[0] ^ state[2]
state = [feedback] + state[:-1]
keystream.append(out)
res_bits = [int(bin_data[i]) ^ keystream[i] for i in range(len(bin_data))]
hex_out = hex(int("".join(map(str, res_bits)), 2))[2:].upper().zfill(len(clean_hex))
return " ".join(hex_out[i:i+2] for i in range(0, len(hex_out), 2))
except: return "ERROR"
# ================= 中央控制台程式 =================
class RFIDCentralConsole:
def __init__(self, root):
self.root = root
self.root.title("RFID 旗艦級中央運營控制台")
self.root.geometry("900x750")
# 系統狀態
self.db = {
"USERS": {
"53 71 37 A4 F6": {"name": "張小明", "balance": 1000, "key": "AC55"},
"12 AB 34 CD EF": {"name": "李華", "balance": 50, "key": "B88B"}
},
"PRODUCTS": {
"P01": {"name": "無人機", "price": 450, "kill_pwd": "BADC"},
"P02": {"name": "傳感器", "price": 120, "kill_pwd": "DEAD"},
"P03": {"name": "加密晶片", "price": 300, "kill_pwd": "FACE"}
}
}
self.inventory_cart = []
self.killed_tags = set()
self.is_running = False
self.setup_ui()
def setup_ui(self):
# --- 頂部:數據庫監控 ---
db_frame = tk.LabelFrame(self.root, text="後端資產管理系統 (Backend ERP)", padx=10, pady=5)
db_frame.pack(fill="x", padx=10, pady=5)
self.db_tree = ttk.Treeview(db_frame, columns=("UID", "Name", "Balance", "Key"), show="headings", height=3)
for col in ("UID", "Name", "Balance", "Key"): self.db_tree.heading(col, text=col)
self.db_tree.pack(fill="x")
self.update_db_view()
# --- 中間:工作區域 (分為左掃描、右結帳) ---
work_frame = tk.Frame(self.root)
work_frame.pack(fill="both", expand=True, padx=10)
# 左側:倉庫/賣場掃描 (Anti-collision)
scan_frame = tk.LabelFrame(work_frame, text="空中介面掃描 (Air Interface)", padx=10)
scan_frame.pack(side=tk.LEFT, fill="both", expand=True)
self.btn_scan = tk.Button(scan_frame, text="🔍 批次抗碰撞掃描", command=self.run_anti_collision, bg="#3498db", fg="white")
self.btn_scan.pack(fill="x", pady=5)
self.scan_list = tk.Listbox(scan_frame, height=8, font=("Courier", 9))
self.scan_list.pack(fill="both", expand=True)
# 右側:結帳與安全驗證
pay_frame = tk.LabelFrame(work_frame, text="安全支付終端 (Payment Terminal)", padx=10)
pay_frame.pack(side=tk.RIGHT, fill="both", expand=True)
self.lbl_total = tk.Label(pay_frame, text="應付金額: $0", font=("Arial", 12, "bold"), fg="#e67e22")
self.lbl_total.pack(pady=10)
tk.Label(pay_frame, text="選擇感應卡片:").pack()
for uid, info in self.db["USERS"].items():
tk.Button(pay_frame, text=f"感應 {info['name']}", command=lambda u=uid: self.process_payment(u)).pack(fill="x", pady=2)
# --- 底部:系統日誌與傳輸監控 ---
log_frame = tk.LabelFrame(self.root, text="系統原始日誌 (Raw Logs)", padx=10)
log_frame.pack(fill="x", padx=10, pady=10)
self.log_text = tk.Text(log_frame, height=10, bg="#2c3e50", fg="#ecf0f1", font=("Consolas", 9))
self.log_text.pack(fill="x", pady=5)
# ---------------- 邏輯處理 ----------------
def update_db_view(self):
for i in self.db_tree.get_children(): self.db_tree.delete(i)
for uid, info in self.db["USERS"].items():
self.db_tree.insert("", tk.END, values=(uid, info["name"], f"${info['balance']}", info["key"]))
def run_anti_collision(self):
if self.is_running: return
self.is_running = True
self.inventory_cart = []
self.scan_list.delete(0, tk.END)
Thread(target=self._scan_thread, daemon=True).start()
def _scan_thread(self):
self.log(">>> [運營] 啟動批次掃描程序...")
products = list(self.db["PRODUCTS"].keys())
# 模擬 8 個時槽 (Slots)
for slot in range(8):
time.sleep(0.4)
# 隨機選中商品,且排除已銷毀的
available = [p for p in products if p not in self.killed_tags and random.random() < 0.3]
if len(available) == 1:
pid = available[0]
item = self.db["PRODUCTS"][pid]
self.inventory_cart.append(item)
self.root.after(0, lambda p=pid, n=item['name']: self.scan_list.insert(tk.END, f"Slot {slot}: {n} (${item['price']})"))
self.log(f"Slot {slot}: 辨識成功 -> {item['name']}")
elif len(available) > 1:
self.log(f"Slot {slot}: 偵測到碰撞!訊號干擾中...")
total = sum(i['price'] for i in self.inventory_cart)
self.root.after(0, lambda: self.lbl_total.config(text=f"應付金額: ${total}"))
self.is_running = False
def process_payment(self, user_uid):
if not self.inventory_cart or self.is_running: return
self.is_running = True
Thread(target=self._pay_thread, args=(user_uid,), daemon=True).start()
def _pay_thread(self, uid):
total = sum(i['price'] for i in self.inventory_cart)
user = self.db["USERS"][uid]
self.log(f"\n[安全] 向卡片 {uid} 發起挑戰...")
nonce = hex(random.getrandbits(16))[2:].upper().zfill(4)
time.sleep(1)
# 模擬加密響應
cipher_resp = RFIDSecurityEngine.stream_cipher(uid, user["key"], nonce)
self.log(f"[傳輸] 接收密文: {cipher_resp}")
# 驗證
decrypted = RFIDSecurityEngine.stream_cipher(cipher_resp, user["key"], nonce)
if decrypted.replace(" ","") == uid.replace(" ",""):
if user["balance"] >= total:
user["balance"] -= total
self.log(f"[成功] 扣款 ${total}。正在發送 Kill Command 銷毀商品標籤...")
# 執行 Kill Command (隱私保護)
for item in self.inventory_cart:
# 查找對應的 PID
for pid, p_info in self.db["PRODUCTS"].items():
if p_info["name"] == item["name"]:
self.killed_tags.add(pid)
self.log(f"-> Tag {pid} 已銷毀 (Kill PWD used)")
self.inventory_cart = []
self.root.after(0, self.update_db_view)
self.root.after(0, lambda: self.lbl_total.config(text="應付金額: $0"))
messagebox.showinfo("系統通知", "支付成功!商品標籤已停用以保護隱私。")
else:
self.log("[錯誤] 餘額不足。")
else:
self.log("[警告] 密鑰錯誤,偵測到潛在非法卡片!")
self.is_running = False
def log(self, msg):
self.root.after(0, lambda: self.log_text.insert(tk.END, msg + "\n"))
self.root.after(0, lambda: self.log_text.see(tk.END))
if __name__ == "__main__":
root = tk.Tk()
app = RFIDCentralConsole(root)
root.mainloop()


沒有留言:
張貼留言