Delphi复制HID、ID门禁卡源码

news2024/12/26 23:32:35

        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卡初始化

  1. 01、初始配置块取值:00 08 80 E8,表示AOR请求应答模式=0、PWD密码有效=0、MAXBLK自动发送最大块=7,无需密码可读卡,自动发送0页的1-7块;
  2. 02、配置块取值:00 08 82 F8,表示AOR应答模式=1、PWD密码有效=1,卡片为密码保护模式,需要认证密码才能读、写卡;
  3. 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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模电学习3. MCU接三极管开关电路简单分析

模电学习3. MCU接三极管开关电路简单分析一、说明二、使用NPN型三极管工作状态分析1. 饱和状态基本要求2. 计算限流电阻R23. IbI_bIb​4. 计算 RbR_bRb​5. 下拉电阻三、使用PNP型三极管工作状态分析1. 示例原理图2. IO输出低电平3. IO输出高电平一、说明 本文演示了一个使用M…

adb调试工具-笔记

adb调试工具adb工具可以在电脑通过终端命令操作安卓手机/模拟器命令&#xff1a;adb shell dumpsys window windows | findstr mFocusedApp该命令是查找程序的包名和界面名让我们打开夜神模拟器&#xff0c;并打开设置界面然后在电脑打开命令行&#xff0c;输入上述查询命令传送…

小红书数据分析网站:2023年如何产出爆文(纯干货分享)

导语&#xff1a; 不懂小红书最近火热的赛道、总是错过爆款打造的节奏……2023年了&#xff0c;相信不少人会发现关于小红书营销种草投放&#xff0c;入门容易&#xff0c;做好难。本文将借助第三方工具为品牌锚定赛道&#xff0c;寻找新风向。 1、行业流量大盘 —— 实时掌握…

Android 进程保活(一)

最近公司项目需求&#xff0c;需要给应用加入进程保活。 这里简述一下需求&#xff0c;由于App应用对接了蓝牙接收实时数据&#xff0c;并且数据量很大&#xff1b; 用户在操作App获取实时数据的时候&#xff0c;不可能一直看着手机屏幕&#xff0c; 这时候手机一般会有黑屏或者…

freertos学习之路1-裸机和rtos的区别

写在最前 由于工作需要&#xff0c;需要开始学习freertos的相关知识&#xff0c;本专题主要记录freertos的相关内容 参考&#xff1a; https://www.bilibili.com/video/BV19g411p7UT 正点原子视频 1. 裸机和rtos的多任务处理 试想一种场景&#xff0c;我们正在打游戏&#xff0…

java基础巩固-宇宙第一AiYWM:为了维持生计,大数据之ElasticSearch【ElasticSearch的概念、关于文档、索引的命令】~整起

ElasticSearch一、ElasticSearch基本概念1.ElasticSearch是什么&#xff1f;从哪来、来干啥&#xff1f;2.ElasticSearch与Solr的对比与选型&#xff1a;3.ES核心概念及相关操作4.ELK&#xff1a;拆箱即用的技术&#xff0c;解压完成就能用5.IK分词器6.ElasticSearch与SpringBo…

字节跳动青训营--前端day6

文章目录前言一、React的历史和应用二、React的设计思路1. ui编程痛点 & 对React的期望2. 组件化3.状态归属问题4. 生命周期三、React&#xff08;hooks&#xff09;1.Virtual DOM(虚拟 DOM)&#xff1a;2. diff算法四、React状态管理库五、应用级框架科普前言 仅以此文章…

spark 内存管理机制与相关参数调优

spark 内存管理 文章目录spark 内存管理spark 1.6 内存管理机制spark 2.0 内存管理机制spark 3.3.1 官方文档spark 内存相关参数调优spark 1.6 内存管理机制 https://0x0fff.com/spark-memory-management 统一内存管理 Spark 1.6 之后引入的统一内存管理机制&#xff0c;与静…

SpringbootAdmin:轻量级的Springboot监控组件,用过的都说好

简介 Springboot Admin是一个管理和监控Springboot项目的组件&#xff0c;分为服务端和客户端&#xff0c;两端通过http进行通信。由于其轻量级的特性&#xff0c;所以特别适合中小项目使用。 其效果图如下&#xff1a; 服务端配置 1&#xff0c;引入Springboot admin和Spri…

3.5 异常

1.概述 异常是一些用来封装错误信息的对象 它由异常的类型、提示信息、报错的行号提示三部分组成 2.异常的继承结构 3.异常的处理方式 当程序中遇到了异常,通常有两种处理方式:捕获或者向上抛出 当一个方法抛出异常,调用位置可以不做处理继续向上抛出,也可以捕获处理异常 大…

简单使用OpenGauss数据库

1 参考网站 # OpenGauss官网 https://opengauss.org/zh/2 Docker安装OpenGauss 下载OpenGauss docker pull enmotech/opengauss:3.0.0安装OpenGauss 容器参数说明&#xff1a; GS_PASSWORD&#xff1a;必须设置该参数&#xff0c;该参数设置了openGauss数据库的超级用户omm…

LeetCode 刷题系列 -- 1110. 删点成林

给出二叉树的根节点 root&#xff0c;树上每个节点都有一个不同的值。如果节点值在 to_delete 中出现&#xff0c;我们就把该节点从树上删去&#xff0c;最后得到一个森林&#xff08;一些不相交的树构成的集合&#xff09;。返回森林中的每棵树。你可以按任意顺序组织答案。示…

多域(跨域)计算「起势」,智能汽车赛道迎来新拐点

多域&#xff08;跨域&#xff09;计算平台正在成为新一轮市场争夺战的焦点。 就在今年CES展上&#xff0c;采埃孚推出多域功能版本的ProAI高性能计算平台&#xff0c;可以在不同的单板上支持基于域的ADAS、信息娱乐以及车身控制功能&#xff0c;并适配不同供应商的系统芯片以及…

前后端分离的陷阱

不管你设计的系统架构是怎么样&#xff0c;最后都是你的组织内的沟通结构胜出。这个观点一直在组织内不断地被证明&#xff0c;但也不断地被忽略。 前后端分离的利与弊 近几年&#xff0c;随着微服务架构风格的引入、前后端生态的快速发展、多端产品化的出现&#xff0c;前后…

vue前端框架应用案例(三)实现简单的echarts柱状图表

目录前端效果展示项目架构Seller.vueSellerPage.vueindex.jsApp.vuemain.jsindex.html后端源程序接口测试本博客内容参考黑马课程&#xff0c;详细信息请参考以下网址 Bilibili官方黑马课程&#xff1a;【echarts数据可视化项目】 前端 效果展示 项目架构 Seller.vue 该部分…

点云双边滤波

双边滤波&#xff08;Bilateral filter&#xff09;是一种非线性的滤波方法&#xff0c;是结合图像的空间邻近度和像素值相似度的一种折中处理&#xff0c;同时考虑空域信息和灰度相似性&#xff0c;达到保边去噪的目的。具有简单、局部的特点。双边滤波器的好处是可以做边缘保…

rootlogger 和 logger的关系

你是不是经常看到日志框架&#xff08;log4j、log4j2、logback等&#xff09;配置文件中有类似配置&#xff0c;但是始终搞不清楚啥意思&#xff1f;<root level"INFO"><appender-ref ref"CONSOLE" /><appender-ref ref"FILE" /&…

3.9.1Cache的基本概念和原理

文章目录一、引子二、工作原理三、局部性原理&#xff08;1&#xff09;空间局部性&#xff08;2&#xff09;时间局部性&#xff08;3&#xff09;总结四、性能分析&#xff08;1&#xff09;方案一&#xff08;2&#xff09;方案二&#xff08;3&#xff09;考题五、块&#…

LeetCode 212. 单词搜索 II 【字典树+回溯】

题目链接&#xff1a;https://leetcode.cn/problems/word-search-ii/ 给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二维网格上的单词 。 单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&am…

VC+VB开发CAD重生记:CADEditorX 15.X Crack

CADEditorX是一个 ActiveX 组件&#xff0c;用于在任何支持 ActiveX 和 COM 技术的开发环境&#xff08;例如 C#、Visual C、Delphi、VB、JavaScript 等&#xff09;中向网页或正在开发的应用程序添加 CAD 功能。它可以查看、编辑、转换、打印和测量DWG、DXF、SVG、HPGL、PDF、…