T5557卡是美国Atmel公司生产的多功能非接触式射频芯片卡,属于125KHz的低频卡,在国内有广大的应用市场,如很多酒店的门禁卡都是使用T5557卡。该芯片共有330bit(比特)的EPROM(分布为10个区块, 每个区块33bit)。0页的块0是被保留用于设置T5557操作模式的参数配置块。第0页第7块可以作用户数据块使用,也可以作为保护全部数据的密码(假如在配置块中启用密码功能的话),防止非法改写数据。 第1页的1、2块保存了出厂商信息及唯一出厂ID,只能读取不可更改。T5567、T5577是T5557的升级版。
通过修改T5557卡的参数配置块,可以将t5557卡模拟成ID卡及HID卡,所以被广泛地用于门禁卡的复制。
本示例使用的发卡器:T5557 T5567 T5577低频RFID读写器 EM4100 HID卡复制器 酒店门卡-淘宝网 (taobao.com)
一、函数声明
unit declaredll;
interface
//ID卡读卡
function idr_read(pserial:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//HID卡读卡
function hid_read(pserial:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//T5557卡写配置块
function t5557_init(ctrlword:byte;serial:pbyte;key:pbyte;configdata:pbyte;newkey:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//T5557卡读卡
function t5557_read(ctrlword:byte;serial:pbyte;key:pbyte;blockflag:pbyte;readdata:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//T5557卡写卡
function t5557_write(ctrlword:byte;serial:pbyte;key:pbyte;blockflag:pbyte;writedata:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//T5557卡改密码
function t5557_changekey(ctrlword:byte;serial:pbyte;oldkey:pbyte;newkey:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//用T5557卡制作ID卡(也就是EM4100及兼容卡)
function t5557_to4100(ctrlword:byte;serial:pbyte;oldkey:pbyte;newkey:pbyte;myuidbuf:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//用T5557卡制作HID卡
function t5557_tohid(ctrlword:byte;serial:pbyte;oldkey:pbyte;newkey:pbyte;myuidbuf:pbyte):byte;stdcall;external 'OUR_IDR.dll';
//驱动蜂鸣器函数声明
function idr_beep(xms:integer):byte;stdcall;external 'OUR_IDR.dll';
//读出设备序列编号函数声明
function pcdgetdevicenumber(pdevicenumber:pbyte):byte;stdcall;external 'OUR_IDR.dll';
const
//以下控制字的含义请查看本公司网站提供的动态库说明
NEEDSERIAL = $01; //需要只对指定系列号的卡操作
NEEDKEY = $02; //需要用密码认证
LOCKBIT = $04; //锁定配置块或数据块,仅对 t5557_init,t5557_write ,t5557_changekey函数有效
KEYENABLE = $08; //启用本卡的密码功能
RESETCARD = $10; //操作成功后重启卡片
implementation
end.
二、读取T5557卡块内数据
procedure TForm1.Button3Click(Sender: TObject);//读卡
var
j:integer;
status:byte;//存放返回值
myctrlword:byte;//控制字
oldpicckey:array[0..3] of byte;//密码
mypiccserial:array[0..5] of byte;//卡序列号
mypiccdata:array[0..49] of byte;//读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
mypiccblockflag:array[0..1] of byte;//指定读哪一块
strls:string;
strls1:string;
begin
myctrlword := $00; //NEEDSERIAL:需要只对指定系列号的卡操作,NEEDKEY:需要用密码认证,LOCKBIT:锁定块,KEYENABLE:启用本卡的密码功能
if CheckBox2.Checked then
begin//本次操作需要密码验证
oldpicckey[0] := StrToInt('$' + midstr(Edit5.Text,1,2));
oldpicckey[1] := StrToInt('$' + midstr(Edit5.Text,3,2));
oldpicckey[2] := StrToInt('$' + midstr(Edit5.Text,5,2));
oldpicckey[3] := StrToInt('$' + midstr(Edit5.Text,7,2));
myctrlword := myctrlword + NEEDKEY;
end;
if CheckBox3.Checked then
begin//仅操作指定卡号的卡
if(Length(Edit8.Text) < 12) then
begin
ShowMessage('卡号长度不足');
Edit8.SetFocus;
Exit;
end;
myctrlword := myctrlword + NEEDSERIAL;
//仅操作指定卡号的卡,6个字节卡号如下
mypiccserial[0] := StrToInt('$' + midstr(Edit8.Text,1,2));
mypiccserial[1] := StrToInt('$' + midstr(Edit8.Text,3,2));
mypiccserial[2] := StrToInt('$' + midstr(Edit8.Text,5,2));
mypiccserial[3] := StrToInt('$' + midstr(Edit8.Text,7,2));
mypiccserial[4] := StrToInt('$' + midstr(Edit8.Text,9,2));
mypiccserial[5] := StrToInt('$' + midstr(Edit8.Text,11,2));
end;
//操作块标志
//第0页的块
mypiccblockflag[0] := 0;
if chkP0B0.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 1;
end;
if chkP0B1.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 2;
end;
if chkP0B2.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 4;
end;
if chkP0B3.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 8;
end;
if chkP0B4.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 16;
end;
if chkP0B5.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 32;
end;
if chkP0B6.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 64;
end;
if chkP0B7.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 128;
end;
//第1页
mypiccblockflag[1] := 0;
if chkP1B1.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 2;
end;
if chkP1B2.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 4;
end;
if chkP1B3.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 8;
end;
if chkP1B4.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 16;
end;
status := t5557_read(myctrlword,@mypiccserial,@oldpicckey,@mypiccblockflag,@mypiccdata);
case status of
0:
begin
strls := '卡无线转输分频比[';
strls := strls + IntToStr(mypiccdata[0]);
strls := strls + '],卡号[';
strls1 := '';
for j := 0 to 5 do
begin
strls1 := strls1 + IntToHex(mypiccserial[j],2);
end;
strls := strls + strls1;
strls := strls + '],卡数据[';
strls1 := '';
for j := 0 to mypiccdata[1] - 1 do
begin
strls1 := strls1 + IntToHex(mypiccdata[2+j],2);
end;
strls := strls + strls1;
strls := strls + ']';
Memo2.Text := strls;
ShowMessage('读卡成功');
end;
8: ShowMessage('请将卡放在感应区');
2: ShowMessage('本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY');
3: ShowMessage('需要密码才能读卡,函数myctrlword要加入NEEDKEY');
5: ShowMessage('密码错误!');
23: ShowMessage('机器没连上,或驱动程序未安装!');
else ShowMessage('错误代码:' + IntToStr(status));
end;
end;
三、写数据到T5557卡内
procedure TForm1.Button1Click(Sender: TObject);//写卡
var
i,j:integer;
status:byte;//存放返回值
myctrlword:byte;//控制字
oldpicckey:array[0..3] of byte;//密码
mypiccserial:array[0..5] of byte;//卡序列号
mypiccdata:array[0..47] of byte;//写入数据缓冲:最多返回12个块的数据
mypiccblockflag:array[0..1] of byte;//指定写哪一块
strls:string;
strls1:string;
begin
myctrlword := $00; //NEEDSERIAL:需要只对指定系列号的卡操作,NEEDKEY:需要用密码认证,LOCKBIT:锁定块,KEYENABLE:启用本卡的密码功能
if CheckBox2.Checked then
begin//本次操作需要密码验证
oldpicckey[0] := StrToInt('$' + midstr(Edit5.Text,1,2));
oldpicckey[1] := StrToInt('$' + midstr(Edit5.Text,3,2));
oldpicckey[2] := StrToInt('$' + midstr(Edit5.Text,5,2));
oldpicckey[3] := StrToInt('$' + midstr(Edit5.Text,7,2));
myctrlword := myctrlword + NEEDKEY;
end;
if CheckBox3.Checked then
begin//仅操作指定卡号的卡
if(Length(Edit8.Text) < 12) then
begin
ShowMessage('卡号长度不足');
Edit8.SetFocus;
Exit;
end;
myctrlword := myctrlword + NEEDSERIAL;
//仅操作指定卡号的卡,6个字节卡号如下
mypiccserial[0] := StrToInt('$' + midstr(Edit8.Text,1,2));
mypiccserial[1] := StrToInt('$' + midstr(Edit8.Text,3,2));
mypiccserial[2] := StrToInt('$' + midstr(Edit8.Text,5,2));
mypiccserial[3] := StrToInt('$' + midstr(Edit8.Text,7,2));
mypiccserial[4] := StrToInt('$' + midstr(Edit8.Text,9,2));
mypiccserial[5] := StrToInt('$' + midstr(Edit8.Text,11,2));
end;
//操作块标志
j := 0;
//第0页的块
mypiccblockflag[0] := 0;
if chkP0B0.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 1;
Inc(j);
end;
if chkP0B1.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 2;
Inc(j);
end;
if chkP0B2.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 4;
Inc(j);
end;
if chkP0B3.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 8;
Inc(j);
end;
if chkP0B4.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 16;
Inc(j);
end;
if chkP0B5.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 32;
Inc(j);
end;
if chkP0B6.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 64;
Inc(j);
end;
if chkP0B7.Checked then
begin
mypiccblockflag[0] := mypiccblockflag[0] + 128;
Inc(j);
end;
//第1页
mypiccblockflag[1] := 0;
if chkP1B1.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 2;
Inc(j);
end;
if chkP1B2.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 4;
Inc(j);
end;
if chkP1B3.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 8;
Inc(j);
end;
if chkP1B4.Checked then
begin
mypiccblockflag[1] := mypiccblockflag[1] + 16;
Inc(j);
end;
if j = 0 then
begin
ShowMessage('请选择需要写入的块!');
Exit;
end;
//写卡数据准备
strls := Memo1.Text;
i := Length(strls);
i := i div 2;
if i < (j * 4) then
begin
ShowMessage('数据长度不足,请补足数据!');
Memo1.SelStart := Length(Memo1.Text);
Memo1.SetFocus;
Exit;
end;
for i := 0 to (j * 4 - 1) do
begin
mypiccdata[i] := StrToInt('$' + MidStr(strls,i*2+1,2)); //22232425 26272829
end;
status := t5557_write(myctrlword,@mypiccserial,@oldpicckey,@mypiccblockflag,@mypiccdata);
case status of
0:
begin
strls := '卡号[';
strls1 := '';
for i := 0 to 5 do
begin
strls1 := strls1 + IntToHex(mypiccserial[i],2);
end;
strls := strls + strls1;
strls := strls + ']';
Memo2.Text := strls;
ShowMessage('写卡成功');
end;
8: ShowMessage('请将卡放在感应区');
2: ShowMessage('本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY');
3: ShowMessage('需要密码才能写卡,函数myctrlword要加入NEEDKEY');
5: ShowMessage('密码错误!');
23: ShowMessage('机器没连上,或驱动程序未安装!');
else ShowMessage('错误代码:' + IntToStr(status));;
end;
end;
四、将T5557卡配置成ID卡、HID卡
procedure TForm1.Button7Click(Sender: TObject);//单次制卡(收费功能)
var
i,j:Integer;
cardnumber:int64;
myuidbuf:array[0..6] of byte;//ID卡序列号
status:byte;//存放返回值
myctrlword:byte;//控制字
oldpicckey:array[0..3] of byte;//密码
mypiccserial:array[0..5] of byte;//卡序列号
newpicckey:array[0..3] of byte;//新密码
strls:string;
strls1:string;
begin
//输入检查
//卡号
try
if RadioButton3.Checked then
begin//ID卡
if ComboBox5.ItemIndex = 1 then
begin//输入10位十进制码
if Length(Edit1.Text) < 10 then
begin
ShowMessage('卡号输入长度不足,必须为10位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
if(cardnumber > 4294967295) then
begin
ShowMessage('卡号的值不能超过4294967295');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
myuidbuf[4] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
end
else if ComboBox5.ItemIndex = 2 then
begin//输入韦根34码
if Length(Edit1.Text) < 10 then
begin
ShowMessage('卡号输入长度不足,必须为10位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(midstr(Edit1.Text,1,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG34卡号的前5位字符的值不能超过65535');
Edit1.SelStart := 1;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[2] := cardnumber;
cardnumber:= StrToInt64(midstr(Edit1.Text,6,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG34卡号的后5位字符的值不能超过65535');
Edit1.SelStart := 6;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[4] := cardnumber;
myuidbuf[3] := (cardnumber div 256);
end
else if ComboBox5.ItemIndex = 3 then
begin//输入韦根26码
if Length(Edit1.Text) < 8 then
begin
ShowMessage('卡号输入长度不足,必须为8位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(midstr(Edit1.Text,1,3));
if(cardnumber > 255) then
begin
ShowMessage('WG26卡号的前3位字符的值不能超过255');
Edit1.SelStart := 1;
Edit1.SelLength := 3;
Edit1.SetFocus;
Exit;
end;
myuidbuf[2] := cardnumber;
cardnumber:= StrToInt64(midstr(Edit1.Text,4,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG26卡号的后5位字符的值不能超过65535');
Edit1.SelStart := 4;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[4] := cardnumber;
myuidbuf[3] := (cardnumber div 256);
end
else
begin//输入10位十六进制码
if Length(Edit1.Text) < 10 then
begin
ShowMessage('卡号输入长度不足,必须为10位十六进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber := StrToInt64('$'+Edit1.Text);
myuidbuf[4] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
end;
end
else
begin//HID卡
if (ComboBox5.ItemIndex = 1) then
begin//输入10位十进制码
if Length(Edit1.Text) < 10 then
begin
ShowMessage('卡号输入长度不足,必须为10位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
if(cardnumber > 4294967295) then
begin
ShowMessage('卡号的值不能超过4294967295');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
myuidbuf[6] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[5] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[4] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[3] := cardnumber;
end
else if ComboBox5.ItemIndex = 2 then
begin//输入韦根34码
if Length(Edit1.Text) < 10 then
begin
ShowMessage('卡号输入长度不足,必须为10位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(midstr(Edit1.Text,1,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG34卡号的前5位字符的值不能超过65535');
Edit1.SelStart := 1;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[4] := cardnumber;
myuidbuf[3] := (cardnumber div 256);
cardnumber:= StrToInt64(midstr(Edit1.Text,6,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG34卡号的后5位字符的值不能超过65535');
Edit1.SelStart := 6;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[6] := cardnumber;
myuidbuf[5] := (cardnumber div 256);
end
else if ComboBox5.ItemIndex = 3 then
begin//输入韦根26码
if Length(Edit1.Text) < 8 then
begin
ShowMessage('卡号输入长度不足,必须为8位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(midstr(Edit1.Text,1,3));
if(cardnumber > 255) then
begin
ShowMessage('WG26卡号的前3位字符的值不能超过255');
Edit1.SelStart := 1;
Edit1.SelLength := 3;
Edit1.SetFocus;
Exit;
end;
myuidbuf[4] := cardnumber;
cardnumber:= StrToInt64(midstr(Edit1.Text,4,5));
if(cardnumber > 65535) then
begin
ShowMessage('WG26卡号的后5位字符的值不能超过65535');
Edit1.SelStart := 4;
Edit1.SelLength := 5;
Edit1.SetFocus;
Exit;
end;
myuidbuf[6] := cardnumber;
myuidbuf[5] := (cardnumber div 256);
end
else if ComboBox5.ItemIndex = 4 then
begin//输入4.3H6D码
if Length(Edit1.Text) < 6 then
begin
ShowMessage('卡号输入长度不足,必须为6位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
myuidbuf[6] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[5] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[4] := cardnumber mod 8;//只取低3个位
end
else if ComboBox5.ItemIndex = 5 then
begin//输入4H5D码
if Length(Edit1.Text) < 5 then
begin
ShowMessage('卡号输入长度不足,必须为5位十进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber:= StrToInt64(Edit1.Text);
if(cardnumber < 0) then
begin
ShowMessage('卡号的值不能为负数');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
myuidbuf[6] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[5] := cardnumber;
end
else
begin//输入12位十六进制码
if Length(Edit1.Text) < 11 then
begin
ShowMessage('卡号输入长度不足,必须为11位十六进制数值');
Edit1.SelStart := Length(Edit1.Text);
Edit1.SetFocus;
Exit;
end;
cardnumber := StrToInt64('$'+Edit1.Text);
myuidbuf[6] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[5] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[4] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[1] := cardnumber;
end;
if ComboBox2.ItemIndex = 0 then
begin//H10301(韦根26)
myuidbuf[0] := 26 - 2;//有效位bit
end
else if ComboBox2.ItemIndex = 1 then
begin//H10302(韦根37)
myuidbuf[0] := 37 - 2;//有效位bit
end
else if ComboBox2.ItemIndex = 2 then
begin//H10304(韦根37)
myuidbuf[0] := 37 - 2;//有效位bit
end
else if ComboBox2.ItemIndex = 3 then
begin//企业1000格式(韦根35)
myuidbuf[0] := 35 - 2;//有效位bit
end
else
begin
myuidbuf[0] := ComboBox2.ItemIndex + 4;//韦根10有效位bit为8位
end;
end;
except
ShowMessage('卡号输入错误,必须为没有负数的数字');
Edit1.SelectAll;
Edit1.SetFocus;
Exit;
end;
if RadioButton3.Checked then
begin//ID卡
try
//版本号
if Length(Edit10.Text) = 0 then
begin
ShowMessage('请先输入版本号,为0至15的数值');
Edit10.SetFocus;
Exit;
end;
if ComboBox5.ItemIndex = 0 then
begin
i := StrToInt('$'+ Edit10.Text);
end
else
begin
i := StrToInt(Edit10.Text);
end;
if i < 0 then
begin
ShowMessage('版本号不能为 负数');
Edit10.SelectAll;
Edit10.SetFocus;
Exit;
end;
if i > 15 then
begin
ShowMessage('版本号不能大于 15 ');
Edit10.SelectAll;
Edit10.SetFocus;
Exit;
end;
except
ShowMessage('版本号输入错误,必须为数字');
Edit10.SelectAll;
Edit10.SetFocus;
Exit;
end;
//客户代码
try
if Length(Edit11.Text) = 0 then
begin
ShowMessage('请先输入客户代码,为0至15的数值');
Edit11.SetFocus;
Exit;
end;
if ComboBox5.ItemIndex = 0 then
begin
j := StrToInt('$'+ Edit11.Text);
end
else
begin
j := StrToInt(Edit11.Text);
end;
if j < 0 then
begin
ShowMessage('客户代码不能为负数 ');
Edit11.SelectAll;
Edit11.SetFocus;
Exit;
end;
if j > 15 then
begin
ShowMessage('客户代码不能大于 15 ');
Edit11.SelectAll;
Edit11.SetFocus;
Exit;
end;
except
ShowMessage('客户代码输入错误,必须为数字');
Edit11.SelectAll;
Edit11.SetFocus;
Exit;
end;
myuidbuf[0] := i * 16 + j;
end;
if RadioButton3.Checked then
begin//ID卡
//前缀码
try
if ComboBox5.ItemIndex = 0 then
begin
if Length(Edit13.Text) = 0 then
begin
ShowMessage('请先输入前缀码,为十六进制00至FF的数值');
Edit13.SetFocus;
Exit;
end;
i := StrToInt('$'+ Edit13.Text);
end
else
begin
if Length(Edit13.Text) = 0 then
begin
ShowMessage('请先输入前缀码,为0至255的数值');
Edit13.SetFocus;
Exit;
end;
i := StrToInt(Edit13.Text);
end;
if i < 0 then
begin
ShowMessage('前缀码不能为负数 ');
Edit13.SelectAll;
Edit13.SetFocus;
Exit;
end;
if i > 255 then
begin
ShowMessage('前缀码不能大于 255 ');
Edit13.SelectAll;
Edit13.SetFocus;
Exit;
end;
except
ShowMessage('前缀码输入错误,必须为数字');
Edit13.SelectAll;
Edit13.SetFocus;
Exit;
end;
myuidbuf[1] := i;
end
else
begin//HID卡
if (ComboBox5.ItemIndex > 0) then
begin
//前缀码
try
if Length(Edit13.Text) = 0 then
begin
ShowMessage('请先输入前缀码,为十进制数值');
Edit13.SetFocus;
Exit;
end;
cardnumber := StrToInt64(Edit13.Text);
if cardnumber < 0 then
begin
ShowMessage('前缀码不能为负数 ');
Edit13.SelectAll;
Edit13.SetFocus;
Exit;
end;
if (ComboBox5.ItemIndex = 1) or (ComboBox5.ItemIndex = 2) then
begin//输入10位十进制码 或 输入韦根34码
myuidbuf[2] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[1] := cardnumber;
end
else if ComboBox5.ItemIndex = 3 then
begin//输入韦根26码
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[1] := cardnumber;
end
else if ComboBox5.ItemIndex = 4 then
begin//输入4.3H6D码
myuidbuf[4] := myuidbuf[4] + ((cardnumber mod 32) * 8);//只取高5个位
cardnumber := cardnumber div 32;
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[1] := cardnumber;
end
else if ComboBox5.ItemIndex = 5 then
begin//输入4H5D码
myuidbuf[4] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[3] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[2] := cardnumber;
cardnumber := cardnumber div 256;
myuidbuf[1] := cardnumber;
end;
except
ShowMessage('前缀码输入错误,必须为数字');
Edit13.SelectAll;
Edit13.SetFocus;
Exit;
end;
end;
end;
myctrlword := $00; //NEEDSERIAL:需要只对指定系列号的卡操作,NEEDKEY:需要用密码认证,LOCKBIT:锁定块,KEYENABLE:启用本卡的密码功能
if CheckBox2.Checked then
begin//本次操作需要密码验证
oldpicckey[0] := StrToInt('$' + midstr(Edit5.Text,1,2));
oldpicckey[1] := StrToInt('$' + midstr(Edit5.Text,3,2));
oldpicckey[2] := StrToInt('$' + midstr(Edit5.Text,5,2));
oldpicckey[3] := StrToInt('$' + midstr(Edit5.Text,7,2));
myctrlword := myctrlword + NEEDKEY;
end;
if CheckBox3.Checked then
begin//仅操作指定卡号的卡
if(Length(Edit8.Text) < 12) then
begin
ShowMessage('卡号长度不足');
Edit8.SetFocus;
Exit;
end;
myctrlword := myctrlword + NEEDSERIAL;
//仅操作指定卡号的卡,6个字节卡号如下
mypiccserial[0] := StrToInt('$' + midstr(Edit8.Text,1,2));
mypiccserial[1] := StrToInt('$' + midstr(Edit8.Text,3,2));
mypiccserial[2] := StrToInt('$' + midstr(Edit8.Text,5,2));
mypiccserial[3] := StrToInt('$' + midstr(Edit8.Text,7,2));
mypiccserial[4] := StrToInt('$' + midstr(Edit8.Text,9,2));
mypiccserial[5] := StrToInt('$' + midstr(Edit8.Text,11,2));
end;
if CheckBox14.Checked then
begin//修改卡号保护密码
newpicckey[0] := StrToInt('$' + midstr(Edit14.Text,1,2));
newpicckey[1] := StrToInt('$' + midstr(Edit14.Text,3,2));
newpicckey[2] := StrToInt('$' + midstr(Edit14.Text,5,2));
newpicckey[3] := StrToInt('$' + midstr(Edit14.Text,7,2));
myctrlword := myctrlword + KEYENABLE;
end
else
begin
newpicckey[0] := $00;
newpicckey[1] := $00;
newpicckey[2] := $00;
newpicckey[3] := $00;
end;
myctrlword := myctrlword + RESETCARD;//操作后重启卡片,否则在制卡后,需要拿开卡片重放才能成功读ID卡
if RadioButton3.Checked then
begin//ID卡
status := t5557_to4100(myctrlword,@mypiccserial,@oldpicckey,@newpicckey,@myuidbuf);
end
else
begin//HID卡
status := t5557_tohid(myctrlword,@mypiccserial,@oldpicckey,@newpicckey,@myuidbuf);
end;
case status of
0:
begin
strls := '卡号[';
strls1 := '';
for i := 0 to 5 do
begin
strls1 := strls1 + IntToHex(mypiccserial[i],2);
end;
strls := strls + strls1;
strls := strls + ']';
Memo2.Text := strls;
ShowMessage('写卡成功');
end;
8: ShowMessage('卡不在感应区或密码不正确');
2: ShowMessage('本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY');
3: ShowMessage('需要密码才能制卡,函数myctrlword要加入NEEDKEY');
5: ShowMessage('密码错误!');
23: ShowMessage('机器没连上,或驱动程序未安装!');
else ShowMessage('错误代码:' + IntToStr(status));;
end;
end;
五、T5557卡初始化
- 01、初始配置块取值:00 08 80 E8,表示AOR请求应答模式=0、PWD密码有效=0、MAXBLK自动发送最大块=7,无需密码可读卡,自动发送0页的1-7块;
- 02、配置块取值:00 08 82 F8,表示AOR应答模式=1、PWD密码有效=1,卡片为密码保护模式,需要认证密码才能读、写卡;
- 03、配置块取值:00 08 80 F8,表示AOR应答模式=0、PWD密码有效=1,读卡(自动发送)不需要密码,写卡要带密码操作。
procedure TForm1.Button6Click(Sender: TObject); //设定卡配置
var
status:byte;//存放返回值
myctrlword:byte;//控制字
oldpicckey:array[0..3] of byte;//密码
mypiccserial:array[0..5] of byte;//卡序列号
mypiccdata:array[0..3] of byte;//卡数据缓冲
newpicckey:array[0..3] of byte;//新密码
begin
myctrlword := $00; //NEEDSERIAL:需要只对指定系列号的卡操作,NEEDKEY:需要用密码认证,LOCKBIT:锁定块,KEYENABLE:启用本卡的密码功能
if CheckBox2.Checked then
begin//本次操作需要密码验证
oldpicckey[0] := StrToInt('$' + midstr(Edit5.Text,1,2));
oldpicckey[1] := StrToInt('$' + midstr(Edit5.Text,3,2));
oldpicckey[2] := StrToInt('$' + midstr(Edit5.Text,5,2));
oldpicckey[3] := StrToInt('$' + midstr(Edit5.Text,7,2));
myctrlword := myctrlword + NEEDKEY;
end
else
begin
newpicckey[0] := $00;
newpicckey[1] := $00;
newpicckey[2] := $00;
newpicckey[3] := $00;
end;
if CheckBox1.Checked then
begin//启用密码功能
newpicckey[0] := StrToInt('$' + midstr(Edit3.Text,1,2));
newpicckey[1] := StrToInt('$' + midstr(Edit3.Text,3,2));
newpicckey[2] := StrToInt('$' + midstr(Edit3.Text,5,2));
newpicckey[3] := StrToInt('$' + midstr(Edit3.Text,7,2));
myctrlword := myctrlword + KEYENABLE;
end
else
begin
newpicckey[0] := $00;
newpicckey[1] := $00;
newpicckey[2] := $00;
newpicckey[3] := $00;
end;
//配置值:
mypiccdata[0] := StrToInt('$' + midstr(Edit6.Text,1,2));
mypiccdata[1] := StrToInt('$' + midstr(Edit6.Text,3,2));
mypiccdata[2] := StrToInt('$' + midstr(Edit6.Text,5,2));
mypiccdata[3] := StrToInt('$' + midstr(Edit6.Text,7,2));
status := t5557_init(myctrlword,@mypiccserial,@oldpicckey,@mypiccdata,@newpicckey);
case status of
0: ShowMessage('操作成功');
8: ShowMessage('卡不在感应区或密码不正确');
1: ShowMessage('写入配置的值不正确,请重新写入');
2: ShowMessage('本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY');
3: ShowMessage('需要密码才能重新设定,函数myctrlword要加入NEEDKEY');
5: ShowMessage('密码错误!');
23: ShowMessage('机器没连上,或驱动程序未安装!');
else ShowMessage('错误代码:' + IntToStr(status));;
end;
end;