首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 中國身分證字號驗證完整實作 (符合 GB11643-1999)

     編輯:關於C#

身分證字號規則速覽

版本長度結構
舊制15 碼6 碼地址 + 6 碼生日 (YYMMDD) + 3 碼流水號
新制18 碼6 碼地址 + 8 碼生日 (YYYYMMDD) + 3 碼流水號 + 1 碼檢核碼

檢核碼演算法 (新制 18 碼)

  1. 前 17 碼乘以權重加權求和:
    權重陣列:[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
  2. 和值對 11 取模:Y = Sum % 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

完整驗證程式碼 (支援 15/18 碼)


using System;
using System.Globalization;

public static class IdCardValidator
{
    // 省份/地區代碼前兩碼 (含港澳台、國外)
    private static readonly string[] AreaCodes = {
        "11","12","13","14","15","21","22","23","31","32","33","34","35","36","37",
        "41","42","43","44","45","46","50","51","52","53","54","61","62","63","64","65",
        "71","81","82","91"
    };

    private static readonly int[] Weights = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    private static readonly char[] CheckCodes = "10X98765432".ToCharArray();

    /// 
    /// 驗證身分證字號 (自動判別 15/18 碼)
    /// 
    public static bool Validate(string id)
    {
        if (string.IsNullOrWhiteSpace(id)) return false;
        id = id.Trim().ToUpper();
        return id.Length switch
        {
            18 => Validate18(id),
            15 => Validate15(id),
            _  => false
        };
    }

    private static bool Validate18(string id)
    {
        // 1. 數字檢查 (前17碼為數字,第18碼為數字或X)
        if (!long.TryParse(id[..17], out _) || id[17] is not (>= '0' and <= '9' or 'X')) return false;

        // 2. 省份碼檢查
        if (Array.IndexOf(AreaCodes, id[..2]) < 0) return false;

        // 3. 生日檢查
        if (!DateTime.TryParseExact(id[6..14], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
            return false;

        // 4. 檢核碼計算
        int sum = 0;
        for (int i = 0; i < 17; i++)
            sum += (id[i] - '0') * Weights[i];
        char expected = CheckCodes[sum % 11];
        return id[17] == expected;
    }

    private static bool Validate15(string id)
    {
        // 1. 全數字
        if (!long.TryParse(id, out _)) return false;

        // 2. 省份碼
        if (Array.IndexOf(AreaCodes, id[..2]) < 0) return false;

        // 3. 生日 (YYMMDD) - 注意年代歧義,通常視為 19xx
        string yymmdd = "19" + id[6..12];
        return DateTime.TryParseExact(yymmdd, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _);
    }
}

// 使用範例
class Program
{
    static void Main()
    {
        string[] tests = {
            "11010519900307892X", // 正確 18 碼
            "110105900307892",    // 正確 15 碼
            "110105199003078921", // 錯誤檢核碼
            "99010519900307892X"  // 錯誤省份碼
        };

        foreach (var id in tests)
            Console.WriteLine($"{id,-20} => {IdCardValidator.Validate(id)}");
    }
}

進階應用建議

  • 效能優化:`AreaCodes` 改用 `HashSet` O(1) 查找;熱路徑避免 `Substring` 配置,改用 `AsSpan()` 切片。
  • 年代歧義處理:15 碼生日年份僅兩碼,實務上需結合業務判斷是 19xx 或 20xx。
  • 擴充性:支援港澳台居民居住證、外國人永久居留身分證 (不同規則),可建立 `IIdValidator` 策略介面。
  • 資料庫層:建議在資料庫 `CHECK CONSTRAINT` 或觸發器同步驗證,防臟資料入庫。

總結

嚴格遵循 GB11643-1999 標準,結合省份碼、生日合法性、加權檢核碼三重驗證,即可精準判斷中國大陸身分證字號真偽。提供的實作採用現代 C# 語法 (Switch Expression, Range, Pattern Matching),程式碼簡潔且高效,可直接整合至註冊、實名認證等業務流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved