Windows读取NXP MiFare Ultralight C类型NFC卡片的信息
1,读取
我们需要外接一个NFC Reader让Windows可以读取NFC卡片的内容。
因为特殊原因,我们选择了Sony rc-s380 NFC Reader。相关介绍
我们需要下载并安装NFC Port Software,以便我们可以顺利使用上述NFC Reader。
安装之后,我们需要去Github获取一个NFC Port Software的.Net封装包:tijins/NfcLib
解压并运行nfc_lib_sample之后我们可以看到这样一个WindowFrom程序。

因为现在要读取的卡类型试MIFARE,所以我们勾选正确的CheckBox,其他设置保持不变,依次点击上述三个橘色方框按钮。
在红色箭头所指的方向就能看到第一个block的十六进制字符串的数据。
为了读取卡片所有block/page的信息,我们将btRead_Click的代码稍稍修改为:
private void btRead_Click(object sender, EventArgs e)
{
byte block = (byte)nudBlock.Value;
try
{
byte[] data = null;
data = new byte[NfcLib.MF_BLOCK_LENGTH];
if (card is Mifare)
{
StringBuilder readSB = new StringBuilder();
for(byte i=;i < ; i++)//我现在的卡包含45个blocks/pages
{
((Mifare)card).Read(i, data, );
readSB.AppendLine(Utility.ByteToHex(data, , data.Length));
}
tbRead.Text = readSB.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
有个小遗憾就是,如果NFC Reader没有连接的时候启动app会抛出异常,而如果app已经启动再拔出然后插入NFC Reader又会无法再读卡除非重启app或者重新初始化。这个需要有点改进。
2,解析
根据上述步骤,我们得到了某张卡的信息如下:
C9 0A C9 5A 1D E1
0A C9 5A 1D E1 A0 0C
1D E1 A0 0C 0F D1
E1 A0 0C 0F D1 0B
A0 0C 0F D1 0B 6E
0F D1 0B 6E
0B 6E FE
6E FE
FE
FE (以下省略...)
然后,我们对它做一点移位:
04 C9 02 47 0A C9 5A 84 1D 48 00 00 E1 10 12 00
0A C9 5A 84 1D 48 00 00 E1 10 12 00 01 03 A0 0C
1D 48 00 00 E1 10 12 00 01 03 A0 0C 34 03 0F D1
E1 10 12 00 01 03 A0 0C 34 03 0F D1 01 0B 54 02
01 03 A0 0C 34 03 0F D1 01 0B 54 02 65 6E 32 30
34 03 0F D1 01 0B 54 02 65 6E 32 30 31 38 31 30
01 0B 54 02 65 6E 32 30 31 38 31 30 32 35 FE 00
65 6E 32 30 31 38 31 30 32 35 FE 00 00 00 00 00
31 38 31 30 32 35 FE 00 00 00 00 00 00 00 00 00
32 35 FE 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
可以看出,每一行只有第一列是我们需要的tag信息。
C9
0A C9 5A
1D
E1 00 A0 0C
0F D1
0B
6E FE
前面的四行是卡的UID以及制造商等信息。我们只需要关心下半段的数据。
(Tag: Lock Control TLV)
(Length: bytes)
A0 0C (Value: Information on position and function of lock bytes)
(Tag: NDEF Message TLV)
0F (Length: bytes)
D1 0B 6E
FE (Tag: Terminator TLV; has no length field)
所以,我们得到了NDEF message:D1 01 0B 54 02 65 6E 32 30 31 38 31 30 32 35
NDEF message:
D1 (Header byte of record )
(Type length: byte)
0B (Payload length: bytes)
(Type: "T")
6E (Payload field)
我们再分析最为关键的payload field,如下:
The payload field:
(Status byte: Text is UTF- encoded, Language code has a length of bytes)
6E (Language code: "en")
(Text: "")
可以用在线工具来验证一下 “32 30 31 38 31 30 32 35 ”
最后,上述步骤,用写C#的实现如下(不保证所有Mifare卡适用):
private string GetNfcTag(List<byte[]> cardContentList)
{
List<byte> cardBytes = new List<byte>();
foreach(byte[] rowCardContent in cardContentList)
{
cardBytes.AddRange(rowCardContent.Take());
} byte[] cardUid = cardBytes.Take().ToArray();
string cardUidStr = Utility.ByteToHex(cardUid, , cardUid.Length); byte[] cardMaker = cardBytes.Skip().Take().ToArray();
string cardMakerStr = Utility.ByteToHex(cardMaker, , cardMaker.Length); byte[] memoryBytes = cardBytes.Skip().ToArray(); byte lockControlByte = memoryBytes[];
byte lockByteCount = memoryBytes[];//how many bytes are the lock bytes
byte[] lockBytes = memoryBytes.Skip().Take(lockByteCount).ToArray(); int nedfLengthByteIndex = + lockByteCount + + ;
byte ndefLength = memoryBytes[nedfLengthByteIndex]; if (ndefLength == )//Tag empty
return string.Empty; byte[] ndefBytes = memoryBytes.Skip(nedfLengthByteIndex + ).Take(ndefLength).ToArray(); byte payloadHeader = ndefBytes[];
byte payloadTypeLength = ndefBytes[];
byte payloadLength = ndefBytes[];
byte[] payloadType = ndefBytes.Skip().Take(payloadTypeLength).ToArray(); byte[] payloadBytes = ndefBytes.Skip( + payloadType.Length).Take(payloadLength).ToArray(); byte languageCodeLength = payloadBytes[];
byte[] languageCode = payloadBytes.Skip().Take(languageCodeLength).ToArray();
byte[] tag = payloadBytes.Skip( + languageCode.Length).Take(payloadLength - languageCode.Length - ).ToArray(); string tagHex= Utility.ByteToHex(tag , , tag .Length);
string tagStr = Encoding.UTF8.GetString(tag);
return tagStr;
}
参考链接:
How to read binary blocks of mifare card?
Reading a NFC Mifare card raw data in android
RC-S380 非接触ICカードリーダー/ライター PaSoRi(パソリ)
Windows读取NXP MiFare Ultralight C类型NFC卡片的信息的更多相关文章
- 射频识别技术漫谈(16)——Mifare UltraLight
Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本.小容量的卡片.低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片 ...
- php 读取文件头判断文件类型的实现代码
php代码实现读取文件头判断文件类型,支持图片.rar.exe等后缀. 例子: <?php $filename = "11.jpg"; //为图片的路径可以用d:/uploa ...
- Windows上常见的集中布尔类型的比较
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Windows上常见的集中布尔类型的比较.
- Windows Phone 同步方式获取网络类型
原文:Windows Phone 同步方式获取网络类型 在Windows Phone 开发中有时候需要获取设备当前连接网络的类型,是Wifi,还是2G,3G,或者4G,SDK中提供获取网络类型的API ...
- python3 在 windows 读取路径多了一个\u202a 是咋回
python3 在 windows 读取路径多了一个\u202a 是咋回事
- wpf prism4 出现问题:无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。
WPF Prism 框架 程序 出现 问题: 无法加载一个或多个请求的类型.有关更多信息,请检索 LoaderExceptions 属性. 1.开始以为是配置的问题,找了半天,最后原来是有个依赖类库没 ...
- 无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。
新建一个MVC4的项目,引用DAL后,将DAL的连接字符串考入: <connectionStrings> <add name="brnmallEntities&qu ...
- “无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性 “之解决
今天在学习插件系统设计的时候遇到一个问题:“System.Reflection.ReflectionTypeLoadException: 无法加载一个或多个请求的类型. 于是百度一下,很多内容都差不多 ...
- Sqlserver查询表结构信息-字段说明、类型、长度等信息
Sqlserver 中查询表结构信息-字段说明.类型.长度等信息综合语法. SELECT 表名 = d.name,--case when a.colorder=1 then d.name else ' ...
随机推荐
- Gift
[问题描述] 人生赢家老王在网上认识了一个妹纸,然后妹纸的生日到了,为了表示自己的心 意,他决定送她礼物.可是她喜爱的东西特别多,然而他的钱数有限,因此他想 知道当他花一定钱数后剩余钱数无法再购买任何 ...
- C# Pen绘制虚线(System.Drawing.Pen与System.Windows.Media.Pen)
一.绘制虚线的方法 GDI绘制,使用的是System.Drawing.Pen Pen pen = new Pen(Color.Red, 1); pen.DashStyle = S ...
- codevs2557张程易(背包dp)
2557 张程易,编程易 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 张程易是一名神奇的魔法少女,在oier之中有着 ...
- UNIX环境高级编程--7
进程环境main函数: C程序总是从main函数开始执行.main函数原型是: int main(int argc, char *argv[]); 当内核执行C程序时(使用一个exe ...
- 在 kafka 的 broke 和 client 之间加入 SSL 双向认证
在 kafka 的 broke 和 client 之间加入 SSL 双向认证https://blog.csdn.net/hohoo1990/article/details/79110031 kafka ...
- Unity3d dotween
位置 1. 移动到指定位置 obj.transform.DOMove(, , ), 2f); a. 单方向可以用DOMoveX.DOMoveY.DOMoveZ b. 本地坐标系版本:DOLocalMo ...
- Glide4.0 centerCrop属性和圆角 冲突
首先致谢:https://blog.csdn.net/flyinbed_/article/details/75506062 咱们不是代码的生产者,只是代码的搬运工. 最近有个工作中有个需求就是展示的图 ...
- ibatis知识点
1:ibatis是apache的一个开源的项目,是一个O/R mapping解决方案,优点,小巧,灵活.2:搭建环境:导入ibatis相关jar包,jdbc驱动包等3:配置文件: jdbc连接的属性文 ...
- linux下用scp命令在两个服务器之间传输文件,利用php_scp函数进行文件传输
在linux下利用scp进行文件传输, 从服务器下载文件 scp username@servername:/path/filename /path/filename 上传本地文件到服务器 scp /p ...
- Spring学习_day02_AOP,AspectJ,JdbcTemplate
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! Spring_day02 一.AOP面向切面编程 1. ...