delphi工具类

接触delphi,工作中经常碰到各种方法类,这里进行个人总结

1.分割字符串

这里借鉴了万一老师的方法,很好用。(TStrings需要class模块)

//分割字符串的函数
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.判断网络连接状态

前端用来检验和后端的网络联通性,有多种情况,一种是只检测ip,一种的检测ip和端口。

2.1仅检测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检测ip和端口

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.身份证相关

身份证最常用的就是验证合法性,我这里还做了个判断性别的引申。

3.1验证身份证合法性

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根据身份证判断性别

{ 身份证性别判断,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.时间相关

{ 获取当前时间 }
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.随机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.转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;
CnPack是什么? CnPack是一个仍在筹划开发中的Delphi第三方开发包:-) ,它的全称是 CnPack For Delphi 开发包。 与一般的控件包不同的是,CnPack开发包除了包括大量的组件外,还包括用于IDE扩展的专家包、大量的通用窗体、数据桌面、组件编写工具等辅助开发工具,以及一个版本控制系统等等与Delphi软件开发相关的代码、文档和程序。 CnPack由网上的自愿者们组成的CnPack开发组制作,是一个典型的网上合作开发项目。 CnPack是一个完全符合GPL LGPL协议的自由程序。 CnPack开发组将用2002年全年甚至更长的时间来完成这一开发计划。 为什么要开发CnPack呢? Delphi以其完全开放的VCL体系吸引了很多的程序员,通过使用第三方的代码和控件,可以极大的提高软件开发效率。然而,在大量的优秀控件中,由中国程序员制作的却少得可怜。除去商业控件包不说(恕小弟识浅,哪位朋友见过国产的商业控件包吗?),国内有多少控件包可以和RxLib、GExpert、FastReport、FlatStyle等这些免费、共享包相提并论?CnPack的计划就是集中大家的力量制作一个真正优秀的大型开发包,同时提供大量的代码和文档让Delphi程序员参考和学习。我想,不需要我做太多解释,大家也能理解开发CnPack的意义:1、对程序员用户而言,首先,开发包所有文档、注释都将使用中文编写,这对很多E文不好的程序员来说绝对是一件好事。其次,技术支持和学习交流将变得方便,有多少人可以从国外获得控件包的技术支持呢?当然,前面两点国产优势都是次要的,CnPack的设计目标是一个真正功能强大、实用的开发包,能帮助程序员更方便地做出好的软件。 2、对开发人员而言,通过开发,可以对Delphi的系统结构有更深的认识,并从中学到大量的经验和技巧,而多人协作开发的经验亦是非常有用。更重要的是,我们将以自己的实际行动证明,中国的Delphi程序员并不比外国的差。CnPack包括些什么内容? 在开发计划中,CnPack包括了Delphi程序设计相关的很多方面:不可视工具组件包。 用户界面控件包。 符合中国人使用习惯的数据、报表组件包。 网络通讯组件包。 本地化、扩展的属性、组件编辑器。 IDE扩展专家工具包。 CnVCS版本控制系统。 本地化、功能强大的数据桌面、资源编辑器、组件编写工具等辅助开发工具。 大量可重用的窗体模板。 而在正式的开发中,将根据具体情况进行调整,详细的内容参见开发资料中相应部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值