返回列表 回复 发帖

[文章类] delphi 身份证号有效性验证函数


function ValidatePID(const APID: string): string;   
  {内部函数,取身份证号校验位,最后一位,对18位有效}  
  function GetVerifyBit(sIdentityNum: string): Char;   
  var  
    nNum: Integer;   
  begin  
    Result := #0;   
    nNum := StrToInt(sIdentityNum[1]) * 7 +   
            StrToInt(sIdentityNum[2]) * 9 +   
            StrToInt(sIdentityNum[3]) * 10 +   
            StrToInt(sIdentityNum[4]) * 5 +   
            StrToInt(sIdentityNum[5]) * 8 +   
            StrToInt(sIdentityNum[6]) * 4 +   
            StrToInt(sIdentityNum[7]) * 2 +   
            StrToInt(sIdentityNum[8]) * 1 +   
            StrToInt(sIdentityNum[9]) * 6 +   
            StrToInt(sIdentityNum[10]) * 3 +   
            StrToInt(sIdentityNum[11]) * 7 +   
            StrToInt(sIdentityNum[12]) * 9 +   
            StrToInt(sIdentityNum[13]) * 10 +   
            StrToInt(sIdentityNum[14]) * 5 +   
            StrToInt(sIdentityNum[15]) * 8 +   
            StrToInt(sIdentityNum[16]) * 4 +   
            StrToInt(sIdentityNum[17]) * 2;   
    nNum := nNum mod 11;   
    case nNum 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  
  L : Integer;   
  sCentury : string;   
  sYear2Bit : string;   
  sMonth : string;   
  sDate : string;   
  iCentury : Integer;   
  iMonth : Integer;   
  iDate : Integer;   
  CRCFact : string;//18位证号的实际值   
  CRCTh : string; //18位证号的理论值   
  FebDayAmt: Byte;//2月天数   
begin  
  L := Length(APID);   
  if (L in [15, 18]) = False then  
  begin  
     Result := Format('身份证号不是15位或18位(%0:s, 实际位数:%1:d)', [APID, L]);   
     Exit;   
  end;   
  CRCFact := '';   
  if L = 18 then  
  begin  
     sCentury := Copy(APID, 7, 2);   
     iCentury := StrToInt(sCentury);   
     if (iCentury in [18..20]) = False then  
     begin  
        Result := Format('身份证号码无效:18位证号的年份前两位必须在18-20之间(%0:S)', [sCentury]);   
        Exit;   
     end;   
     sYear2Bit := Copy(APID, 9, 2);   
     sMonth := Copy(APID, 11, 2);   
     sDate := Copy(APID, 13, 2);   
     CRCFact := Copy(APID, 18, 1);   
  end else  
  begin  
     sCentury := '19';   
     sYear2Bit := Copy(APID, 7, 2);   
     sMonth := Copy(APID, 9, 2);   
     sDate := Copy(APID, 11, 2);   
  end;   
  iMonth := StrToInt(sMonth);   
  iDate := StrToInt(sDate);   
  if (iMonth in [01..12]) = False then  
  begin  
     Result := Format('身份证号码无效:月份必须在01-12之间(%0:s)', [sMonth]);   
     Exit;   
  end;   
  if (iMonth in [1, 3, 5, 7, 8, 10, 12]) then  
  begin  
     if (iDate in [01..31]) = False then  
     begin  
        Result := Format('身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s)', [sDate]);   
        Exit;   
     end;   
  end;   
  if (iMonth in [4, 6, 9, 11]) then  
  begin  
     if (iDate in [01..30]) = False then  
     begin  
        Result := Format('身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s)', [sDate]);   
        Exit;   
     end;   
  end;   
  if IsLeapYear(StrToInt(sCentury + sYear2Bit)) = True then  
  begin  
     FebDayAmt := 29;   
  end else  
  begin  
     FebDayAmt := 28;   
  end;   
  if (iMonth in [2]) then  
  begin  
     if (iDate in [01..FebDayAmt]) = False then  
     begin  
        Result := Format('身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s)', [sDate]);   
        Exit;   
     end;   
  end;   
  if CRCFact <> '' then  
  begin  
     CRCTh := GetVerifyBit(APID);   
     if CRCFact <> CRCTh then  
     begin  
        Result := Format('身份证号码无效:校验位(第18位)错%0:s)', [APID]);   
        Exit;   
     end;   
  end;   
end;
返回列表