联系我们

公司:中纬达科技

联系人:韦先生

电话:0755-32914836

手机/微信:18620850485

E-mail:info@zowinda.com

公司地址:深圳市宝安区新桥街道上星社区新沙路110号星源商务中心313、315

工厂地址:深圳光明区公明塘尾工业区F栋

MIFARE DESFire 开发指南 - 四、实现步骤

2026-06-14
来源:AI生成

四、实现步骤

4.1 环境配置

Windows

  1. 安装 ACR122U 驱动:从 ACS 官网下载并安装
  2. 安装 Python 3.7+
  3. 安装依赖库:pip install pyscard python-desfire pandas PyYAML colorama pyinstaller

Linux (Ubuntu/Debian)

  1. 安装 PC/SC 服务:sudo apt-get install libpcsclite1 pcscd
  2. 配置 ACR122U 权限(udev 规则)
  3. 安装 Python 依赖

macOS

macOS 内置 PC/SC 支持,直接安装依赖即可。

4.2 核心代码实现

4.2.1 读卡器连接模块 (src/reader/card_reader.py)

from smartcard.System import readers
from smartcard.Exceptions import NoCardException

class CardReader:
    # ACR122U 读卡器管理类
    def __init__(self):
        self.reader = None
        self.connection = None

    def find_reader(self):
        available = readers()
        for r in available:
            if "ACR" in str(r) or "ACS" in str(r):
                return r
        return available[0] if available else None

    def connect(self) -> bool:
        self.reader = self.find_reader()
        if not self.reader:
            print("❌ 未找到 ACR122U 读卡器")
            return False
        try:
            self.connection = self.reader.createConnection()
            self.connection.connect()
            print("✅ 读卡器连接成功")
            return True
        except Exception as e:
            print(f"❌ 连接失败: {e}")
            return False

    def disconnect(self):
        if self.connection:
            try:
                self.connection.disconnect()
            except:
                pass

4.2.2 芯片版本检测模块 (src/inspector/chip_inspector.py)

from smartcard.Exceptions import NoCardException

class ChipInspector:
    # DESFire 芯片检测器
    CMD_GET_VERSION = [0x90, 0x60, 0x00, 0x00, 0x00]
    VERSION_MAP = {
        0x00: "DESFire (Legacy)",
        0x01: "DESFire EV1",
        0x02: "DESFire EV2",
        0x03: "DESFire EV3"
    }

    def __init__(self, connection):
        self.connection = connection
        self.target_version = "EV3"

    def wait_for_card(self, timeout=30) -> bool:
        import time
        start = time.time()
        while time.time() - start < timeout:
            try:
                atr = self.connection.getATR()
                if atr:
                    print(f"✅ 检测到卡片,ATR: {atr.hex().upper()}")
                    return True
            except NoCardException:
                time.sleep(0.5)
        print("❌ 超时未检测到卡片")
        return False

    def get_version(self) -> dict:
        try:
            response, sw1, sw2 = self.connection.transmit(self.CMD_GET_VERSION)
            status = (sw1 << 8) | sw2
            if status != 0x9100:
                print(f"❌ 获取版本失败,状态码: 0x{status:04X}")
                return None
            if len(response) < 9:
                return None
            return {
                "hw_major": response[3],
                "hw_minor": response[4],
                "sw_major": response[10] if len(response) > 10 else 0,
                "sw_minor": response[11] if len(response) > 11 else 0
            }
        except Exception as e:
            print(f"❌ 通信错误: {e}")
            return None

    def identify_chip(self, version_data: dict) -> str:
        if not version_data: return "UNKNOWN"
        sw_major = version_data.get("sw_major", 0)
        return self.VERSION_MAP.get(sw_major, f"未知版本 (0x{sw_major:02X})")

    def check_quality(self, chip_type: str) -> str:
        level_map = {"Legacy": 0, "EV1": 1, "EV2": 2, "EV3": 3}
        target_level = level_map.get(self.target_version, 3)
        detected_level = level_map.get(chip_type.split()[-1], -1)
        if detected_level >= target_level: return "PASS"
        elif detected_level == -1: return "UNKNOWN"
        else: return "FAIL"

4.2.3 报告导出模块 (src/report/exporter.py)

import pandas as pd
from datetime import datetime

class ReportExporter:
    # 检测报告导出类
    def __init__(self, output_dir="./reports"):
        self.output_dir = output_dir
        self.results = []

    def add_result(self, card_id: int, chip_type: str, result: str, version_data: dict):
        self.results.append({
            "card_id": card_id,
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "chip_type": chip_type,
            "result": result,
            "hw_version": f"{version_data['hw_major']}.{version_data['hw_minor']}",
            "sw_version": f"{version_data['sw_major']}.{version_data['sw_minor']}"
        })

    def save_csv(self, filename=None):
        if not self.results: return
        if not filename:
            filename = f"inspection_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
        filepath = f"{self.output_dir}/{filename}"
        df = pd.DataFrame(self.results)
        df.to_csv(filepath, index=False, encoding="utf-8")
        print(f"✅ 报告已保存: {filepath}")

4.3 测试与调试

使用 pytest 编写测试用例,覆盖核心功能。集成测试需连接真实 ACR122U 硬件与 DESFire 卡片验证 APDU 通信。

4.4 打包部署

使用 pyinstaller 打包为独立可执行文件: pyinstaller --onefile --windowed --name "MDCI" --add-data "config.yaml:." main.py

搜索