舊版身分證 15 碼 (6 碼地址 + 6 碼出生年月日 + 3 碼順序碼),新版擴充為 18 碼:插入「19」作世紀碼、增加校驗碼。
Wi = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}。Y = Sum % 11。校驗碼 = "10X98765432"[Y] (索引 0-10)。public static string UpgradeId15To18(string id15)
{
if (string.IsNullOrEmpty(id15) || id15.Length != 15)
throw new ArgumentException("必須為 15 碼身分證");
int[] weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
string checkCodes = "10X98765432";
// 1-6 地址碼 + 19 + 7-15 出生順序
string id17 = id15.Substring(0, 6) + "19" + id15.Substring(6, 9);
// 加權求和
int sum = 0;
for (int i = 0; i < 17; i++)
sum += (id17[i] - '0') * weight[i];
// 校驗碼
char check = checkCodes[sum % 11];
return id17 + check;
}
// 測試
Console.WriteLine(UpgradeId15To18("429005811009091")); // 輸出 18 碼新身分證
public static bool ValidateId18(string id18)
{
if (string.IsNullOrEmpty(id18) || id18.Length != 18) return false;
int[] w = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
string codes = "10X98765432";
int sum = 0;
for (int i = 0; i < 17; i++)
if (!char.IsDigit(id18[i])) return false;
else sum += (id18[i] - '0') * w[i];
char expected = codes[sum % 11];
return char.ToUpper(id18[17]) == expected;
}
X 不分大小寫。依照國標 GB 11643-1999 實作 15→18 碼轉換與驗證,核心為加權求和模 11 查表,程式碼簡潔易維護。