注:c#初学者,懂得不是很多,因为最近有一个项目才开始研究的,学术不精,勿喷。
这里我们用的是明华URF-R330读写器 卡片类型M1 开发环境vs2008
由于我只需要进行对卡片的读取和修改,所以这篇文章只针对读卡写卡而生
首先我们得简单的了解一下读卡器从连接电脑到读取卡片到写卡这一个简单的过程 :
1.读卡器连接电脑,明华这款读卡器是利用USB接口的,首先是驱动吗?这个大家都懂(这里我是没有用到驱动直接就连上了,可以在我的电脑右击管理的配置里查看是否连接上卡机)。
2.咳咳!这里敲黑板了,因为我们要开始用代码来连接了,首先是需要代码这边通过端口来连接卡机。(这里提醒一下注意卡机的端口是否被占用,也就是说卡机这个时候是否被你电脑的另一个程序占用)
3.端口连接上了,这里就需要读卡的步骤,但是在读卡之前呢需要进行对卡片的寻卡、认证。
4.这个时候就可以对你的卡片为所欲为了,想读想写随你便。
5.关闭端口,这个不要我说了吧,图书馆借完书还得换回去呢!
M1卡的结构:
M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63.
这里要注意,扇区0的0块是不允许修改的,这里存储这卡片的基本信息。而且每个扇区的最后一块是存储着扇区的控制块和密码,这个基本的卡片规则你们就去网上一查,有的是。
说了这么一大堆了终于要开始步入正题了。
由于我是用的开发者文件进行二次开发的,首先我们需要以下几个文件,nwrf32.dll,common.cs,mifareone.cs,如果需要的大家可以来找我要(我也是在淘宝那里骗来的……..),首先把dll放入Debug里面,引入这两个文件就好了。
1.连接端口部分:
public int icdev; // 通讯设备标识符
icdev = common.rf_init(0, 115200);//这个是在按钮里的
我看了他们的Demo写了一大堆,我一开始还照着他的一点一点写,后来发现他写的那些一点用都没有,也就是这一句话,不要问我为什么写0,115200;我也不知道,这是我经过无限的测试发现的问题,只要这么写就能连上,我只知道第一个参数是端口第二个是波特率。对了,这里最好定义一个全局变量,就是我写的那样,因为我们随时要调用这个通讯设备标识符,如果成功的话这个标识符会大于0;
2.寻卡
UInt16 tagtype = 0;
byte size = 0;
uint snr = 0;
mifareone.rf_reset(icdev, 3);
st = mifareone.rf_request(icdev, 1, out tagtype);
if (st != 0)
{
lbResult.Text = "request error!";
return;
}
st = mifareone.rf_anticoll(icdev, 0, out snr);
if (st != 0)
{
lbResult.Text = "anticoll error!";
return;
}
string snrstr = "";
snrstr = snr.ToString("X");
//lbSnr.Text = snrstr;
st = mifareone.rf_select(icdev, snr, out size);
if (st != 0)
{
lbResult.Text = "select error!";
return;
}
lbResult.Text = "寻卡成功!";
这个是按照他的那个说明文档写的,后来我总结了一下,其实只需要三句话,就是调用dll里的三个方法,这个留给你们自己去想象吧!
3.寻卡
byte[] key1 = new byte[17];
byte[] key2 = new byte[7];
string skey = "FFFFFFFFFFFF";
key1 = Encoding.ASCII.GetBytes(skey);
common.a_hex(key1, key2, 12);
common.rf_load_key(icdev, 0, sec, key2);
st = mifareone.rf_authentication(icdev, 0, sec);
这个也是我通过修改之后的版本这里的skey就是卡片扇区的密码,sec是扇区,这里一定要注意这个认证是通过扇区进行认证的,也就是说你每次必须先认证扇区后才能进行对该扇区的读取和写入,这里我们必须回到一开始M1卡的问题,这个卡有16个扇区,也就是说你想读那个扇区就要读取那个扇区,毕竟一把钥匙开一把锁么,如果初始卡的话一般都是12个f,如果是扇区被改密码了的话,哼哼这里我就没办法了,比较这时候你可能在想一些其他打法律擦边球的事情了。。。。(对了扇区最好也有用全局变量)
4.读卡
mifareone.rf_read(icdev, sec * 4 + j, data);
str=System.Text.Encoding.Default.GetString(data);
这里其实也就是一句话,就是上面那个读取的方法,这我有必要讲一下,看到j了么,这个就是代表块的意思,因为每个扇区有4块么,所以这里j只取0123,data就是你们想要的数据了,这里我用的是第二句的方法解析成的字符串,这里你们可以自己开发,有好多办法可以去解析的,下面给大家看一下demo里提供的方法:
byte[] data = new byte[16];
byte[] buff = new byte[32];
for (i = 0; i < 32; i++)
buff[i] = 0;
for (i = 0; i < 16; i++)
buff[i] = 0;
byte[] buffs =System.Text.Encoding.ASCII.GetBytes(str);
buff = System.Text.Encoding.Default.GetBytes(str);
common.a_hex(buff, data, 32);
common.hex_a(data, buff, 16);
txtShanQu.Text = System.Text.Encoding.ASCII.GetString(buffs);
txtShuJu.Text = System.Text.Encoding.Default.GetString(buff);
这个是他们的解析方法,都是大同小异,看你们想怎么用。
5.写卡
data = System.Text.Encoding.Default.GetBytes(str);
st = mifareone.rf_write(icdev, sec * 4 + j, data);
我就是很暴力的把一个字符串放到data里面,然后给他装进去,大家可以用其他的方法,因为我这样写的话存不了多少数据。
6.断开端口
common.rf_exit(icdev);//断开连接
这个就很简单了,断开就是了,到结尾了,给大家一个彩蛋
common.rf_beep(icdev, 5);//蜂鸣
这个是让卡机叫的代码,当时我怀着好奇心把那个5改成了1000后我才知道妈的这个竟然是蜂鸣,当时办公室所有人都在认真的敲代码!!!!
好了基本上就是这么个情况,如果这里我说的不够好那块不对的话尽管提,互相学习吗,毕竟我就是一个初学者,那块错了欢迎指出,勿喷就好了。。。。。。。。