如何逐个认证MIFARE Classic 1K扇区并批量写入数据?求C#代码
实现MIFARE Classic 1K多扇区认证与写入的C#方案
当然可以实现逐个扇区认证并写入多个块的功能!MIFARE Classic 1K的每个扇区(共16个扇区)独立需要认证,认证通过后就能操作该扇区内的所有数据块(每个扇区包含3个数据块+1个控制块)。你只需要循环遍历目标扇区,依次完成扇区认证→写入该扇区所有数据块的流程即可。
核心思路
- 遍历需要操作的扇区列表(比如你提到的扇区10、11)
- 对每个扇区,先调用你已实现的单扇区认证函数完成认证
- 计算该扇区对应的3个数据块编号(扇区N的块号为
N*4、N*4+1、N*4+2,务必跳过第4个控制块N*4+3) - 逐个写入每个数据块的内容
- 处理过程中的异常(比如认证失败、写入失败)
完整C#代码示例
假设你已经有一个基础的NFC操作类(比如MifareCard),包含已实现的AuthenticateSector(扇区认证)和WriteBlock(块写入)方法,以下是封装后的多扇区写入函数:
using System; using System.Collections.Generic; public class MifareOperations { // 假设你已有的MIFARE卡操作实例 private readonly MifareCard _mifareCard; public MifareOperations(MifareCard mifareCard) { _mifareCard = mifareCard ?? throw new ArgumentNullException(nameof(mifareCard)); } /// <summary> /// 批量写入多个扇区的数据 /// </summary> /// <param name="sectorDataMap">键:扇区号,值:该扇区3个数据块的内容(每个块16字节)</param> /// <param name="key">扇区认证密钥(若不同扇区密钥不同,可改为传入字典)</param> /// <returns>是否全部写入成功</returns> public bool WriteMultipleSectors(Dictionary<int, byte[][]> sectorDataMap, byte[] key) { foreach (var sectorEntry in sectorDataMap) { int sectorNumber = sectorEntry.Key; byte[][] sectorBlocksData = sectorEntry.Value; // 1. 验证输入合法性:扇区号范围0-15,每个扇区必须提供3个块的数据 if (sectorNumber < 0 || sectorNumber > 15) { Console.WriteLine($"无效的扇区号:{sectorNumber},仅支持0-15"); return false; } if (sectorBlocksData == null || sectorBlocksData.Length != 3) { Console.WriteLine($"扇区{sectorNumber}需要提供3个数据块的内容"); return false; } // 2. 认证当前扇区 bool isAuthenticated = _mifareCard.AuthenticateSector(sectorNumber, key); if (!isAuthenticated) { Console.WriteLine($"扇区{sectorNumber}认证失败"); return false; } // 3. 计算该扇区的3个数据块编号并写入 for (int blockIndex = 0; blockIndex < 3; blockIndex++) { int blockNumber = sectorNumber * 4 + blockIndex; byte[] blockData = sectorBlocksData[blockIndex]; // 验证块数据长度:每个块必须是16字节 if (blockData == null || blockData.Length != 16) { Console.WriteLine($"扇区{sectorNumber}的块{blockNumber}数据长度错误,需16字节"); return false; } bool isWritten = _mifareCard.WriteBlock(blockNumber, blockData); if (!isWritten) { Console.WriteLine($"扇区{sectorNumber}的块{blockNumber}写入失败"); return false; } Console.WriteLine($"扇区{sectorNumber}的块{blockNumber}写入成功"); } } Console.WriteLine("所有扇区写入完成"); return true; } } // 假设你已有的基础MIFARE操作类(示例框架,替换为你的真实实现) public class MifareCard { // 你已实现的单扇区认证函数 public bool AuthenticateSector(int sectorNumber, byte[] key) { // 这里替换为你的真实认证逻辑:比如发送认证指令到NFC读卡器 // 示例返回true,实际需根据硬件交互结果返回 return true; } // 你已实现的块写入函数 public bool WriteBlock(int blockNumber, byte[] data) { // 这里替换为你的真实写入逻辑:比如发送写入指令到NFC读卡器 // 示例返回true,实际需根据硬件交互结果返回 return true; } }
使用示例
// 初始化NFC卡操作实例 var mifareCard = new MifareCard(); var operations = new MifareOperations(mifareCard); // 准备要写入的数据:扇区10和11的3个数据块内容(每个块16字节) var sectorData = new Dictionary<int, byte[][]> { { 10, new byte[][] { new byte[16] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }, new byte[16] { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 }, new byte[16] { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30 } } }, { 11, new byte[][] { new byte[16] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40 }, new byte[16] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50 }, new byte[16] { 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60 } } } }; // 认证密钥(示例用默认的MIFARE密钥A:0xFF 0xFF 0xFF 0xFF 0xFF 0xFF) byte[] key = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // 执行多扇区写入 bool success = operations.WriteMultipleSectors(sectorData, key);
关键注意事项
- 密钥管理:如果不同扇区使用不同的认证密钥,你可以把
key参数改为Dictionary<int, byte[]>,按扇区号匹配对应的密钥。 - 数据长度:MIFARE Classic的每个数据块固定为16字节,写入时必须保证数据长度符合要求,否则会写入失败。
- 控制块保护:绝对不要写入扇区的第4个块(控制块),该块存储扇区的密钥和访问权限,误写会导致扇区甚至整个卡片报废。
- 异常处理:实际项目中建议添加更细致的异常捕获(比如读卡器断开、卡片移除等情况),避免程序崩溃。
内容的提问来源于stack exchange,提问作者ANKIT JOHRI
相关产品推荐
相关产品推荐

