
核心代码
using System;
using System.Text.RegularExpressions;
namespace WindowsFormsApp1
{
/// <summary>
/// 身份证号码工具类(支持18位身份证,含校验码计算、合法性验证)
/// </summary>
public static class IdCardValidationHelper
{
#region 私有常量
/// <summary>
/// 前17位对应的加权因子(固定序列)
/// </summary>
private static readonly int[] WeightFactors = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
/// <summary>
/// 余数与校验码的映射表(索引对应余数0-10)
/// </summary>
private static readonly char[] CheckCodeMap = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
#endregion
#region 公共方法
/// <summary>
/// 根据18位身份证号码验证其合法性(含校验码验证+格式验证)
/// </summary>
/// <param name="idCardNumber">18位身份证号码</param>
/// <returns>是否合法</returns>
public static bool IsValidIdCard(string idCardNumber)
{
// 1. 基础格式验证(长度18位、前17位为数字、第18位为数字或X)
if (!IsIdCardFormatValid(idCardNumber))
{
return false;
}
// 2. 校验码验证
return IsCheckCodeValid(idCardNumber);
}
/// <summary>
/// 计算17位身份证前缀对应的校验码
/// </summary>
/// <param name="idCardPrefix17">17位身份证前缀(必须为数字)</param>
/// <returns>校验码(大写X或数字)</returns>
/// <exception cref="ArgumentException">前缀不合法时抛出异常</exception>
public static char CalculateCheckCode(string idCardPrefix17)
{
// 验证17位前缀的合法性
if (string.IsNullOrEmpty(idCardPrefix17) || idCardPrefix17.Length != 17 || !IsAllDigits(idCardPrefix17))
{
throw new ArgumentException("输入的身份证前缀必须是17位数字", nameof(idCardPrefix17));
}
// 1. 计算加权和
int sum = 0;
for (int i = 0; i < 17; i++)
{
// 将字符转换为数字(char转int需减去'0'的ASCII值)
int digit = idCardPrefix17[i] - '0';
sum += digit * WeightFactors[i];
}
// 2. 计算模11的余数
int remainder = sum % 11;
// 3. 映射得到校验码
return CheckCodeMap[remainder];
}
/// <summary>
/// 补全17位身份证前缀为完整的18位身份证号码
/// </summary>
/// <param name="idCardPrefix17">17位身份证前缀</param>
/// <returns>18位身份证号码</returns>
/// <exception cref="ArgumentException">前缀不合法时抛出异常</exception>
public static string CompleteIdCardNumber(string idCardPrefix17)
{
char checkCode = CalculateCheckCode(idCardPrefix17);
return idCardPrefix17 + checkCode;
}
#endregion
#region 私有辅助方法
/// <summary>
/// 验证身份证号码的格式是否合法(18位、前17位数字、第18位数字或X)
/// </summary>
/// <param name="idCardNumber">身份证号码</param>
/// <returns>格式是否合法</returns>
private static bool IsIdCardFormatValid(string idCardNumber)
{
if (string.IsNullOrEmpty(idCardNumber) || idCardNumber.Length != 18)
{
return false;
}
// 正则匹配:前17位为数字,第18位为数字或大写X
string pattern = @"^\d{17}[\dX]$";
return Regex.IsMatch(idCardNumber, pattern);
}
/// <summary>
/// 验证身份证号码的校验码是否正确
/// </summary>
/// <param name="idCardNumber">18位身份证号码</param>
/// <returns>校验码是否正确</returns>
private static bool IsCheckCodeValid(string idCardNumber)
{
// 提取前17位
string prefix17 = idCardNumber.Substring(0, 17);
// 计算应有的校验码
char expectedCheckCode = CalculateCheckCode(prefix17);
// 提取实际的第18位(统一转为大写,兼容小写x)
char actualCheckCode = char.ToUpper(idCardNumber[17]);
return expectedCheckCode == actualCheckCode;
}
/// <summary>
/// 判断字符串是否全部为数字
/// </summary>
/// <param name="input">输入字符串</param>
/// <returns>是否全部为数字</returns>
private static bool IsAllDigits(string input)
{
foreach (char c in input)
{
if (!char.IsDigit(c))
{
return false;
}
}
return true;
}
#endregion
}
}使用示例
// 示例1:计算17位前缀的校验码
string prefix17 = "21041419010306091";
char checkCode = IdCardValidationHelper.CalculateCheckCode(prefix17);
MessageBox.Show($"17位前缀【{prefix17}】的校验码是:{checkCode}");
// 示例2:补全为18位身份证号码
string fullIdCard = IdCardValidationHelper.CompleteIdCardNumber(prefix17);
MessageBox.Show($"完整的身份证号码:{fullIdCard}");
// 示例3:验证身份证号码的合法性
string testIdCard = "210414190103060911"; // 合法号码
bool isValid = IdCardValidationHelper.IsValidIdCard(testIdCard);
MessageBox.Show($"身份证号码【{testIdCard}】是否合法:{isValid}");
string invalidIdCard = "210414190103060916"; // 非法号码(校验码错误)
bool isInvalid = IdCardValidationHelper.IsValidIdCard(invalidIdCard);
MessageBox.Show($"身份证号码【{invalidIdCard}】是否合法:{isInvalid}");本文来自 www.luofenming.com