中國大陸身分證 18 碼結構:
校驗碼計算公式:Σ(位碼 × 權重) % 11,對應查表 {1,0,X,9,8,7,6,5,4,3,2}。
using System;
using System.Text.RegularExpressions;
public static class IdCardValidator {
// 權重陣列 (18 碼)
private static readonly int[] Weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
// 校驗碼對照表 (索引 = 餘數)
private static readonly char[] CheckCodeMap = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
// 行政區劃代碼 (簡化版,實務建議載入完整表)
private static readonly string[] AreaCode = {
null, null, null, null, null, null, null, null, null, null, null,
"北京", "天津", "河北", "山西", "內蒙古",
null, null, null, null, null,
"遼寧", "吉林", "黑龍江",
null, null, null, null, null, null,
"上海", "江蘇", "浙江", "安徽", "福建", "江西", "山東",
null, null, null,
"河南", "湖北", "湖南", "廣東", "廣西", "海南",
null, null, null,
"重慶", "四川", "貴州", "雲南", "西藏",
null, null, null, null, null, null,
"陝西", "甘肅", "青海", "寧夏", "新疆",
null, null, null, null, null,
"台灣",
null, null, null, null, null, null, null, null, null,
"香港", "澳門",
null, null, null, null, null, null, null, null,
"國外"
};
///
/// 驗證身分證並回傳資訊 (地區, 生日, 性別);失敗回傳錯誤訊息
///
public static string Validate(string idCard) {
if (string.IsNullOrWhiteSpace(idCard)) return "輸入為空";
idCard = idCard.Trim().ToUpper();
// 1. 格式檢查 (18 碼)
if (!Regex.IsMatch(idCard, @"^\d{17}[\dX]$")) {
return "格式錯誤:應為 18 碼數字或尾碼 X";
}
// 2. 行政區劃檢查
int area = int.Parse(idCard.Substring(0, 2));
if (area >= AreaCode.Length || AreaCode[area] == null) {
return "非法地區代碼";
}
// 3. 生日檢查
if (!DateTime.TryParseExact(idCard.Substring(6, 8), "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out _)) {
return "非法生日";
}
// 4. 校驗碼驗證
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (idCard[i] - '0') * Weight[i];
}
char expectedCheck = CheckCodeMap[sum % 11];
if (idCard[17] != expectedCheck) {
return "非法證號:校驗碼不符";
}
// 5. 解析性別
string gender = ((idCard[16] - '0') % 2 == 1) ? "男" : "女";
string birthday = $"{idCard.Substring(6,4)}-{idCard.Substring(10,2)}-{idCard.Substring(12,2)}";
return $"{AreaCode[area]},{birthday},{gender}";
}
///
/// 15 碼舊版身分證轉 18 碼新版
///
public static string Convert15To18(string id15) {
if (string.IsNullOrWhiteSpace(id15) || id15.Length != 15 || !Regex.IsMatch(id15, @"^\d{15}$")) {
throw new ArgumentException("輸入必須為 15 碼純數字");
}
// 插入 "19" 年份前綴
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 = CheckCodeMap[sum % 11];
return id17 + check;
}
///
/// 計算 17 碼本體的校驗碼
///
public static char CalculateCheckCode(string id17) {
if (id17.Length != 17) throw new ArgumentException("必須為 17 碼");
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (id17[i] - '0') * Weight[i];
}
return CheckCodeMap[sum % 11];
}
}
// 驗證 18 碼身分證
string id18 = "620102197811196218";
string result = IdCardValidator.Validate(id18);
Console.WriteLine(result); // 輸出: 甘肅,1978-11-19,男
// 15 碼轉 18 碼
string id15 = "620102781119621";
string converted = IdCardValidator.Convert15To18(id15);
Console.WriteLine(converted); // 輸出: 620102197811196218
// 單獨計算校驗碼
char check = IdCardValidator.CalculateCheckCode("62010219781119621");
Console.WriteLine(check); // 輸出: 8
static readonly 並加 RegexOptions.Compiled。