获取mifare卡序列号不正确

本文关键字:不正确 序列号 mifare 获取 | 更新日期: 2023-09-27 18:21:00

使用我使用的读卡器,检索MIFARE卡序列号的协议如下:

Mifare防撞,0x0202:
功能卡防撞
格式 nbsp nbsp 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

我需要更改什么才能获得正确的输出?

获取mifare卡序列号不正确

您遇到的问题似乎是值高于0x7F的字节被0x3F(问号("?")字符)取代。即,只有7位值正确显示,第8位设置的值被转换为"?"(0x3F)。例如,对于卡1,974682D6被"接收"为3F463F3F,因为0x970x820xD6设置了它们的第8位。

此问题的根源是使用ReadExisting()方法从串行端口读取字符串值。默认情况下,ReadExisting()从串行端口中读取字节,使用ASCII编码(System.Text.ASCIIEncoding)对其进行转换,并返回结果字符串。然后获取该字符串并将其转换回字节数组(再次使用ASCII编码)。

有问题的步骤是使用System.Text.ASCIIEncoding/Encoding.ASCII的转换。文件上写着:

由于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);