欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 身份证号码15位和18位验证

程序员文章站 2022-06-28 20:11:27
///  /// 身份证 ///  [Serializable] public class IDCard { ///  /// 身份证号 ///  public string IDCardNum { get; set; } ......
/// <summary>
/// 身份证
/// </summary>
[serializable]
public class idcard
{
    /// <summary>
    /// 身份证号
    /// </summary>
    public string idcardnum { get; set; }
    /// <summary>
    /// 行政区
    /// </summary>
    public string canton { get; private set; }
    /// <summary>
    /// 出生日期
    /// </summary>
    public datetime birthday { get; private set; }
    /// <summary>
    /// 性别(0-女;1-男)
    /// </summary>
    public int gander { get; private set; }
    /// <summary>
    /// 是否为合法身份证号
    /// </summary>
    public bool isidcard { get; private set; }
 
    public idcard() { }
 
    public idcard(string idnumber)
    {
        this.idcardnum = idnumber;
    }
 
 
    /// <summary>
    /// 
    /// </summary>
    /// <param name="number"></param>
    /// <returns></returns>
    public static idcard parse(string number)
    {
        idcard idcard = new idcard(number);
 
        const int s5bits = 15;
        const int s8bits = 18;
 
        #region 15位
        if (number.length == s5bits)  //15位的处理
        {
            //检查输入是否为数字
            for (int i = 0; i < number.length; i++)
            {
                if ((number[i] < '0') || (number[i] > '9'))
                {
                    throw new formatexception("身份证号错误");
                }
            }
 
            //出生日期
            string birthday = "19" + number.substring(6, 6);
            string year = birthday.substring(0, 4);
            string month = birthday.substring(4, 2);
            string day = birthday.substring(6, 2);
            birthday = string.format("{0}-{1}-{2}", year, month, day);
 
            datetime date = new datetime();
            if (datetime.tryparse(birthday, out date))
            {
                idcard.birthday = date;
            }
            else
            {
                throw new invalidcastexception("身份证号出生日期错误");
            }
            
            //性别
            if ((number[s5bits - 1] == '0') || (number[s5bits - 1] % 2 == 0))
            {
                idcard.gander = 0; // 女
            }
            else
            {
                idcard.gander = 1; // 男
            }
 
            idcard.isidcard = true;
            return idcard;
        }
        #endregion
 
        #region 18位
        else if (number.length == s8bits)  //18位的处理
        {
            // 检查前17位是否为数字
            for (int i = 0; i < number.length -1; i++)
            {
                if ((number[i] < '0') || (number[i] > '9'))
                {
                    throw new formatexception("身份证号错误");
                }
            }
 
            char end = number[s8bits - 1];  //最后一位
 
            //最后1位是x转成大写x
            if (end == 'x')
            {
                end = 'x';
                number = number.substring(0, s8bits - 1) + end;
            }
 
            if (!(end == 'x' || (end >= '0' && end <= '9')))
            {
                throw new formatexception("身份证号错误");
            }
            
            /// 校验
            int num = 0;
            char proof;
            for (int i = 17; i > 0; i--)
            {
                num = num + (int)(math.pow(2, i) % 11) * (number[17 - i] - 48);
            }
            num %= 11;
            switch (num)
            {
                case 0:
                    proof = '1';
                    break;
                case 1:
                    proof = '0';
                    break;
                case 2:
                    proof = 'x';
                    break;
                default:
                    proof = (char)(12 - num + 48);
                    break;
            }
 
            if (end != proof)  //最后一位与校验码不符
            {
                throw new formatexception("身份证号错误");
            }
 
            //出生日期
            string birthday = number.substring(6, 8);
            string year = birthday.substring(0, 4);
            string month = birthday.substring(4, 2);
            string day = birthday.substring(6, 2);
            birthday = string.format("{0}-{1}-{2}", year, month, day);
 
            datetime date = new datetime();
            if (datetime.tryparse(birthday, out date))
            {
                idcard.birthday = date;
            }
            else
            {
                throw new invalidcastexception("身份证号出生日期错误");
            }
 
            //行政区
            idcard.canton = number.substring(0, 6);
 
            //性别
            if ((number[16] == '0') || (number[16] % 2 == 0))
            {
                idcard.gander = 0;  //女
            }
            else
            {
                idcard.gander = 1;  //男
            }
 
            idcard.isidcard = true;
            return idcard;
        }
        #endregion
        else
        {
            throw new formatexception("无效的身份证号码位数:" + number.length);
        }
    }
 
    public static bool tryparse(string number, out idcard card)
    {
        idcard idcard = null;
        bool isidcard = true;
        try
        {
            parse(number);
        }
        catch (exception)
        {
            isidcard = false;
        }
        card = idcard;
        return isidcard;
    }
}