本示例使用设备:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.6781645eXF3tm5&ft=t&id=959258149468
一、密钥认证
procedure TForm1.Button21Click(Sender: TObject);
varctrlword:byte;passwordid:byte; //密钥类型status:byte; //存放返回值authkeybuf:array[0..3] of byte;uidbuf:array[0..7] of byte; //UIDcardstr:string;
begincardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;if checkuidstr(Trim(Edit5.Text) ,4,authkeybuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('卡片认证密钥输入错误,请输入8位16进制卡认证密钥!', '提示', MB_OK+MB_ICONSTOP);edit5.SetFocus ;exit;end;if ComboBox2.ItemIndex =4 thenpasswordid:=$10else if ComboBox2.ItemIndex =3 thenpasswordid:=$8else if ComboBox2.ItemIndex =2 thenpasswordid:=$4else if ComboBox2.ItemIndex =1 thenpasswordid:=$2else passwordid:=$1;ctrlword:=$4;status:=iso15693authkey(ctrlword,@uidbuf,passwordid,@authkeybuf);case status of0:beginpcdbeep(50);Application.MessageBox(PAnsiChar(AnsiString('UID '+cardstr+' 密钥认证成功!')), '提示', MB_OK+MB_ICONINFORMATION);end;8:Application.MessageBox('异常代码:8,卡不在感应区或指令UID不匹配该卡!', '提示', MB_OK+MB_ICONSTOP);20:Application.MessageBox('异常代码:20,读写器不支持该指令!', '提示', MB_OK+MB_ICONSTOP);47:Application.MessageBox('异常代码:47,该卡不支持加密功能,或加密功能未启用,或密码错误(该卡将不能再响应任何指令,只能拿开卡再重放)!', '提示', MB_OK+MB_ICONSTOP);else MessageDispInfo(status);end;
end;
二、更改密钥
procedure TForm1.Button22Click(Sender: TObject);
varctrlword:byte;passwordid:byte; //密钥类型status:byte; //存放返回值newkeybuf:array[0..3] of byte;uidbuf:array[0..7] of byte; //UIDcardstr:string;
begincardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;if checkuidstr(Trim(Edit10.Text) ,4,newkeybuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('卡片新密钥输入错误,请输入8位16进制新密钥!', '提示', MB_OK+MB_ICONSTOP);edit10.SetFocus ;exit;end;if ComboBox2.ItemIndex =4 thenpasswordid:=$10else if ComboBox2.ItemIndex =3 thenpasswordid:=$8else if ComboBox2.ItemIndex =2 thenpasswordid:=$4else if ComboBox2.ItemIndex =1 thenpasswordid:=$2else passwordid:=$1;ctrlword:=$4;status:=iso15693writekey(ctrlword,@uidbuf,passwordid,@newkeybuf);case status of0:beginpcdbeep(50);Application.MessageBox(PAnsiChar(AnsiString('UID '+cardstr+' 更改卡密钥成功!')), '提示', MB_OK+MB_ICONINFORMATION);end;8:Application.MessageBox('异常代码:8,卡不在感应区或指令UID不匹配该卡!', '提示', MB_OK+MB_ICONSTOP);20:Application.MessageBox('异常代码:20,读写器不支持该指令!', '提示', MB_OK+MB_ICONSTOP);47:Application.MessageBox('异常代码:47,上一条指令必须是认证密码指令......!', '提示', MB_OK+MB_ICONSTOP);else MessageDispInfo(status);end;
end;
三、设置密钥保护块及密钥认证方式
procedure TForm1.Button23Click(Sender: TObject);
varctrlword:byte;blockpoint,extprotectstatus:byte; //高低块分隔地址,配置值status:byte; //存放返回值uidbuf:array[0..7] of byte; //UIDcardstr:string;
begincardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;if(not isrightint(edit11.Text)) thenbeginApplication.MessageBox('分隔高低块的块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);edit11.SetFocus();edit11.SelectAll();exit;endelse blockpoint:=strtoint(edit11.Text);extprotectstatus:=ComboBox3.ItemIndex +ComboBox4.ItemIndex *16;ctrlword:=$4;status:=iso15693protectblock(ctrlword,@uidbuf,blockpoint,extprotectstatus);case status of0:beginpcdbeep(50);Application.MessageBox(PAnsiChar(AnsiString('UID '+cardstr+' 块密码保护设定成功!')), '提示', MB_OK+MB_ICONINFORMATION);end;8:Application.MessageBox('异常代码:8,卡不在感应区或指令UID不匹配该卡!', '提示', MB_OK+MB_ICONSTOP);20:Application.MessageBox('异常代码:20,读写器不支持该指令!', '提示', MB_OK+MB_ICONSTOP);47:Application.MessageBox('异常代码:47,必须都认证读取密码和写入密码成功后再进行块密码保护设定!', '提示', MB_OK+MB_ICONSTOP);else MessageDispInfo(status);end;
end;
四、开启隐私保护
procedure TForm1.Button24Click(Sender: TObject);
varctrlword:byte;status:byte; //存放返回值password:array[0..3] of byte;uidbuf:array[0..7] of byte; //UIDcardstr:string;
begincardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;if checkuidstr(Trim(Edit5.Text) ,4,password)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('卡片隐私密钥输入错误,请输入8位16进制卡认证隐私密钥!', '提示', MB_OK+MB_ICONSTOP);edit5.SetFocus ;exit;end;if Application.MessageBox('卡片启用隐私保护后将不再响应除认证隐私密钥的任何指令,确认您已记住此卡的UID 及 隐私密钥,否则此卡将报废!', '严重警告', MB_OKCANCEL+MB_ICONQUESTION) <>1 then exit;ctrlword:=$4;status:=iso15693privacyen(ctrlword,@uidbuf,@password);case status of0:beginpcdbeep(50);Application.MessageBox(PAnsiChar(AnsiString('UID '+cardstr+' 启用隐私保护成功,此卡不再响应除认证隐私密码的任何指令,该卡必须 验证隐私密码 才能恢复非隐私状态!')), '提示', MB_OK+MB_ICONINFORMATION);end;8:Application.MessageBox('异常代码:8,卡不在感应区或指令UID不匹配该卡!', '提示', MB_OK+MB_ICONSTOP);20:Application.MessageBox('异常代码:20,读写器不支持该指令!', '提示', MB_OK+MB_ICONSTOP);47:Application.MessageBox('异常代码:47,该卡不支持加密功能,或加密功能未启用,或密码错误(该卡将不能再响应任何指令,只能拿开卡再重放)!', '提示', MB_OK+MB_ICONSTOP);else MessageDispInfo(status);end;
end;
五、读取块内数据
procedure TForm1.Button16Click(Sender: TObject);
vari:byte;status:byte;//存放返回值flags:byte;//控制标志startblock:byte; //起始扇区blocknum:byte; //读扇区数revlen:array[0..1] of byte; //长度uidbuf:array[0..7] of byte;//UIDmypiccdata:array[0..60] of byte;//每次读卡数据缓冲readbuf:array[0..8000] of byte;//全部卡数据缓冲j,p:integer;cardstr,carddatahex:string;begincardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;edit9.Text :='22';flags := strtoint('$'+edit9.Text);//操作标志if(not isrightint(edit2.Text)) thenbeginApplication.MessageBox('读写起始块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);edit2.SetFocus();edit2.SelectAll();exit;endelse startblock:=strtoint(edit2.Text);if(not isrightint(edit3.Text)) thenbeginApplication.MessageBox('读写块数输入错误!', '警告', MB_OK+MB_ICONSTOP);edit3.SetFocus();edit3.SelectAll();exit;endelse blocknum:=strtoint(edit3.Text );memo1.Text :='';j:=0;carddatahex:='';while j<blocknum dobeginstatus := iso15693readblock(flags,startblock+j,1,@uidbuf,@revlen,@mypiccdata); //读一个块数据if status=0 then //读卡成功,获取数据,指针加1beginfor i:=0 to revlen[0]-1 docarddatahex:=carddatahex+inttohex(mypiccdata[i],2)+' ';j:=j+1;endelse //读卡失败,指针跳到最后退出j:=blocknum;end;if status=0 thenbeginpcdbeep(50);memo1.Text:=carddatahex;if revlen[0]=8 then //根据读一块返回的字节数预判是什么类型的卡ComboBox1.ItemIndex:=1else if revlen[0]=32 thenComboBox1.ItemIndex:=2else ComboBox1.ItemIndex:=0;endelse if status=46 thenApplication.MessageBox('请先认证相应的密码!', '提示', MB_OK+MB_ICONSTOP)elseMessageDispInfo(status);
end;
六、写数据到块内
procedure TForm1.Button17Click(Sender: TObject);
vari,j,p:integer;status:byte; //存放返回值flags:byte; //控制标志startblock:byte; //起始扇区blocknum:byte; //读扇区数writelen:integer; //长度uidbuf:array[0..7] of byte;//UIDwritebuf:array[0..1024] of byte;//卡数据缓冲mypiccdata:array[0..31] of byte;writestr:string;cardstr:string;eachblocksize:integer;beginif ComboBox1.ItemIndex=0 theneachblocksize:=4else if ComboBox1.ItemIndex=1 theneachblocksize:=8else eachblocksize:=32;cardstr:=trim(edit4.Text);if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);edit4.SetFocus ;exit;end;if(not isrightint(edit2.Text)) thenbeginApplication.MessageBox('读写起始块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);edit2.SetFocus();edit2.SelectAll();exit;endelse startblock:=strtoint(edit2.Text);if(not isrightint(edit3.Text)) thenbeginApplication.MessageBox('读写块数输入错误!', '警告', MB_OK+MB_ICONSTOP);edit3.SetFocus();edit3.SelectAll();exit;endelse blocknum:=strtoint(edit3.Text );writelen:=blocknum*eachblocksize;if checkuidstr(trim(Memo1.Text) ,writelen,writebuf)=false then //检测数据是否合法并放入数组缓冲beginApplication.MessageBox('需要写入的数据输入错误,可先执行读卡操作!', '提示', MB_OK+MB_ICONSTOP);Memo1.SetFocus ;exit;end;edit9.Text :='22';flags := strtoint('$'+edit9.Text);//操作标志j:=0;while j<blocknum dobeginfor p:=0 to eachblocksize-1 do mypiccdata[p]:=writebuf[j*eachblocksize+p];status := iso15693writeblock(flags,startblock+j,1,@uidbuf,eachblocksize,@mypiccdata);if status=0 then //写卡成功,指针加1j:=j+1else //写卡失败,指针跳到最后退出j:=blocknum;end;if status=0 thenbeginpcdbeep(50);Application.MessageBox(PAnsiChar(AnsiString(cardstr+' 号卡写卡成功!')), '提示', MB_OK+MB_ICONINFORMATION);endelse if status=46 thenApplication.MessageBox('请先认证相应的密码!', '提示', MB_OK+MB_ICONSTOP)else MessageDispInfo(status);
end;