各位高手:
小弟初次接触IC卡,只看了一些参考书,晕!想请教一些问题,谢谢!(用敏华接触式读卡器)
1.向生产卡的供应商拿了几张卡,他告诉我已做了初始化,这是什么意思,我在一些参考书上关于IC卡的应用程序上也有初始化程序,这两者有区别吗?我拿了这些供应商提供的卡还需初始化吗?
2.书上说对卡的读写首先需要检验密码,连续几次密码错误,卡会烧掉,则密码供应商是否会提供(据说供应商不愿提供),在我编程的时候密码是否要写在程序中?
3.听说对数据的读写都是十六制的并且要知道地址,如何知道卡的具体地址数(听说是块操作,且每个块都要一次性写满,否则出错).
4.据说每次对卡的操作都要经过上下电的程序,这是什么意思?
总之,对ic卡的知识极度匮乏,各位费心了!这好象和计算机的读写方式不一样吧
小弟初次接触IC卡,只看了一些参考书,晕!想请教一些问题,谢谢!(用敏华接触式读卡器)
1.向生产卡的供应商拿了几张卡,他告诉我已做了初始化,这是什么意思,我在一些参考书上关于IC卡的应用程序上也有初始化程序,这两者有区别吗?我拿了这些供应商提供的卡还需初始化吗?
2.书上说对卡的读写首先需要检验密码,连续几次密码错误,卡会烧掉,则密码供应商是否会提供(据说供应商不愿提供),在我编程的时候密码是否要写在程序中?
3.听说对数据的读写都是十六制的并且要知道地址,如何知道卡的具体地址数(听说是块操作,且每个块都要一次性写满,否则出错).
4.据说每次对卡的操作都要经过上下电的程序,这是什么意思?
总之,对ic卡的知识极度匮乏,各位费心了!这好象和计算机的读写方式不一样吧
1、 M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63,存贮结构如下图所示:
块0 数据块 0
扇区0 块1 数据块 1
块2 数据块 2
块3 密码A 存取控制 密码B 控制块 3
块0 数据块 4
扇区1 块1 数据块 5
块2 数据块 6
块3 密码A 存取控制 密码B 控制块 7
∶ ∶ ∶
0 数据块 60
扇区15 1 数据块 61
2 数据块 62
3 密码A 存取控制 密码B 控制块 632、 第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。
3、 每个扇区的块0、块1、块2为数据块,可用于存贮数据。
数据块可作两种应用:
★ 用作一般的数据保存,可以进行读、写操作。
★ 用作数据值,可以进行初始化值、加值、减值、读值操作。
4、 每个扇区的块3为控制块,包括了密码A、存取控制、密码B。具体结构如下:
密码A(6字节) 存取控制(4字节) 密码B(6字节) 5、 每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:
块0: C10 C20 C30
块1: C11 C21 C31
块2: C12 C22 C32
块3: C13 C23 C33
三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权限(如
进行减值操作必须验证KEY A,进行加值操作必须验证KEY B,等等)。三个控制
位在存取控制字节中的位置,以块0为例:
对块0的控制:
bit 7 6 5 4 3 2 1 0
字节6 C20_b C10_b
字节7 C10 C30_b
字节8 C30 C20
字节9
( 注: C10_b表示C10取反 ) 存取控制(4字节,其中字节9为备用字节)结构如下所示:
bit 7 6 5 4 3 2 1 0
字节6 C23_b C22_b C21_b C20_b C13_b C12_b C11_b C10_b
字节7 C13 C12 C11 C10 C33_b C32_b C31_b C30_b
字节8 C33 C32 C31 C30 C23 C22 C21 C20
字节9
( 注: _b表示取反 ) 6、数据块(块0、块1、块2)的存取控制如下: 控制位(X=0.1.2) 访 问 条 件 (对数据块 0、1、2)
C1X C2X C3X Read Write Increment Decrement, transfer,Restore
0 0 0 KeyA|B KeyA|B KeyA|B KeyA|B
0 1 0 KeyA|B Never Never Never
1 0 0 KeyA|B KeyB Never Never
1 1 0 KeyA|B KeyB KeyB KeyA|B
0 0 1 KeyA|B Never Never KeyA|B
0 1 1 KeyB KeyB Never Never
1 0 1 KeyB Never Never Never
1 1 1 Never Never Never Never
(KeyA|B 表示密码A或密码B,Never表示任何条件下不能实现)
例如:当块0的存取控制位C10 C20 C30= 1 0 0时,验证密码A或密码B正确后可读;
验证密码B正确后可写;不能进行加值、减值操作。 7、控制块块3的存取控制与数据块(块0、1、2)不同,它的存取控制如下: 密码A 存取控制 密码B
C13 C23 C33 Read Write Read Write Read Write
0 0 0 Never KeyA|B KeyA|B Never KeyA|B KeyA|B
0 1 0 Never Never KeyA|B Never KeyA|B Never
1 0 0 Never KeyB KeyA|B Never Never KeyB
1 1 0 Never Never KeyA|B Never Never Never
0 0 1 Never KeyA|B KeyA|B KeyA|B KeyA|B KeyA|B
0 1 1 Never KeyB KeyA|B KeyB Never KeyB
1 0 1 Never Never KeyA|B KeyB Never Never
1 1 1 Never Never KeyA|B Never Never Never
例如:当块3的存取控制位C13 C23 C33= 0 0 1时,表示:
密码A:不可读,验证KEYA或KEYB正确后,可写(更改)。
存取控制:验证KEYA或KEYB正确后,可读、可写。
密码B:验证KEYA或KEYB正确后,可读、可写。新卡片中的控制字为:“FF 07 80 69”,其定义中说明密码A可用,密码B不可用,新卡中所有密码A都为6个字节的“FF”; 推荐的控制字
方案一:7F 07 88 69
此控制字说明:数据块:用密码A或B都可以读写;
控制块:密码A:由密码B来写,不可读;
密码B:由密码B来写,不可读;
控制字:用密码A或B都可读,由密码B写;
方案二:08 77 8F 69
此控制字说明:数据块:用密码A读,由密码B读写;
控制块:密码A:由密码B来写,不可读;
密码B:由密码B来写,不可读;
控制字:用密码A或B都可读,由密码B写;三、 卡片
卡片的电气部分只由一个天线和ASIC组成。
天线:卡片的天线是只有几组绕线的线圈,很适于封装到IS0卡片中。
ASIC:卡片的ASIC由一个高速(106KB波特率)的RF接口,一个控制单元和一个
8K位EEPROM组成。四、对数据块的操作
读 (Read):读一个块;
写 (Write):写一个块;
加(Increment):对数值块进行加值;
减(Decrement):对数值块进行减值;
存储(Restore):将块中的内容存到数据寄存器中;
传输(Transfer):将数据寄存器中的内容写入块中;
中止(Halt):将卡置于暂停工作状态;
2.书上说对卡的读写首先需要检验密码,连续几次密码错误,卡会烧掉,则密码供应商是否会提供(据说供应商不愿提供),在我编程的时候密码是否要写在程序中?
不会烧掉的。16个扇区,除了0扇区的密码不提供外,其他的都是12个f
3.听说对数据的读写都是十六制的并且要知道地址,如何知道卡的具体地址数(听说是块操作,且每个块都要一次性写满,否则出错).
这个不懂。
4.据说每次对卡的操作都要经过上下电的程序,这是什么意思?
这个也不懂。
总之,对ic卡的知识极度匮乏,各位费心了!这好象和计算机的读写方式不一样吧附资料,你看一下:http://baike.baidu.com/view/4189.htm
给你卡的供应商,应该不是生产商,可能是一些做卡应用行业的公司,他们拿给你的卡,并且说已初始化,则很可能是加密码了,只能他们自己的设备来使用。 haochin回答的正确,应该是供应商提前将卡内设置密码了,你在读写该卡时都需要用密码提前验证,因此你必须问供应商要到该密码。2.书上说对卡的读写首先需要检验密码,连续几次密码错误,卡会烧掉,则密码供应商是否会提供(据说供应商不愿提供),在我编程的时候密码是否要写在程序中?
确切的说如果密码多次错误,会导致卡锁死,倒不至于烧掉,当然卡锁死的话,也就不能再对该卡进行读写了。至于密码,是厂家自己定的出厂密码,肯定会告诉你的,否则你读写卡是无法通过密码验证,而且这个密码一般还允许自行设定,所以你编程的时候肯定要用的密码。
3.听说对数据的读写都是十六制的并且要知道地址,如何知道卡的具体地址数(听说是块操作,且每个块都要一次性写满,否则出错).
数据的读写一般是2进制或16进制,而是否需要知道地址,这个需要根据厂家提供的通讯协议来确定
4.据说每次对卡的操作都要经过上下电的程序,这是什么意思?
上下电是一次读写卡的操作步骤而已,你想象成开始,结束就行。比如一次读写卡的步骤是:上电,判断读卡器有卡,验证卡密码,读写卡数据,下电
前面的回答均是针对非接触式IC卡来的,但我看你用的应该是接触式的IC卡,应为你提到你用的是明华的接触式读写器。如果你用的是接触式的IC卡,那么答案应该就不一样了。
1:两种卡是一样的,初始化的意思应该是修改了原始的密码,也即是说已经写了新密码了
2:非接触式IC卡的密码可以随便校验,密码错了再试多少次也没有问题,但接触式的IC卡应该是试了N次后卡会被锁死的。如果你要对其编程,一般来说两种卡都需要知道密码。
3:读写卡要通知读写器我要读写哪个区那个块
4:卡内有芯片,存储了数据,没有电怎么读?只不过两种卡的电的来源不一样。一般明华的读写器都附带有很详细的说明,你可以看看说明。
答:初始化就是向IC卡里写入了认证密码(IC卡出厂的时候默认为空密码),对写入认证密码之后的IC卡读写,必须使用相同的密码认证,否则就无法对IC卡读写,应用程序的初始化应该是读卡器芯片的初始化吧。你拿的IC卡,发卡操作时读卡器就对IC卡进行了初始化。
2.书上说对卡的读写首先需要检验密码,连续几次密码错误,卡会烧掉,则密码供应商是否会提供(据说供应商不愿提供),在我编程的时候密码是否要写在程序中?
答:这个密码是读卡器和IC卡之间通讯的认证秘钥,如果供应商不原意提供,就是说读卡器初始化卡的时候写入了一个只有读卡器供应商知道的、固定的密码,你就不需要管这个密码了。如果读卡器厂商提供的应用接口可以改写这个密码,你就要管理起这个密码了。也就是初始化卡时你写入什么密码,你读写这些初始化过的卡时,必须使用相同的密码来认证。
3.听说对数据的读写都是十六制的并且要知道地址,如何知道卡的具体地址数(听说是块操作,且每个块都要一次性写满,否则出错).
答:卡存储分块,区。不同的卡容量不同,根据卡片类型对应处理。
4.据说每次对卡的操作都要经过上下电的程序,这是什么意思?
答:上电有点奇怪,如果卡片拿到了读卡器的射频区(读卡器通过固定频率如13.56M发射射频能量,通讯的编码调制在这个固定频率上),IC卡的线圈接收射频能量,可能就几个mS,IC卡的电路充电后就可以正常工作了,也就算是上电吧。IC卡的内容读写之前需要一系列的认证步骤。真正的下电就是把IC卡从读卡器的射频区移开。这里的下电可能是指IC卡的IDLE吧,IC卡休眠之后就不再响应读卡器的通讯请求了(当然如果从射频区移开,IC卡电路冷重启之后就可以相应请求了)。因为读卡器读卡是快速定时扫描的,比如1秒钟50次,如果你不休眠,可能会在你刷卡的一两秒钟之间,发生多次读写(可能就多次扣钱了,呵呵)。
timic,mifare卡结构不同,你只要知道卡结构怎么存储,一般读卡器供应商都给你写好了底层代码,你只要调用读写等命令就好了.
密码不对会烧掉的
(可以是我不懂),请指教.大致程序如下:
procedure TForm1.Button1Click(Sender: TObject);//读
begin
if edit1.Text='' then
begin
application.MessageBox('数据不能为空','');
exit;
end;
if Open_Card() then
if Write_card(pchar(edit1.Text)) then
if CLose_Card then
begin
end;
end;
procedure TForm1.Button2Click(Sender: TObject);//写 begin
If OPen_Card Then
begin
edit2.Text := Read_Card;
If Close_card Then
begin
Exit;
end;
end;
end;unit U_Card;
interface
{1} //打开设备,进行口令验正
function Open_Card():Boolean;
{2} // 关闭设备
function CLose_Card():boolean;
{3} // 写卡,对卡进行写操作
function Write_card(COntent:pchar):boolean;
{4}//对卡进行读操作
function Read_Card():string;
{5} //写卡时内容组织
function Content(aa:string):string;
{6}//卡片比效函数
function Card_Compare():boolean;
{7}//是否有卡片在驱动器里
function Check_card():Boolean;
implementation
uses u_public_define,dialogs,sysutils,StrUtils; {1} //打开设备,进行口令验正
function Open_Card():Boolean;
var
Status:integer;
aa:array[0..2]of char;
begin
// g_icdev:=auto_init(0,9600);
g_st:=setsc_md(g_icdev,1); aa:=chr(0)+chr(0)+chr(0);
// g_icdev:=auto_init(0,9600);
G_st := cmp_dvsc(G_icdev, 3, aa); G_st:=setsc_md(G_icdev, 0); G_st:=get_status(G_icdev, @Status);
If G_st < 0 Then
begin
showmessage('驱动器有错误!请检查设备后继续使用!');
OPen_Card:= False;
// G_st :=ic_exit(G_icdev);
Exit;
end;
OPen_Card := True;
end;
{2} // 关闭设备
function CLose_Card():boolean;
begin
G_st := ic_exit(G_icdev);
If G_st < 0 Then
begin
showmessage('关闭设备时有误,请重新启动系统');
close_card:=false;
exit;
end;
close_card:=true;
//
end;
{3} // 写卡,对卡进行写操作
function Write_card(COntent:pchar):boolean;
begin
G_st := swr_eeprom(G_icdev, 0, 384, Content);
If G_st <> 0 Then
begin
showmessage('写卡时出错,请检查后使用!');
Write_card := False;
exit;
end; Write_card:= True;
//
end;
{4}//对卡进行读操作
function Read_Card():string;
var
Cent:array[0..383] of char;
tent:array[0..383] of char;
I,j:integer;
DD:string;
begin
G_st:= srd_eeprom(G_icdev, 0, 383, Cent);
If G_st < 0 Then
begin
showmessage('读卡时出错,请检查后使用!');
Exit;
end;
For i := 0 To 383 do
begin
If i > 13 Then
begin
for j:=0 to 12 do
begin
dd:=dd+cent[j];
end;
Read_Card:= dd;
Exit;
end;
end;
end;
// {5} //写卡时内容组织
function Content(aa:string):string;
begin
//
end;
{6}//卡片比效函数
function Card_Compare():boolean;
begin
//
end;
{7}//
function check_card():boolean;
var
Status:integer;
aa:array[0..2]of char;
begin
status:=0;
G_st:=get_status(G_icdev, @Status); If Status =0 Then
begin
//showmessage('请插入卡后使用!');
check_Card:=False;
// G_st := ic_exit(G_icdev);
Exit;
End; check_Card := True;
end;end.
unit WriteIC4428_RemovingEndNum;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;type
TPCH_Write_IC_Card4428 = class(TForm)
rb_IsWriteMainCard: TRadioButton;
lst_ReadWriteInfo: TListBox;
rb_IsWriteAttachCard: TRadioButton;
grp__1: TGroupBox;
grp__2: TGroupBox;
lbl_1: TLabel;
lbl_2: TLabel;
lbl_3: TLabel;
grp__3: TGroupBox;
lbl_4: TLabel;
edt_CardPWD: TEdit;
lbl_5: TLabel;
edt_WritePosition_Byte: TEdit;
lbl_7: TLabel;
btn_OpenInterface: TBitBtn;
btn_VerifyCardPwd: TBitBtn;
btn_ReadCard: TBitBtn;
btn_ClearListBoxRec: TBitBtn;
btn_Exit: TBitBtn;
btn_WriteCard: TBitBtn;
edt_CardMainNo: TEdit;
edt_CardFirstNo: TEdit;
edt_AttachCardEndNo: TEdit;
grp__4: TGroupBox;
edt_WriteCardNum: TEdit;
lbl_6: TLabel;
btn_ChangeCardPWD: TBitBtn;
btn_ClosePort: TBitBtn;
procedure btn_OpenInterfaceClick(Sender: TObject);
procedure btn_VerifyCardPwdClick(Sender: TObject);
procedure btn_WriteCardClick(Sender: TObject);
procedure btn_ExitClick(Sender: TObject);
procedure btn_ReadCardClick(Sender: TObject);
procedure btn_ChangeCardPWDClick(Sender: TObject);
procedure btn_ClearListBoxRecClick(Sender: TObject);
procedure btn_ClosePortClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure edt_CardMainNoChange(Sender: TObject);
procedure edt_AttachCardEndNoChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
PCH_Write_IC_Card4428: TPCH_Write_IC_Card4428; ClickNum:Integer;
MainCardNum:string[10];
RW_MainCardNum:string[20];
RW2_MainCardNum:string[44];
RW2_AttachCardNum:string[48];
// ----------------------------------------------
icdev:longint;
st:smallint;
outbuff:pchar; //输出缓冲区_主卡
inbuff:string; //输入缓冲区implementation{$R *.dfm}uses drv_unit_D6;// 打开串口
procedure TPCH_Write_IC_Card4428.btn_OpenInterfaceClick(Sender: TObject);
begin
// ClickNum:=0;
icdev := IC_InitComm(100);
If icdev < 0 Then
begin
lst_ReadWriteInfo.Items.Add('打开端口出错!请检查端口是否被占用或设备是否已连接!');
exit;
end
else
begin
lst_ReadWriteInfo.Items.Add('打开端口成功!');
PCH_Write_IC_Card4428.btn_VerifyCardPwd.Enabled:=True;
PCH_Write_IC_Card4428.btn_WriteCard.Enabled:=True;
PCH_Write_IC_Card4428.btn_ReadCard.Enabled:=True;
PCH_Write_IC_Card4428.btn_ChangeCardPWD.Enabled:=True;
PCH_Write_IC_Card4428.btn_ClosePort.Enabled:=True;
end; st := IC_Status(icdev);
If st <0 Then begin
lst_ReadWriteInfo.Items.Add('读写器存在错误!');
exit;
end;
lst_ReadWriteInfo.Items.Add('读写器状态正常!'); If st >0 Then
If st = 1 then
begin
Windows.Beep(300,600);
lst_ReadWriteInfo.Items.Add('>>>>>>>>>>>没有检测到卡,请重新插卡!');
st := IC_ExitComm(icdev); //关闭串口
icdev:=0;
end
else
lst_ReadWriteInfo.Items.Add('检测到卡!'); st := IC_InitType(icdev, 4); //给卡型号
If st = 0 Then
begin
lst_ReadWriteInfo.Items.Add('卡型检测成功!');
Exit;
End
else
lst_ReadWriteInfo.Items.Add('卡型检测失败!');
end;//校验密码
procedure TPCH_Write_IC_Card4428.btn_VerifyCardPwdClick(Sender: TObject);
begin
st := IC_ReadCount_SLE4428(icdev);
If st < 0 Then begin
lst_ReadWriteInfo.Items.Add('读芯片SLE4428、4442出错!');
Exit;
End; lst_ReadWriteInfo.Items.Add('读芯片SLE4428、4442成功!');
lst_ReadWriteInfo.Items.Add('错误记数器为'+inttostr(st)); inbuff:=string(edt_CardPWD.Text); //核对密码
st := IC_CheckPass_4428hex(icdev,pchar(inbuff));
If st <> 0 Then begin
lst_ReadWriteInfo.Items.Add('密码校验失败!');
Exit;
End;
lst_ReadWriteInfo.Items.Add('密码校验成功!');
end;
// 写卡
procedure TPCH_Write_IC_Card4428.btn_WriteCardClick(Sender: TObject);
var CardMain_temp:string[6];
CardMainNo:string[6];
CardFirstNo:string[4];
CardEndNo:string[2];
M_WriteCardNum:string[22];
A_WriteCardNum:string[24];
begin
CardMain_temp:=IntToStr(StrToInt(edt_CardMainNo.Text)+ClickNum);
if Length(CardMain_temp)=1 then
CardMainNo:='00000'+string(CardMain_temp)
else
begin
if Length(CardMain_temp)=2 then
CardMainNo:='0000'+string(CardMain_temp)
else
begin
if Length(CardMain_temp)=3 then
CardMainNo:='000'+string(CardMain_temp)
else
begin
if Length(CardMain_temp)=4 then
CardMainNo:='00'+string(CardMain_temp)
else
begin
if Length(CardMain_temp)=5 then
CardMainNo:='0'+string(CardMain_temp)
else
CardMainNo:=string(CardMain_temp);
end;
end;
end;
end; CardFirstNo:=Copy(string(edt_CardFirstNo.Text),1,2)+copy(edt_CardFirstNo.Text,3,2);
CardEndNo:=Copy(string(edt_AttachCardEndNo.Text),1,1)+copy(edt_AttachCardEndNo.Text,2,1); MainCardNum:=string(CardFirstNo)+string(CardMainNo);
M_WriteCardNum:=Copy(MainCardNum,1,2)+'YN'+copy(MainCardNum,5,10)+' '+
Copy(MainCardNum,1,2)+'YN'+copy(MainCardNum,5,10);
A_WriteCardNum:=string(M_WriteCardNum)+string(CardEndNo); inbuff:=string(edt_CardPWD.Text); //核对密码
st := IC_CheckPass_4428hex(icdev,pchar(inbuff));
If st <> 0 Then begin
lst_ReadWriteInfo.Items.Add('密码校验失败!');
Exit;
End;
lst_ReadWriteInfo.Items.Add('密码校验成功!'); if rb_IsWriteMainCard.Checked then
begin RW_MainCardNum:='3'+copy(MainCardNum,1,1)+'3'+copy(MainCardNum,2,1)+'59'+'4e'+'3'
+copy(MainCardNum,5,1)+'3'+copy(MainCardNum,6,1)+'3'
+copy(MainCardNum,7,1)+'3'+copy(MainCardNum,8,1)+'3'+copy(MainCardNum,9,1)+'3'
+copy(MainCardNum,10,1); RW2_MainCardNum:=string(RW_MainCardNum)+'20'+'20'+string(RW_MainCardNum);
inbuff:=RW2_MainCardNum; st := IC_Write_hex(icdev, StrToInt(edt_WritePosition_Byte.Text),22,pchar(inbuff)); //写主卡数据
st := IC_Status(icdev);
If st <> 0 Then begin
Windows.Beep(300,600);
ShowMessage('写卡失败,请确认是否正确插入卡,或重新插卡!');
lst_ReadWriteInfo.Items.Add('>>>>>>>>>>>>>>>>>>>>写入失败的主卡号为:'+string(M_WriteCardNum));
Exit;
End;
lst_ReadWriteInfo.Items.Add('成功写入主卡号:'+string(M_WriteCardNum));
ClickNum:=ClickNum+1;
edt_WriteCardNum.Text:=string(M_WriteCardNum);
end
else
begin
if rb_IsWriteAttachCard.Checked then
begin
RW_MainCardNum:='3'+copy(MainCardNum,1,1)+'3'+copy(MainCardNum,2,1)+'59'+'4e'+'3'
+copy(MainCardNum,5,1)+'3'+copy(MainCardNum,6,1)+'3'
+copy(MainCardNum,7,1)+'3'+copy(MainCardNum,8,1)+'3'+copy(MainCardNum,9,1)+'3'
+copy(MainCardNum,10,1);
RW2_MainCardNum:=string(RW_MainCardNum)+'20'+'20'+string(RW_MainCardNum); RW2_AttachCardNum:=RW2_MainCardNum+'3'+copy(CardEndNo,1,1)+'3'+copy(CardEndNo,2,1);;
inbuff:=RW2_AttachCardNum;
st := IC_Write_hex(icdev, StrToInt(edt_WritePosition_Byte.Text),24,pchar(inbuff)); // 写副卡数据
If st <> 0 Then
begin
Windows.Beep(300,600);
ShowMessage('写卡失败,请确认是否正确插入卡,或重新插卡!');
lst_ReadWriteInfo.Items.Add('>>>>>>>>>>>>>>>>>写入失败的副卡号为:'+string(A_WriteCardNum));
Exit;
end;
lst_ReadWriteInfo.Items.Add('成功写入副卡号:'+string(A_WriteCardNum));
ClickNum:=ClickNum+1;
edt_WriteCardNum.Text:=string(A_WriteCardNum);
End;
end;
end;
// 读卡号
procedure TPCH_Write_IC_Card4428.btn_ReadCardClick(Sender: TObject);
var READ_MainCardNum:string[28];
READ_AttachCardNum:string[32];
begin
if rb_IsWriteMainCard.Checked then
begin
getmem(outbuff,60);
st := IC_Read_hex(icdev, StrToInt(edt_WritePosition_Byte.Text),22,outbuff); //读主卡卡号
READ_MainCardNum:=copy(outbuff,2,1)+copy(outbuff,4,1)+copy(outbuff,5,2)+copy(outbuff,7,2)
+copy(outbuff,10,1)+copy(outbuff,12,1)+copy(outbuff,14,1)+copy(outbuff,16,1)
+copy(outbuff,18,1)+copy(outbuff,20,1)+' '+copy(outbuff,26,1)+copy(outbuff,26,1)
+copy(outbuff,29,2)+copy(outbuff,31,2)+copy(outbuff,34,1)+copy(outbuff,36,1)
+copy(outbuff,38,1)+copy(outbuff,40,1)+copy(outbuff,42,1)+copy(outbuff,44,1);
If st <> 0 Then
begin
Windows.Beep(300,600);
ShowMessage('读主卡卡号失败,请确认是否正确插入卡,或重新插卡!');
lst_ReadWriteInfo.Items.Add('读主卡卡号失败!');
freemem(outbuff);
Exit;
end
else
begin
lst_ReadWriteInfo.Items.Add('读主卡成功!');
outbuff[44]:=chr(0);
lst_ReadWriteInfo.Items.Add('>>>>>>>>>>>>数据为:'+READ_MainCardNum);
end;
end; if rb_IsWriteAttachCard.Checked then
begin
getmem(outbuff,60);
st := IC_Read_hex(icdev, StrToInt(edt_WritePosition_Byte.Text),24,outbuff); //读副卡卡号
READ_AttachCardNum:=copy(outbuff,2,1)+copy(outbuff,4,1)+copy(outbuff,5,2)+copy(outbuff,7,2)
+copy(outbuff,10,1)+copy(outbuff,12,1)+copy(outbuff,14,1)+copy(outbuff,16,1)
+copy(outbuff,18,1)+copy(outbuff,20,1)+' '+copy(outbuff,26,1)+copy(outbuff,26,1)
+copy(outbuff,29,2)+copy(outbuff,31,2)+copy(outbuff,34,1)+copy(outbuff,36,1)
+copy(outbuff,38,1)+copy(outbuff,40,1)+copy(outbuff,42,1)+copy(outbuff,44,1)
+copy(outbuff,46,1)+copy(outbuff,48,1);
If st <> 0 Then
begin
Windows.Beep(300,600);
ShowMessage('读副卡卡号失败,请确认是否正确插入卡,或重新插卡!');
lst_ReadWriteInfo.Items.Add('读副卡卡号失败!');
freemem(outbuff);
Exit;
end
else
begin
lst_ReadWriteInfo.Items.Add('读副卡成功!');
outbuff[48]:=chr(0);
lst_ReadWriteInfo.Items.Add('>>>>>>>>>>>>数据为:'+READ_AttachCardNum);
end;
end;
end;//修改密码
procedure TPCH_Write_IC_Card4428.btn_ChangeCardPWDClick(Sender: TObject);
begin
inbuff:=string(edt_CardPWD.Text);
st := IC_ChangePass_4428hex(icdev,pchar(inbuff)); //修改密码
If st <> 0 Then begin
lst_ReadWriteInfo.Items.Add('修改密码失败!');
Exit;
End;
lst_ReadWriteInfo.Items.Add('修改密码成功!');
lst_ReadWriteInfo.Items.Add('卡密码改为'+string(edt_CardPWD.Text));
lst_ReadWriteInfo.Items.Add('读写设备测试通过!');
end;
// 清除记录
procedure TPCH_Write_IC_Card4428.btn_ClearListBoxRecClick(Sender: TObject);
begin
lst_ReadWriteInfo.Items.Clear;
end;
// 仅关闭串口
procedure TPCH_Write_IC_Card4428.btn_ClosePortClick(Sender: TObject);
begin
if icdev>0 then
begin
st := IC_ExitComm(icdev); //关闭串口
icdev:=0;
PCH_Write_IC_Card4428.btn_VerifyCardPwd.Enabled:=False;
PCH_Write_IC_Card4428.btn_WriteCard.Enabled:=False;
PCH_Write_IC_Card4428.btn_ReadCard.Enabled:=False;
PCH_Write_IC_Card4428.btn_ChangeCardPWD.Enabled:=False;
PCH_Write_IC_Card4428.btn_ClosePort.Enabled:=False;
lst_ReadWriteInfo.Items.Add('关闭串口成功!');
end;
end;//退出,关闭串口
procedure TPCH_Write_IC_Card4428.btn_ExitClick(Sender: TObject);
begin
close;
if icdev>0 then
begin
st := IC_ExitComm(icdev); //关闭串口
icdev:=0;
end;
freemem(outbuff);
end;procedure TPCH_Write_IC_Card4428.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if icdev>0 then
begin
st := IC_ExitComm(icdev); //关闭串口
icdev:=0;
end;
freemem(outbuff);
Action:=caFree;
end;procedure TPCH_Write_IC_Card4428.edt_CardMainNoChange(Sender: TObject);
begin
ClickNum:=0;
end;procedure TPCH_Write_IC_Card4428.edt_AttachCardEndNoChange(
Sender: TObject);
begin
ClickNum:=0;
end;end.
但密码检验通不过,打开源程序,发现程序中设的密码值为'B62307',IC卡出厂的密码为'FFFFFF',再通过DEMO程序将IC卡密码改为'B72307',到程序中测试通过(中间好几次折腾),但现在出现读操作通过,写操作出错,并且提示'rsct ok count=0',打开源程序,是通过下列语句所得
counter:=0;
st:=rsct_4442(icdev,@counter);
这是否意味卡已锁死?
CSC OK',为何?请教大佬