本示例使用设备:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.6781645eXF3tm5&ft=t&id=959258149468
一、密钥认证
procedure TForm1.Button21Click(Sender: TObject);
var
ctrlword:byte;
passwordid:byte; //密钥类型
status:byte; //存放返回值
authkeybuf:array[0..3] of byte;
uidbuf:array[0..7] of byte; //UID
cardstr:string;
begin
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
if checkuidstr(Trim(Edit5.Text) ,4,authkeybuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('卡片认证密钥输入错误,请输入8位16进制卡认证密钥!', '提示', MB_OK+MB_ICONSTOP);
edit5.SetFocus ;
exit;
end;
if ComboBox2.ItemIndex =4 then
passwordid:=$10
else if ComboBox2.ItemIndex =3 then
passwordid:=$8
else if ComboBox2.ItemIndex =2 then
passwordid:=$4
else if ComboBox2.ItemIndex =1 then
passwordid:=$2
else passwordid:=$1;
ctrlword:=$4;
status:=iso15693authkey(ctrlword,@uidbuf,passwordid,@authkeybuf);
case status of
0:
begin
pcdbeep(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);
var
ctrlword:byte;
passwordid:byte; //密钥类型
status:byte; //存放返回值
newkeybuf:array[0..3] of byte;
uidbuf:array[0..7] of byte; //UID
cardstr:string;
begin
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
if checkuidstr(Trim(Edit10.Text) ,4,newkeybuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('卡片新密钥输入错误,请输入8位16进制新密钥!', '提示', MB_OK+MB_ICONSTOP);
edit10.SetFocus ;
exit;
end;
if ComboBox2.ItemIndex =4 then
passwordid:=$10
else if ComboBox2.ItemIndex =3 then
passwordid:=$8
else if ComboBox2.ItemIndex =2 then
passwordid:=$4
else if ComboBox2.ItemIndex =1 then
passwordid:=$2
else passwordid:=$1;
ctrlword:=$4;
status:=iso15693writekey(ctrlword,@uidbuf,passwordid,@newkeybuf);
case status of
0:
begin
pcdbeep(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);
var
ctrlword:byte;
blockpoint,extprotectstatus:byte; //高低块分隔地址,配置值
status:byte; //存放返回值
uidbuf:array[0..7] of byte; //UID
cardstr:string;
begin
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
if(not isrightint(edit11.Text)) then
begin
Application.MessageBox('分隔高低块的块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);
edit11.SetFocus();
edit11.SelectAll();
exit;
end
else blockpoint:=strtoint(edit11.Text);
extprotectstatus:=ComboBox3.ItemIndex +ComboBox4.ItemIndex *16;
ctrlword:=$4;
status:=iso15693protectblock(ctrlword,@uidbuf,blockpoint,extprotectstatus);
case status of
0:
begin
pcdbeep(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);
var
ctrlword:byte;
status:byte; //存放返回值
password:array[0..3] of byte;
uidbuf:array[0..7] of byte; //UID
cardstr:string;
begin
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
if checkuidstr(Trim(Edit5.Text) ,4,password)=false then //检测数据是否合法并放入数组缓冲
begin
Application.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 of
0:
begin
pcdbeep(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);
var
i:byte;
status:byte;//存放返回值
flags:byte;//控制标志
startblock:byte; //起始扇区
blocknum:byte; //读扇区数
revlen:array[0..1] of byte; //长度
uidbuf:array[0..7] of byte;//UID
mypiccdata:array[0..60] of byte;//每次读卡数据缓冲
readbuf:array[0..8000] of byte;//全部卡数据缓冲
j,p:integer;
cardstr,carddatahex:string;
begin
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
edit9.Text :='22';
flags := strtoint('$'+edit9.Text);//操作标志
if(not isrightint(edit2.Text)) then
begin
Application.MessageBox('读写起始块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);
edit2.SetFocus();
edit2.SelectAll();
exit;
end
else startblock:=strtoint(edit2.Text);
if(not isrightint(edit3.Text)) then
begin
Application.MessageBox('读写块数输入错误!', '警告', MB_OK+MB_ICONSTOP);
edit3.SetFocus();
edit3.SelectAll();
exit;
end
else blocknum:=strtoint(edit3.Text );
memo1.Text :='';
j:=0;
carddatahex:='';
while j<blocknum do
begin
status := iso15693readblock(flags,startblock+j,1,@uidbuf,@revlen,@mypiccdata); //读一个块数据
if status=0 then //读卡成功,获取数据,指针加1
begin
for i:=0 to revlen[0]-1 do
carddatahex:=carddatahex+inttohex(mypiccdata[i],2)+' ';
j:=j+1;
end
else //读卡失败,指针跳到最后退出
j:=blocknum;
end;
if status=0 then
begin
pcdbeep(50);
memo1.Text:=carddatahex;
if revlen[0]=8 then //根据读一块返回的字节数预判是什么类型的卡
ComboBox1.ItemIndex:=1
else if revlen[0]=32 then
ComboBox1.ItemIndex:=2
else ComboBox1.ItemIndex:=0;
end
else if status=46 then
Application.MessageBox('请先认证相应的密码!', '提示', MB_OK+MB_ICONSTOP)
else
MessageDispInfo(status);
end;
六、写数据到块内
procedure TForm1.Button17Click(Sender: TObject);
var
i,j,p:integer;
status:byte; //存放返回值
flags:byte; //控制标志
startblock:byte; //起始扇区
blocknum:byte; //读扇区数
writelen:integer; //长度
uidbuf:array[0..7] of byte;//UID
writebuf:array[0..1024] of byte;//卡数据缓冲
mypiccdata:array[0..31] of byte;
writestr:string;
cardstr:string;
eachblocksize:integer;
begin
if ComboBox1.ItemIndex=0 then
eachblocksize:=4
else if ComboBox1.ItemIndex=1 then
eachblocksize:=8
else eachblocksize:=32;
cardstr:=trim(edit4.Text);
if checkuidstr(cardstr ,8,uidbuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要操作的卡片UID错误,可先执行寻卡操作获取UID!', '提示', MB_OK+MB_ICONSTOP);
edit4.SetFocus ;
exit;
end;
if(not isrightint(edit2.Text)) then
begin
Application.MessageBox('读写起始块地址输入错误!', '警告', MB_OK+MB_ICONSTOP);
edit2.SetFocus();
edit2.SelectAll();
exit;
end
else startblock:=strtoint(edit2.Text);
if(not isrightint(edit3.Text)) then
begin
Application.MessageBox('读写块数输入错误!', '警告', MB_OK+MB_ICONSTOP);
edit3.SetFocus();
edit3.SelectAll();
exit;
end
else blocknum:=strtoint(edit3.Text );
writelen:=blocknum*eachblocksize;
if checkuidstr(trim(Memo1.Text) ,writelen,writebuf)=false then //检测数据是否合法并放入数组缓冲
begin
Application.MessageBox('需要写入的数据输入错误,可先执行读卡操作!', '提示', MB_OK+MB_ICONSTOP);
Memo1.SetFocus ;
exit;
end;
edit9.Text :='22';
flags := strtoint('$'+edit9.Text);//操作标志
j:=0;
while j<blocknum do
begin
for 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 //写卡成功,指针加1
j:=j+1
else //写卡失败,指针跳到最后退出
j:=blocknum;
end;
if status=0 then
begin
pcdbeep(50);
Application.MessageBox(PAnsiChar(AnsiString(cardstr+' 号卡写卡成功!')), '提示', MB_OK+MB_ICONINFORMATION);
end
else if status=46 then
Application.MessageBox('请先认证相应的密码!', '提示', MB_OK+MB_ICONSTOP)
else MessageDispInfo(status);
end;