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,iCentury,iMonth,iDate: Integer;
  sCentury,sYear2Bit,sMonth,sDate : string;
  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;

//http://wenku.baidu.com/view/71e4eef804a1b0717fd5dd0a.html  参考资料
function GetOrgVerifyBit(sIdentityNum: string): Char;
  function GetKeyASC(Key: Char): Integer;
  begin
    Result := 0;
    if ord(Key)<65 then        //ASC大于65的是A..Z 
      Result := strtoint(Key)
    else
      Result := ord(Key)-55;
  end;
var nNum: Integer;
begin
    Result := #0;
    nNum := GetKeyASC(sIdentityNum[1]) * 3 +
            GetKeyASC(sIdentityNum[2]) * 7 +
            GetKeyASC(sIdentityNum[3]) * 9 +
            GetKeyASC(sIdentityNum[4]) * 10+
            GetKeyASC(sIdentityNum[5]) * 5 +
            GetKeyASC(sIdentityNum[6]) * 8 +
            GetKeyASC(sIdentityNum[7]) * 4 +
            GetKeyASC(sIdentityNum[8]) * 2;
    nNum := 11-(nNum mod 11);
    if nNum = 10 then
      Result := 'X'
    else if nNum = 11 then
      Result := '0'
    else
      Result := char(nNum+48);
end;

function ValidateSBH(const NSRSBH: string): string;
begin
  Result := '';

if not (Length(Trim(NSRSBH)) in [15,16,17,18,19,20]) then
  begin
    Result := '纳税人识别号位数错误。';
    Exit;
  end;

if (Copy(NSRSBH,1,1)>='1') and (Copy(NSRSBH,1,1)<='9') then //当身份证号码,包含5开头纳税人识别号
  begin
    if Length(NSRSBH)=15 then  
    begin
      if GetOrgVerifyBit(Copy(NSRSBH,7,8))<>Copy(NSRSBH,15,1) then //先检验机构代码,检验不过再当老身份证号检验
      begin
        if Trim(ValidatePID(NSRSBH))<>'' then
        begin
          Result := '纳税人识别号错误。';
          Exit;
        end;
      end;
    end
    else if Length(NSRSBH)=18 then  //只检验身份证号
    begin
      if Trim(ValidatePID(NSRSBH))<>'' then
      begin
        Result := '纳税人识别号错误。';
        Exit;
      end;
    end
    else   //长度是17,20的就去掉后两位流水号再检验身份证号
    begin
      if Trim(ValidatePID(Copy(NSRSBH,1,Length(NSRSBH)-2)))<>'' then
      begin
        Result := '纳税人识别号错误。';
        Exit;
      end;
    end;
  end
  else if (Copy(NSRSBH,1,1)='L') then  //临时发生纳税义务办理临时登记的纳税人
  begin
    if Trim(ValidatePID(Copy(NSRSBH,2,Length(NSRSBH))))<>'' then
    begin
      Result := '临时性纳税人识别号错误。';
      Exit;
    end;
  end
  else if (Copy(NSRSBH,1,1)='F') or (Copy(NSRSBH,1,1)='J') then //F: 无常设机构的非居民企业的纳税人识别号, J: 以军官证、士兵证
  begin
    if Length(Trim(NSRSBH))<>15 then
    begin
      Result := '无常设机构的纳税人识别号位数错误。';
      Exit;
    end;
    if (Copy(NSRSBH,2,14)='00000000000000') or
       (Copy(NSRSBH,2,14)='11111111111111') or
       (Copy(NSRSBH,2,14)='22222222222222') or
       (Copy(NSRSBH,2,14)='33333333333333') or
       (Copy(NSRSBH,2,14)='44444444444444') or
       (Copy(NSRSBH,2,14)='55555555555555') or
       (Copy(NSRSBH,2,14)='66666666666666') or
       (Copy(NSRSBH,2,14)='77777777777777') or
       (Copy(NSRSBH,2,14)='88888888888888') or
       (Copy(NSRSBH,2,14)='99999999999999') then
    begin
      Result := '无常设机构的纳税人识别号错误。';
      Exit;
    end;
  end
  else
  begin  //其他字母开头表示港、澳、台及外国人,在地区拉丁字母码”首位字母 “4位年份码(登记年份)”只检验年份
    try
      if (StrToInt(Copy(NSRSBH,2,4))<1990) or (StrToInt(Copy(NSRSBH,2,4))>2050) then
      begin
         Result := '自然人登记的纳税人识别号错误。';
         Exit;
      end;
    except
      Result := '自然人登记的纳税人识别号错误。';
      Exit;
    end;
  end;
end;

function ValidateYYZZH(const YYZZH: string): string;
var i:integer;
    CharOK:Boolean;
    S: Array [0..14] Of Integer;
    P: Array [0..14] Of Integer;
    A: Array [0..14] Of Integer;
const M=10;
begin
  P[0] := M;
  
  Result := '';

if Length(Trim(YYZZH)) <> 15 then
  begin
    Result := '营业执照号码位数错误。';
    Exit;
  end;

CharOK := True;
  for i := 1 to 15 do
  begin
    if not (YYZZH[i] in ['0'..'9']) then
    begin
      CharOK := False;
      Result := '营业执照号码必须为数字。';
      Break;
    end;
  end;
  if not CharOK then Exit;

for i := 0 to 14 do
  begin
    A[i] := StrToInt(YYZZH[i+1]);
    S[i] := (P[i] mod (M+1)) + A[i];

if (S[i] mod M = 0) then
      P[i+1] := 10*2
    else
      P[i+1] := (S[i] mod M)*2;
  end;
  if (S[14] MOD M <> 1) then
    begin
      Result := '营业执照号码检验错误。';
      Exit;
    end;
end;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/166523/viewspace-1434280/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/166523/viewspace-1434280/

校验身份证、组织机构代码证、纳税人识别号、营业执照号 的方法相关推荐

  1. Python 组织机构代码证校验

    全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成. 校验码按照以下公式计算: C9=11−MOD(∑i=18Ci×Wi,11) C_9=11-MOD(\sum ...

  2. 组织机构代码证号码校验

    (1)html部分 <div class="test4 txt-com"><input id="StoreAddTxt17" name=&qu ...

  3. 校验全国组织机构代码是否合法

    根据网络整理,经过实际应用. package com.brofe.util; import java.util.HashMap;import java.util.Map;import java.uti ...

  4. python结合正则表达式及校验码生成算法校验:电话号码、营业执照、组织机构代码证、税务登记证、统一社会信用代码证、非盈利性企业登记证号码的函数

    #!/usr/bin/env python3 import re from datetime import datetimedef check_phone(phone):'''三大运营商和虚拟运营商的 ...

  5. 【成立公司】5.营业执照和组织机构代码证

    办事地点 行政服务中心 所需资料 法人代表身份证复印件 取章回执单 花费金额 846元 办事经历 从办理登记业务到今天,正好一周时间,可以领营业执照了.早上9点来到行政服务中心的工商局窗口索取营业执照 ...

  6. 手机号,身份证号,邮政编码,统一信用代码,发票抬头,纳税人识别号正则校验

    手机号 phone(rule, value, callback) {const reg = /^[1][3,4,5,6.7,8,9][0-9]{9}$/if (!reg.test(value)) {c ...

  7. 区分统一社会信用代码、组织机构代码、注册号

    区分统一社会信用代码.组织机构代码.注册号 背景 2015年6月4日,国务院常务会议决定实施法人和其他组织统一社会信用代码制度,提升社会运行效率和信用.法人和其他组织统一社会信用代码相当于让法人和其他 ...

  8. JS实现统一社会信用代码的效验(组织机构代码效验)

    参考原文https://blog.csdn.net/hdhxby/article/details/56015370 部分错误,修改整合了下 想查询数据的,请点击:统一信用代码查询地址 查看效验规则点击 ...

  9. 组织机构代码和统一社会信用代码校验规则以及java校验工具类

    组织机构代码 编码规则编辑 1.全国组织机构代码由八位数字(或大写拉丁字母)本体代码和一位数字(或大写拉丁字母)校验码组成. 本体代码采用系列(即分区段)顺序编码方法. 校验码按照以下公式计算: C9 ...

  10. 校验组织机构代码 合法性

    组织机构代码验证规则: 组织机构代码是每一个机关.社会团体.企事业单位在全国范围内唯一的.始终不变的法定代码标识.  最新使用的组织机构代码在1997年颁布实施,由8位数字(或大写拉丁字母)本体代码和 ...

最新文章

  1. Mybatis注解学习记录
  2. python回归算法_机器学习算法之回归详解
  3. 一个人就需要对象之js中八种创建对象方式
  4. 菜鸟发现--网站的皮肤 ^_^
  5. ios支付宝支付失败不回调_为什么 iOS 支付成功后能回到 APP ,但是没有回调?...
  6. 接口并发如何模仿用户点击率和提交率_洞察| 五大法则揭秘!在抖音如何打造“爆款”?...
  7. 【elasticsearch】 Regexes are disabled. Set [script.painless.regex.enabled] to [true]
  8. Notes on how to use Webots, especially how to make a robot fly in the air
  9. 1064. Complete Binary Search Tree
  10. 2014北科计算机原理试题答案,2014北科计算机组成原理试题
  11. VS2017--如何添加版权声明注释
  12. 动态随机存储器的刷新
  13. linux rpm找不到命令_linux 基础知识
  14. UEditor自定义工具栏图标
  15. PageHelper关闭count语句优化
  16. 项目管理(PMP)项目进度管理
  17. 基因大数据的集成分析
  18. 一文带您了解信号线和电源线的区别
  19. 从F型网页浏览看用户对网页的浏览习惯
  20. 英语单词复习2(四级)

热门文章

  1. 银行争夺又一万亿市场:汽车金融
  2. 邮件服务器搬家,邮件搬家操作方法
  3. 简明外贸报价单(Price List)范本
  4. 使用css画出一条虚线
  5. C语言小白教程第三讲-常量
  6. mac地址被路由器拉黑_我买了一个新路由器,告诉我我被黑了
  7. Normal and self-adjoint operator
  8. 近几年热门的计算机专业,中国近十年最受高考状元青睐专业排行榜
  9. pyodbc linux 乱码,关于python:无法在Linux上安装pyodbc
  10. 电脑系统时间服务器地址,电脑时间同步服务器ip地址