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

C# 實作 15 碼身分證升級 18 碼演算法:加權檢查碼計算

     編輯:關於C語言

身分證字號規則演變

舊制 15 碼:6碼地址 + 6碼出生年月日(YYMMDD) + 3碼順序碼(無西元年、無檢查碼)。
新制 18 碼:6碼地址 + 8碼出生年月日(YYYYMMDD) + 3碼順序碼 + 1碼檢查碼。

升級演算法步驟

  1. 取前 6 碼地址碼
  2. 插入「19」作為出生世紀 (假設皆為 1900 年代出生)
  3. 接原 15 碼第 7~15 碼 (出生日期 + 順序碼) → 共 17 碼
  4. 依加權因子陣列計算加權和
  5. 模 11 取餘數,對應檢查碼對照表取得第 18 碼

標準加權因子與檢查碼對照表

// 加權因子 (17 碼對應)
int[] weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

// 檢查碼對照 (索引 = 餘數 0~10)
string checkCodes = "10X98765432";  // 餘數 0→'1', 1→'0', 2→'X', ...

修正版完整實作 (含輸入驗證)


public static string Upgrade15To18(string id15)
{
    if (string.IsNullOrWhiteSpace(id15) || id15.Length != 15)
        throw new ArgumentException("輸入必須為 15 碼數字");

    if (!id15.All(char.IsDigit))
        throw new ArgumentException("15 碼身分證需全為數字");

    // 1. 組合 17 碼本體
    string body17 = id15.Substring(0, 6) + "19" + id15.Substring(6, 9);

    // 2. 加權求和
    int sum = 0;
    for (int i = 0; i < 17; i++)
    {
        int digit = body17[i] - '0';
        sum += digit * weight[i];
    }

    // 3. 取模對應檢查碼
    int mod = sum % 11;
    char checkChar = checkCodes[mod];

    return body17 + checkChar;
}

// 使用範例
string id18 = Upgrade15To18("429005811009091"); // → 42900519811009091X

重要補充說明

  • 世紀假設:程式碼固定插入「19」,適用 1900~1999 年出生者。2000 年後出生者 15 碼制不適用 (15 碼制 2000 年前已停用)
  • 地址碼驗證:實際應用應檢核前 6 碼是否為有效行政區劃代碼
  • 出生日期驗證:建議解析 YYMMDD 驗證合法日期
  • 檢查碼 'X':代表數值 10,為大寫羅馬數字 10,非英文字母

反向驗證 18 碼合法性


public static bool Validate18(string id18)
{
    if (id18?.Length != 18) return false;
    int sum = 0;
    for (int i = 0; i < 17; i++)
        sum += (id18[i] - '0') * weight[i];
    int mod = sum % 11;
    char expected = checkCodes[mod];
    char actual = char.ToUpper(id18[17]);
    return expected == actual;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved