公民身份号码校验码算法(C#版)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace org_checker
{
    /// <summary>
    /// 公民身份号码  校验码 检证程序
    /// vp:hsg
    /// create date:2013-09-13 1:19
    /// </summary>
    public class sfzhmClass
    {
        public void test()
        {
            string y_bm = "51302119781010543-4";
            //
            Console.WriteLine(y_bm);
            string bm = this.Getsfzh_checkbm(y_bm);
            Console.WriteLine(bm);
            Console.ReadLine();
        }
        public string Getsfzh_checkbm(string str_in)
        {
            string rbc="";
            int[] wi=new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
            char c;
            int S=0, z=0;
            for (int i =0; i <17; i++)
            {
                c = char.Parse(str_in.Substring(i, 1));
                if (c >= 'A' && c <= 'Z')  //A-Z字符
                {
                    z = ((int)c - 55) * wi[i];
                }
                else if (c >= '0' && c <= '9')  //0-9字符
                {
                    z = int.Parse(c.ToString()) * wi[i];
                }
                else
                {
                    rbc = "Err不能输入其他字符错误码";
                    return rbc;
                }
                S += z;
            }
            int Y=S %11;
            string g_c="";
            //校验码
            //根据模的值得到对应的校验码
            //对应关系为:
            //Y值: 0 1 2 3 4 5 6 7 8 9 10
            //校验码: 1 0 X 9 8 7 6 5 4 3 2
            string xym="1,0,X,9,8,7,6,5,4,3,2";
            string[] CArray=xym.Split(new char[]{','});
            g_c=CArray[Y];  //获取校验码
            rbc=str_in.Substring(0,17)+"-"+g_c;
            return rbc;
        }
    }
}
   /* 
 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。
      排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,
      三位数字顺序码和一位校验码。其含义如下:

1. 地址码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
2. 出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,
      年、月、日分别用4位、2位、2位数字表示,之间不用分隔符。
3. 顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,
      顺序码的奇数分配给男性,偶数分配给女性。
校验的计算方式:

1. 对前17位数字本体码加权求和
公式为:S = Sum(Ai * Wi), i = 0, ... , 16
其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,
      其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

2. 以11对计算结果取模
Y = mod(S, 11)

3. 根据模的值得到对应的校验码
对应关系为:
Y值: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2

关于18位身份证号码尾数是“X”的解释

居民身份证的号码是按照国家的标准编制的,由18位组成:前六位为行政区划代码,
     * 第七至第十四位为出生日期码,第15至17位为顺序码,第18位为校验码。
     * 作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,
     * 如果某人的尾号是0-9,都不会出现X,但如果尾号是10,
     * 那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,
     * 而19位的号码违反了国家标准,并且我国的计算机应用系统也不承认19位的身份证号码。
     * Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
     * 但是我国的居民身份证在升位后,一些人的尾号变成了X,这部分人在工作生活中,
     * 例如去银行存取钱、去汽车公司租赁汽车或者报名参加考试等等过程中,
     * 往往不被检验者理解,认为是假身份证,这样的误会给很多人的生活带来不便。
     * 公安局的同志希望领到X身份证的同志正确理解这个数字的含义,
     * 查验身份证的机关和单位更应该清楚这一点。
     

*/

附: GB11714-1997全国组织机构代码编制规则

原文地址:https://www.cnblogs.com/kongxiaoshuang/p/6439182.html