1、 读写S50 IC卡注意事项
S50 IC卡共分为 16个扇区,每个扇区有4个块;
其中 每个扇区的 1、2、3 是可写的,每块可写16个字符。
第一扇区的1、2、3块为保留(或许)区块。第4块不可动
所以,真正写入数据,是从第2个扇区开始,,每个扇区只写前3块;当然,第4块也不是不可能,但是,为防止写废卡。请跳过他;
完整源代码:
unit RY_ReadWriteICCard;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls,StrUtils;
type
Tfrm_ReadWriteICCard = class(TForm)
Panel1: TPanel;
LB_Msg1: TLabel;
btn_WriteCard: TButton;
lst_1: TListBox;
ED_1: TEdit;
ED_2: TEdit;
Btn_ReadCard: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btn_WriteCardClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Btn_ReadCardClick(Sender: TObject);
private
{ Private declarations }
icdev: longint;
snr:longint;
{nkey,}wdata,sendblock:pchar;
st,sector,block,loadmode:smallint;
status:Array[0..18]of Char;
databuff:Array[0..15]of Char;
ack:Array[0..255]of Char;
RY_Info :TStringList;
procedure SendMessageToLBMsg(const MSG:string;AAbort:Boolean =true;Cl:TColor = clRed);
procedure Load_ZZRK_Info;
public
{ Public declarations }
RY_BH :string;
end;
const
nkey ='ffffffffffff';
MKBH :string = 'RY0180';
var
frm_ReadWriteICCard: Tfrm_ReadWriteICCard;
implementation
uses rfexamp, DataModule, global;
{$R *.dfm}
Function Trans(Msg: string): string;
var
TempPchar: Pchar;
i: integer;
Str: string;
begin
TempPchar := Pchar(Msg); //将字符串 Char数组化
i := 0;
Str := '';
while i < length(TempPchar) do begin
Str := TempPchar[i] + TempPchar[i+1]+ Str ;
i := i + 2;
end;
result := Str;
end;
procedure Tfrm_ReadWriteICCard.Btn_ReadCardClick(Sender: TObject);
var
i:Integer;
s,tmp : string;
L:TStringList;
begin
DM.PubF_CheckPermissions(MKBH + '20');
snr:=0;
sector:=0;
block:=4;
loadmode:=0;
// nkey:='ffffffffffff';
L:=TStringList.Create;
try
st:=rf_card(icdev,1,@snr);
if st<>0 then
lst_1.items.add('card snr error')
else
lst_1.items.add('card snr Ok:'+Trans(format('%x',[snr])));
block := 4;
sector:= 0;
s := '';
tmp :='';
for i := 0 to 62 do begin
if i mod 4 =0 then begin
sector:= sector + 1;
st:=rf_load_key_hex(icdev,loadmode,sector, nkey);
if st<>0 then
lst_1.items.add('load key error ')
else
lst_1.items.add('load key Ok');
st:=rf_authentication(icdev,loadmode,sector);
if st<>0 then
lst_1.items.add('authentication error')
else
lst_1.items.add('authentication Ok');
end;
if (block mod 4 =3 ) then begin
lst_1.items.add('跳过第4块 ');
end else begin
st:=rf_read(icdev,block,@databuff);
if st<>0 then
lst_1.items.add('read error')
else begin
lst_1.items.add('read Ok:'+databuff);
tmp := databuff;
end;
s := s + tmp;
if Trim(tmp)>'' then
if tmp[Length(tmp)]='*' then Break;
end;
block := block + 1;
end;
s := Copy(s,1,Length(s)-1);
ED_2.Text := s ;
st:=rf_halt(icdev);
if st<>0 then
lst_1.items.add('halt error')
else
lst_1.items.add('halt Ok');
st:=rf_reset(icdev,10);
if st<>0 then
lst_1.items.add('reset error')
else
lst_1.items.add('reset OK');
lst_1.items.add('-----------------------------------');
L.Delimiter :='|';
L.DelimitedText := Decc(s);
for i := 0 to L.Count - 1 do
lst_1.Items.Add(L.Strings[i]);
finally
FreeAndNil(L);
end;
end;
procedure Tfrm_ReadWriteICCard.btn_WriteCardClick(Sender: TObject);
var
value:longint;
i:Integer;
s,tmp : string;
L:TStringList;
begin
DM.PubF_CheckPermissions(MKBH + '10');
snr:=0;
sector:=0;
block:=4;
loadmode:=0;
// nkey:='ffffffffffff';
L:=TStringList.Create;
try
st:=rf_card(icdev,1,@snr);
if st<>0 then
lst_1.items.add('card snr error')
else
lst_1.items.add('card snr Ok:'+Trans(format('%x',[snr])));
s :='';
for I := 0 to RY_Info.Count - 1 do
s :=s + RY_Info.Strings[i]+'|';
s := Encc(s) +'*';
ED_1.Text := s;
L.Clear;
for i := 0 to (Length(s) div 16) do begin
if (i mod 3=0) and (i <>0) then L.Add('');
L.Add(Copy(s,I*16+1,16));
end;
ShowMessage(L.Text);
lst_1.items.add('-------------开始写------------------ ') ;
for i := 0 to L.Count - 1 do begin
if i mod 4 =0 then begin
sector:= sector + 1;
st:=rf_load_key_hex(icdev,loadmode,sector, nkey);
if st<>0 then
lst_1.items.add('load key error ')
else
lst_1.items.add('load key Ok');
st:=rf_authentication(icdev,loadmode,sector);
if st<>0 then
lst_1.items.add('authentication error')
else
lst_1.items.add('authentication Ok');
end;
tmp := L.Strings[i];
if Trim(tmp)<>'' then begin
wdata := PChar(tmp);
st:=rf_write(icdev,block,wdata);
if st<>0 then
lst_1.items.add('write error -- '+wdata )
else
lst_1.items.add('write Ok -- '+ wdata +' 次:'+ IntToStr(i+1));
end ;
// else
// lst_1.items.add('跳过第4块 ');
block := block + 1;
end;
st:=rf_halt(icdev);
if st<>0 then
lst_1.items.add('halt error')
else
lst_1.items.add('halt Ok');
st:=rf_reset(icdev,60);
if st<>0 then
lst_1.items.add('reset error')
else
lst_1.items.add('reset OK');
lst_1.Items.Add('*************************************');
finally
FreeAndNil(L);
end;
end;
procedure Tfrm_ReadWriteICCard.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
st:=rf_exit(icdev);
end;
procedure Tfrm_ReadWriteICCard.FormCreate(Sender: TObject);
begin
btn_WriteCard.Enabled :=false;
Btn_ReadCard.Enabled :=false;
ED_2.Clear;
ED_1.Clear;
end;
procedure Tfrm_ReadWriteICCard.FormShow(Sender: TObject);
begin
Load_ZZRK_Info;
lst_1.Items := RY_Info;
icdev:=rf_init(0,115200); //串口1 波特率115200
if icdev<=0 then SendMessageToLBMsg('初化始设置失败');
st:=rf_get_status(icdev,@status);
if st<>0 then SendMessageToLBMsg('初化始设置失败');
SendMessageToLBMsg('Hard Ver: '+ status,False,clGreen);
st:=rf_load_key_hex(icdev,loadmode,sector, nkey);
if st<>0 then SendMessageToLBMsg('载入KEY错误');
btn_WriteCard.Enabled :=True;
Btn_ReadCard.Enabled :=True;
end;
procedure Tfrm_ReadWriteICCard.Load_ZZRK_Info;
begin
if not Assigned(RY_Info) then
RY_Info :=TStringList.Create;
RY_Info.Clear;
with dm.qry1 do begin
Close;
SQL.Text :='select * from RY_ZZRKDJ where BDBH='''+RY_BH+'''';
Open;
if not IsEmpty then begin
RY_Info.Add('RYBH='+fieldbyname('BDBH').AsString);
RY_Info.Add('XM='+fieldbyname('XM').AsString);
RY_Info.Add('SFZHM='+fieldbyname('SFZHM').AsString);
RY_Info.Add('XB='+fieldbyname('XB').AsString);
RY_Info.Add('MZ='+fieldbyname('MZ').AsString);
RY_Info.Add('CYM='+fieldbyname('XM').AsString);
RY_Info.Add('HJDXZ='+fieldbyname('HJDXZ').AsString);
RY_Info.Add('LBDRQ='+formatdatetime('yyyy-mm-dd',fieldbyname('LBDRQ').AsDateTime));
end else
ShowErrorMsg('没有找到相关人员',false);
Close;
end;
end;
procedure Tfrm_ReadWriteICCard.SendMessageToLBMsg(const MSG: string;
AAbort: Boolean;Cl:TColor );
begin
LB_Msg1.Caption := MSG ;
LB_Msg1.Font.Color := Cl;
if AAbort then Abort;
end;
end.
2、对图片的缩放
打印IC的界面,可能原始保存的图片太大,需要缩小到指定大小;
(将image1 的图片缩放到 Image2中)
Img_2.Canvas.StretchDraw(Img_2.ClientRect,Img_1.Picture.Graphic);
3、对图片的270度的旋转;
专门的IC卡面打印机,都是纵向打印的,显示将图片旋转
var x,y : Integer;
TmpBitMap : TBitmap;
begin
img_3.Picture.Assign(img_2.Picture);
TmpBitMap := TBitmap.Create;
try
TmpBitMap.Assign(Img_3.Picture.Graphic);
with Img_3 do begin
Picture.Bitmap.Height := TmpBitMap.Width;
Picture.Bitmap.Width := TmpBitMap.Height;
for x:=0 to Width do
for y:=0 to Height do
Canvas.Pixels[TmpBitMap.Height-x,y] := TmpBitMap.Canvas.Pixels[y,x];
Height := TmpBitMap.Width;
Width := TmpBitMap.Height;
end;
finally
TmpBitMap.Free;
end;