C# 身份證號碼15位和18位驗證

/// <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;
    }
}
相關文章
相關標籤/搜索