delphi tools

In contact with delphi, I often encounter various method classes in my work. Here is a personal summary

1. Split the string

Here I borrowed the method of Wanyi teacher, which is very useful. (TStrings requires class module)

//分割字符串的函数
procedure Split(const str: string; const c: Char; var List: TStrings);
begin
  List.Clear;
  List.Delimiter := c;
  List.DelimitedText := str;
end;
//调用测试
procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStrings;
  s: string;
  c: Char;
begin
  s := 'aaa;bbb;ccc;ddd';
  c := ';';

  List := TStringList.Create;
  Split(s,c,List);
  ShowMessage(List[1]); {
    
    bbb}
  List.Free;
end;

2. Determine the network connection status

The front-end is used to check the network connectivity with the back-end. There are many situations. One is to detect only ip, and the other is to detect ip and port.

2.1 Only detect ip

uses
  Winapi.WinSock, windows, SysUtils, Classes, RegularExpressions;
  

function TPing.PingHost(HostIP: string): boolean;
var
  hICMP: THandle;
  hICMPdll: THandle;
  IcmpCreateFile: TIcmpCreateFile;
  IcmpCloseHandle: TIcmpCloseHandle;
  IcmpSendEcho: TIcmpSendEcho;
  pIPE: PIcmpEchoReply; //   ICMP   Echo   reply   buffer
  FIPAddress: NativeInt;
  FSize: DWORD;
  FTimeOut: DWORD;
  BufferSize: DWORD;
  pReqData, pRevData: pchar;
  MyString: string;
begin
  Result := False;
  hICMPdll := LoadLibrary('icmp.dll');
  if hICMPdll = 0 then
    Exit;
  @IcmpCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile');
  @IcmpCloseHandle := GetProcAddress(hICMPdll, 'IcmpCloseHandle');
  @IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');
  hICMP := IcmpCreateFile;
  if (hICMP = INVALID_HANDLE_VALUE) then
    Exit;
  //xe之前:inet_addr(pchar(HostIP)); Delphi xe:  inet_addr(PANSIChar(ansistring(HostIP)));
  FIPAddress := inet_addr(PANSIChar(ansistring(HostIP)));
  MyString := 'Hello Value';
  pReqData := pchar(MyString);
  FSize := 40; //receive data buffer
  BufferSize := SizeOf(TIcmpEchoReply) + FSize;
  GetMem(pIPE, BufferSize);
  FillChar(pIPE^, SizeOf(pIPE^), 0);
  GetMem(pRevData, FSize);
  pIPE^.Data := pRevData;
  FTimeOut := 2000; //超时间隔毫秒
  try
    Result := IcmpSendEcho(hICMP, FIPAddress, pReqData, Length(MyString), nil, pIPE, BufferSize, FTimeOut) > 0;
  finally
    IcmpCloseHandle(hICMP);
    FreeLibrary(hICMPdll);
    FreeMem(pRevData);
    FreeMem(pIPE);
  end;
end;

2.2 Detect ip and port

uses
  Winapi.WinSock, windows, IdTCPClient, SysUtils, Classes, RegularExpressions;

//ip和端口检测联通
function TPing.IsPortActive(AHost: string; APort: Word): boolean;
var
  IdTCPClient: TIdTCPClient;
begin
  IdTCPClient := TIdTCPClient.Create(nil);
  try
    try
      IdTCPClient.Host := AHost;
      IdTCPClient.Port := APort;
      IdTCPClient.Connect;
    except
      on E: Exception do
      begin
        log4me.log4info('【Ping】网络连接连接失败:[' + E.ClassName + ':' + E.Message + ']');
      end;
    end;
  finally
    result := IdTCPClient.Connected;
    IdTCPClient.Disconnect;
    FreeAndNil(IdTCPClient);
  end;
end;
function TPing.PingServer: boolean;
var
  txt: string;
  c: Char;
  ip: string;
  port: string;
  strList: TStrings;
begin
  strList := TStringList.Create;
  txt := FUSBCamSnap.serverUrl;
  //删除字符串中的前缀,由于我这里的格式为http://192.168.1.2:8080
  txt := txt.Replace('http://', '');
  txt := txt.Replace('https://', '');
  c := ':';
  Utils.split(txt, c, strList);
  ip := strList[0];
  port := strList[1];
  Result := IsPortActive(ip, StrToInt(port));
  strList.Free;
end;

3. ID card related

The most commonly used ID card is to verify the legitimacy. I also made an extension to judge gender.

3.1 Verify the legitimacy of the ID card

function TMyUtils.CheckIDCardNum(cardNum: string): Boolean;

{
    
     内部函数,用于验证身份证号码 }
  function ValidateIDCardNum(const cardNum: string): Char;
  var
    num: Integer;
  begin
    result := #0;
    //17位号码乘以相应系数后相加
    num := StrToInt(cardNum[1]) * 7 + StrToInt(cardNum[2]) * 9 + StrToInt(cardNum[3]) * 10 + StrToInt(cardNum[4]) * 5 + StrToInt(cardNum[5]) * 8 + StrToInt(cardNum[6]) * 4 + StrToInt(cardNum[7]) * 2 + StrToInt(cardNum[8]) * 1 + StrToInt(cardNum[9]) * 6 + StrToInt(cardNum[10]) * 3 + StrToInt(cardNum[11]) * 7 + StrToInt(cardNum[12]) * 9 + StrToInt(cardNum[13]) * 10 + StrToInt(cardNum[14]) * 5 + StrToInt(cardNum[15]) * 8 + StrToInt(cardNum[16]) * 4 + StrToInt(cardNum[17]) * 2;
    num := num mod 11; // 取余数
    case num of
      0:
        result := '1';
      1:
        result := '0';
      2:
        result := 'x';
      3:
        result := '9';
      4:
        result := '8';
      5:
        result := '7';
      6:
        result := '6';
      7:
        result := '5';
      8:
        result := '4';
      9:
        result := '3';
      10:
        result := '2';
    end;
  end;

var
  I: Integer;
  iCentury: Integer; // 世纪
  iYear: Integer; // 年份
  iMonth: Integer; // 月份
  iDay: Integer; // 日期
  febDayAmt: Integer; // 二月的天数
  CRCFact: string; // 18位证件号码的验证值
  lastNum: string; // 证件号码的最后一位
begin
  result := False;
  // 检查身份证位数是否正确
  if Length(cardNum) <> 18 then
    exit;
  for I := 1 to 17 do
  begin
    // 判断前17位是否是数字
    if not isDigit(cardNum[I]) then
    begin
      log4me.log4error('【验证身份证合法性】前17位存在非数字情况');
      exit;
    end;
  end;

  lastNum := Copy(cardNum, 18, 1);
  if ((lastNum = 'x') or (lastNum = 'X')) then
  begin
    lastNum := 'x';
    log4me.log4info('【验证身份证合法性】最后一位统一改成小写x:' + lastNum);
  end;

  // isDigit判断最后一位数字是否是十进制 或 x 或 X
  if not (isDigit(cardNum[18]) or (lastNum = 'x')) then
  begin
    log4me.log4error('【验证身份证合法性】最后一位非数字或X');
    exit;
  end;

  iCentury := StrToInt(Copy(cardNum, 7, 2));
  // 如果年份不是19,20世纪
  if not (iCentury in [19..20]) then
  begin
    log4me.log4error('【验证身份证合法性】非19,20世纪');
    exit;
  end;

  iYear := StrToInt(Copy(cardNum, 9, 2));
  iMonth := StrToInt(Copy(cardNum, 11, 2));
  iDay := StrToInt(Copy(cardNum, 13, 2));

  // 如果月份不在112之间
  if not (iMonth in [01..12]) then
  begin
    log4me.log4error('【验证身份证合法性】月份不合法');
    exit;
  end;

  // 如果是大月
  if iMonth in [1, 3, 5, 7, 8, 10, 12] then
  begin
    // 日期是否是在131之间
    if not (iDay in [01..31]) then
    begin
      log4me.log4error('【验证身份证合法性】日期不合法,不在1-31之间');
      exit;
    end;
  end;

  // 如果是小月
  if iMonth in [4, 6, 9, 11] then
  begin
    // 日期是否在130之间
    if not (iDay in [01..30]) then
    begin
      log4me.log4error('【验证身份证合法性】日期不合法,不在1-30之间');
      exit;
    end;
  end;

  // 是否是闰年
  if IsLeapYear(StrToInt(Copy(cardNum, 7, 4))) then
    febDayAmt := 29
  else
    febDayAmt := 28;
  if iMonth in [2] then // 当前是否是2begin
    if not (iDay in [01..febDayAmt]) then
    begin
      log4me.log4error('【验证身份证合法性】2月份日期不合法');
      exit;
    end;
  end;

  // ValidateIDCardNum————验证身份证合法,返回值为1,2,3,4,5,6,7,8,9,x
  CRCFact := ValidateIDCardNum(cardNum);
  if lastNum <> '' then
  begin
    //log4me.log4info('【验证身份证合法性】输入结果:' + lastNum + '--计算结果:' + CRCFact);
    if lastNum <> CRCFact then
    begin
      log4me.log4error('【验证身份证合法性】算法计算结果与实际结果不符');
      exit;
    end;
  end;
  result := True;

end;

3.2 Judging gender based on ID card

{
    
     身份证性别判断,0为女,1为男 }
function TMyUtils.CheckIDCardSex(cardNum: string): Integer;
var
  lastNum: string;
  lastInt: Integer;
begin
  if CheckIDCardNum(cardNum) then
  begin
    lastNum := Copy(cardNum, 17, 1);
    lastInt := StrToInt(lastNum);
    if (lastInt mod 2 = 0) then
      Result := 0
    else
      Result := 1;
  end
  else
    Result := 3;
end;

4. Time related

{
    
     获取当前时间 }
function TMyUtils.getNowTime: string;
begin
  result := FormatDateTime('yyyy-mm-dd hh:mm:ss', Now());
end;

{
    
     获取当前日期 }
function TMyUtils.getNowDate: string;
begin
  result := FormatDateTime('yyyy-mm-dd', Now());
end;

5. Random GUID

{
    
     获取一个GUID }
function TMyUtils.getGUID: string;
var
  guid: TGUID;
  guidStr: string;
begin
  CreateGUID(guid);
  guidStr := GUIDToString(guid);
  Delete(guidStr, 1, 1);
  Delete(guidStr, Length(guidStr), 1);
  guidStr := StringReplace(guidStr, '-', '', [rfReplaceAll]);
  result := guidStr;
end;

6. Convert to utf8

{
    
    万一老师utf8}
function TMyUtils.ToUTF8Encode(str: string): string;
var
  b: Byte;
begin
  for b in BytesOf(UTF8Encode(str)) do
    Result := Format('%s%%%.2x', [Result, b]);
end;

Guess you like

Origin blog.csdn.net/weixin_43487532/article/details/127246016