nfcscript
NFC 测试脚本 DSL 执行环境,基于 nfctester 插件化架构。
安装
uv sync
使用
nfcscript - 脚本执行
nfcscript test_card.py
常用参数
# 指定串口
nfcscript test_card.py -p COM21
# 指定读卡器类型
nfcscript test_card.py -r acr122u
# 开启追踪层
nfcscript test_card.py --trace-layer=protocol,debug
# 设置日志级别
nfcscript test_card.py --trace-level=driver
# 组合使用
nfcscript test_card.py -p COM21 -r pn532 --trace-layer=protocol,debug --trace-level=driver
nfc-cli - 交互式命令行
# 列出所有可用卡片类型
nfc-cli --list-cards
# 连接卡片并进入交互模式
nfc-cli -c ntag224 -p COM21
# 指定读卡器类型
nfc-cli -c mifare_classic -p COM21 -r pn532
# 通过环境变量自动发现外部卡片
export NFC_CARD_PATH="../scripts/lib"
nfc-cli -c sm7 -p COM20
# 或手动指定
nfc-cli -c sm7 -p COM20 -i ../scripts/lib
交互命令
进入交互模式后,可以输入命令操作卡片:
> help # 显示可用命令
> auth 7 FFFFFFFFFFFF # 认证块 7
> read 10 # 读取页 10
> write 20 AABBCCDD... # 写入页 20
> quit # 退出
支持的值格式:
- 十六进制:
0xFF,0xAABBCCDD - 十进制:
7,255 - 字节串:
b'\xff\x00'
导入外部卡片
使用 -i 参数导入外部卡片模块,支持单个 .py 文件或包含 __init__.py 的目录:
# 导入单个文件
nfc-cli -c my_card -p COM20 -i /path/to/my_card.py
# 导入目录(需要有 __init__.py)
nfc-cli -c sm7 -p COM20 -i /path/to/lib
外部卡片模块需要使用 @CardRegistry.register("name") 装饰器注册。
示例
# NTAG224 认证并读取
nfc-cli -c ntag224 -p COM21
> auth 1 AABBCCDD112233445566778899001122
> read 4
# Mifare Classic 操作
nfc-cli -c mifare_classic -p COM21
> authenticate 7 FFFFFFFFFFFF
> read_block 8
> write_block 9 AABBCCDD112233445566778899001122
脚本示例
from nfc import *
# 连接读卡器 (默认使用环境变量 NFC_PORT 或 COM20)
connect()
# 开启追踪
trace.filter.driver = True
trace.filter.protocol = True
# 寻卡(自动切换协议解析器)
card_info = active()
ASSERT_IS_NOT_NONE(card_info, "未扫描到卡片")
trace.app(f"UID: {' '.join(f'{b:02X}' for b in card_info.uid)}")
# 创建卡片实例
from nfctester.registry import CardRegistry
card = CardRegistry.create("mifare_classic", reader=get_reader())
# 关闭连接
close()
上下文管理器
from nfc import *
with session() as reader:
card_info = reader.active()
trace.app(f"UID: {card_info.uid}")
# 自动断开连接
模块说明
| 模块 | 说明 |
|---|---|
reader.py |
读卡器连接与通信 |
trace.py |
日志追踪控制 |
assertions.py |
测试断言 |
bits.py |
位操作工具 |
hex_util.py |
十六进制工具 |
checksum.py |
校验工具 |
delay.py |
延时工具 |
API 参考
reader.py
| 函数 | 说明 |
|---|---|
connect(port, reader_type) |
连接读卡器 |
get_reader() |
获取当前读卡器实例 |
active(low_layer, ignore_error, reqa_cmd) |
寻卡,返回 CardInfo (uid/atq/sak),自动切换协议解析器 |
transceive(data, tx_crc, rx_crc) |
底层帧交互 |
transceive_bits(data, last_tx_bits, tx_crc, rx_crc) |
位控制帧交互 |
reqa() |
ISO14443-A REQA |
wupa() |
ISO14443-A WUPA |
halt() |
ISO14443-A HALT |
select(cl_level, uid) |
ISO14443-A SELECT |
anticoll(cl_level, nvb, uid_prefix) |
ISO14443-A ANTICOLL |
field_on() / field_off() |
RF 场控制 |
session(port, reader_type) |
上下文管理器 |
close() |
断开连接 |
trace.py
简洁写法(推荐):
| 函数 | 说明 |
|---|---|
trace.app(msg) |
输出到 app 层 (level=50) |
trace.debug(msg) |
输出到 debug 层 (level=10) |
trace.warning(msg) |
输出到 warning 层 (level=30) |
trace.error(msg) |
输出到 error 层 (level=40) |
trace.log(msg, layer="app") |
通用文本日志,指定层 |
属性控制(推荐):
| 属性 | 说明 |
|---|---|
trace.filter.driver = True |
启用 driver 层 |
trace.filter.protocol = True |
启用 protocol 层 |
trace.filter.debug = False |
禁用 debug 层 |
trace.filter.level = "warning" |
设置最低日志级别 |
trace.filter.level = 30 |
或用数字 |
# 简洁写法
trace.app("UID: AA BB CC DD")
trace.debug("[auth] Rt: 80 81")
# 属性控制
trace.filter.driver = True
trace.filter.protocol = True
trace.filter.level = "debug"
assertions.py
| 函数 | 说明 |
|---|---|
ASSERT_EQUAL(expected, actual, msg) |
相等断言 |
ASSERT_LEN(data, expected_len, msg) |
长度断言 |
ASSERT_IS_NOT_NONE(value, msg) |
非空断言 |
ASSERT_IS_NONE(value, msg) |
空值断言 |
bits.py
| 函数 | 说明 |
|---|---|
BITS_UPDATE(val, mask, data) |
Read-Modify-Write |
BITS_SET(val, mask) |
置位 |
BITS_RESET(val, mask) |
清位 |
hex_util.py
| 函数 | 说明 |
|---|---|
PARSE_HEX(text) |
解析纯 hex,返回 list[int] |
PARSE_HEX_BITS(text, last_bits=None) |
解析 hex + Verilog 位标记,返回 tuple[list[int], int] |
FORMAT_HEX(data, last_bits) |
格式化为可视化 hex |
checksum.py
| 函数 | 说明 |
|---|---|
GET_BCC(data) |
计算异或校验 |
delay.py
| 函数 | 说明 |
|---|---|
DELAY_MS(ms) |
毫秒延时 |
环境变量
优先级: CLI 参数 > 内层 .env > 外层 .env > 系统环境变量 (必须配置,否则报错)
| 变量 | 说明 | 默认值 |
|---|---|---|
NFC_PORT |
串口号 | - |
NFC_READER |
读卡器类型 | - |
NFC_TRACE_LAYER |
启用的层 (逗号分隔) | - |
NFC_TRACE_LEVEL |
最低日志级别 | warning |
NFC_CARD_PATH |
外部卡片模块搜索路径 (分号分隔) | - |
支持多层 .env 加载:从脚本目录向上搜索所有 .env 文件,按从外到内的顺序依次加载(内层覆盖外层同名变量)。
例如,脚本位于 /project/tests/run.py,沿途有 /project/.env 和 /project/tests/.env,加载顺序为:
/project/.env(基础配置)/project/tests/.env(覆盖基础配置中的同名变量)
在项目根目录或脚本所在目录创建 .env 文件进行持久化配置:
NFC_PORT=COM20
NFC_READER=pn532
NFC_TRACE_LAYER=protocol,warning,error,app
NFC_TRACE_LEVEL=protocol
AI 编写脚本
本目录下 SKILL.md 提供了 DSL 的完整 API 参考和 few-shot 示例,可直接用于 AI Agent 生成 NFC 脚本。
使用方式:在 AI 对话中引用该文件,例如:
@nfcscript/SKILL.md
Agent 会基于 SKILL.md 中的 API 签名、few-shot 示例和约定生成正确的脚本代码。
开发
# 运行测试
uv run pytest
# 运行特定测试
uv run pytest tests/test_xxx.py
Metadata
Release files for nfcscript 0.0.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nfcscript-0.0.18.tar.gz | 24.7 kB | With provenance | Details for nfcscript-0.0.18.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nfcscript-0.0.18-py3-none-any.whl | Python 3 | none | any | Details for nfcscript-0.0.18-py3-none-any.whl |
Total release size: 43.8 kB
Release files / nfcscript-0.0.18.tar.gz
| Download URL | nfcscript-0.0.18.tar.gz |
|---|---|
| Size | 24.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
369edb8be5b0d11c1313c3951568a389240eeb17e0df2ac93b18de1f64375d11
|
|
BLAKE2b-256 checksum How to use checksums |
8898c0b85f67bc4add2db3bd3c9702c9a2c42b9cf4e2559d61c5adc08b25d4e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / nfcscript-0.0.18-py3-none-any.whl
| Download URL | nfcscript-0.0.18-py3-none-any.whl |
|---|---|
| Size | 19.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1dceb6c3966057d48e54083b14e96e8b675aa4f0bf4dd48eb6e2ff24ef34baff
|
|
BLAKE2b-256 checksum How to use checksums |
94df64fd59f16bd715968490b69641918da4352a800895b2f7a588437672de0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logSecurity for nfcscript 0.0.18
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for nfcscript-0.0.18.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.