获取MIFARE卡的序列号不正确

问题描述:

由于我使用的读卡器,检索MIFARE卡的序列号的协议如下:获取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
  • Card 3:received:070D3F3F,expected:070DEBD6

需要更改哪些内容才能获得正确的输出?

+1

但你有什么问题吗? –

+0

我没有完全按照协议,但没有得到正确的卡片序列号。我不知道为什么。我的算法错误或协议丢失? –

+0

确定,所以你有不良的输出,给我你的输入十六进制值和ü想,我会解决它的ü:) Card3输出的3个例子:070D3F3F是坏的输出?或者它是输入? –

您遇到的问题似乎是将0x7F以上的字节替换为0x3F(问号(“?”)字符)。即只有7位值显示正确,第8位设置的值变为“?” (0x3F)。例如。对于卡1,由于0x97,0x820xD6设置了其第8位,所以974682D6被“接收”为3F463F3F

此问题的根源在于您正在使用ReadExisting()方法从串口读取字符串值。默认情况下,ReadExisting()从串口读取字节,使用ASCII编码(System.Text.ASCIIEncoding)翻译它们,并返回结果字符串。然后您将该字符串转换回字节数组(再次使用ASCII编码)。

有问题的步骤是使用System.Text.ASCIIEncoding/的转换。所述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);