获取 mifare 卡序列号不正确
Posted
技术标签:
【中文标题】获取 mifare 卡序列号不正确【英文标题】:Get mifare card serial number is incorrect 【发布时间】:2015-11-08 16:56:13 【问题描述】:使用我使用的读卡器,获取MIFARE卡序列号的协议如下:
Mifare 防碰撞,
0x0202
: 功能卡防撞 格式aa bb 05 00 00 00 02 02 00
回复aa bb 0a 00 52 51 02 02 00 46 ff a6 b8 a4
其中46 ff a6 b8
是上述响应中的卡序列号。
我在 C# 中实现这个协议如下:
private SerialPort _serialPort = new SerialPort();
private string _receivedData = null;
public MifareCardReader(string comPort, int baudRate)
_serialPort = new SerialPort();
_serialPort.PortName = comPort;
_serialPort.BaudRate = baudRate;
_serialPort.DataBits = 8;
_serialPort.Parity = Parity.None;
_serialPort.StopBits = StopBits.One;
_serialPort.Handshake = Handshake.None;
_serialPort.Open();
// Add event
_serialPort.DataReceived += SerialPort_DataReceived;
public string MifareAnticollision()
if (_serialPort != null && _serialPort.IsOpen)
string message = "AABB050000000202000D";
byte[] data = StringToByteArray(message);
_serialPort.Write(data, 0, data.Length);
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
_receivedData += _serialPort.ReadExisting();
byte[] data = Encoding.ASCII.GetBytes(receivedData);
if (data.Length >= 9)
if (data[8] == 0) // OK
// Response data is complete
if (data.Length == 14)
StringBuilder hex = new StringBuilder(8);
hex.AppendFormat("0:X2", data[9]);
hex.AppendFormat("0:X2", data[10]);
hex.AppendFormat("0:X2", data[11]);
hex.AppendFormat("0:X2", data[12]);
string cardID = hex.ToString();
_receivedData = string.Empty;
else // fail
_receivedData = string.Empty;
我用 3 种不同的 MIFARE 卡对此进行了测试,但是,输出不是我所期望的:
卡 1:收到:3F463F3F
,预期:974682D6
卡 2:收到:3F450B3F
,预期:EA450B91
卡 3:收到:070D3F3F
,预期:070DEBD6
我需要更改什么才能获得正确的输出?
【问题讨论】:
但是你的问题是什么? 我完全按照协议做了,但没有得到正确的卡序列号。我不知道为什么。我的算法错误或协议丢失??? 好的,所以你有错误的输出,只需给我 3 个输入示例作为十六进制值和你想要得到的输出,我会为你修复它:) Card3: 070D3F3F 是错误的输出?还是输入? 你通过串口说的是什么? 如果是this读者。为什么不使用“Mifare S50 select a card (Request + anticollision + select) 0x0200”组合命令?我对这个特定的读者没有经验,但通常REQA
(在你的情况下是命令 0x0201)应该在 CL1
(在你的情况下是命令 0x0202)之前。
【参考方案1】:
您遇到的问题似乎是将值高于0x7F
的字节替换为0x3F
(问号(“?”)字符)。 IE。只有 7 位值正确显示,第 8 位设置的值变成“?” (0x3F
)。例如。对于卡 1,974682D6
被“接收”为 3F463F3F
,因为 0x97
、0x82
和 0xD6
设置了它们的第 8 位。
这个问题的根源是你正在使用ReadExisting()
方法从串口读取一个字符串值。默认情况下,ReadExisting()
从串行端口读取字节,使用 ASCII 编码 (System.Text.ASCIIEncoding
) 转换它们,并返回结果字符串。然后获取该字符串并将其转换回字节数组(再次使用 ASCII 编码)。
有问题的步骤是使用System.Text.ASCIIEncoding
/Encoding.ASCII
的转换。 documentation 说:
由于 ASCII 是 7 位编码,ASCII 字符限制为最低 128 个 Unicode 字符,从 U+0000 到 U+007F。 [...] 超出该范围的字符在执行编码操作之前被替换为问号 (?)。
因此,您应该使用Read()
或ReadByte()
方法将字节直接读入字节数组。例如。与
byte[] buffer = new byte[_serialPort.ReadBufferSize];
int bytesRead = _serialPort.Read(buffer, 0, buffer.Length);
【讨论】:
以上是关于获取 mifare 卡序列号不正确的主要内容,如果未能解决你的问题,请参考以下文章