获取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
需要更改哪些内容才能获得正确的输出?
答
您遇到的问题似乎是将0x7F
以上的字节替换为0x3F
(问号(“?”)字符)。即只有7位值显示正确,第8位设置的值变为“?” (0x3F
)。例如。对于卡1,由于0x97
,0x82
和0xD6
设置了其第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);
但你有什么问题吗? –
我没有完全按照协议,但没有得到正确的卡片序列号。我不知道为什么。我的算法错误或协议丢失? –
确定,所以你有不良的输出,给我你的输入十六进制值和ü想,我会解决它的ü:) Card3输出的3个例子:070D3F3F是坏的输出?或者它是输入? –