- 注册时间
- 2021-11-19
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 9194
- 在线时间
- 小时
|
发表于 2025-3-5 13:55:00
|
显示全部楼层
- (*
- 函数功能:
- 该函数用于全面检验中国身份证号码的有效性,包括校验码是否正确、出生年份是否在合理范围内(1900至2100年)、
- 月份和日期是否符合实际情况。中国身份证号码由17位数字本体码和1位校验码组成。
- 校验码的计算方法是:将前17位数字分别乘以对应的加权因子(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2),
- 然后将乘积相加,再对结果取模11,根据模值得到对应的校验码字符(模值为0对应X,模值为1对应1,以此类推),
- 最后与输入的身份证号码的最后一位进行比较,判断校验码是否正确。
- 函数用法:
- IsValidIDCard[cardID],传入一个字符串类型的身份证号码,函数将返回一个布尔值,
- 表示该身份证号码是否有效。
- 输入参数:
- - cardID:类型为字符串(String,或者18位整数),意义是输入的中国身份证号码,长度应为18位。
- 返回值:
- - 类型为布尔值(Boolean),意义是如果输入的身份证号码完全有效,返回True;否则返回False。
- 示例:
- 1. IsValidIDCard["11010519491231002X"],返回True,因为这是一个完全有效的身份证号码。
- 2. IsValidIDCard["11010521011231002X"],返回False,因为出生年份超出合理范围。
- 3. IsValidIDCard["11010519491331002X"],返回False,因为月份不符合实际。
- 4. IsValidIDCard["11010519491232002X"],返回False,因为日期不符合实际。
- 5. IsValidIDCard["110105194912310021"],返回False,因为这是一个校验码错误的身份证号码。
- *)
- IsValidIDCard[cardID_] :=
- Module[{weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2},(*前17位权重*)
- checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"},(*0 1 2 3等余数所对应的校验码*)
- sum, remainder, checkDigit, year, month, day, dateValid,cardNumber},
- If[IntegerQ[cardID],cardNumber=ToString[cardID],cardNumber=cardID];(*如果身份证号码是18位整数,则转化为字符串*)
- If[StringLength[cardNumber] != 18,
- Return[False]];
- (* 计算前17位数字与加权因子的乘积之和 *)
- sum = 0;
- For[i = 1, i <= 17, i++,
- digit = FromDigits[StringTake[cardNumber, {i}]];(*此处有bug,原本是StringTake[cardNumber,i],表示提取前i个字符,而此处需要是第i个字符*)
- sum = sum + digit * weights[[i]];
- ];
- remainder = Mod[sum, 11];(*求余数*)
- checkDigit = StringTake[cardNumber, -1];(*提取最后一位校验码*)
- (* 提取出生年份、月份和日期 *)
- year = FromDigits[StringTake[cardNumber, {7, 10}]];
- month = FromDigits[StringTake[cardNumber, {11, 12}]];
- day = FromDigits[StringTake[cardNumber, {13, 14}]];
- (* 初始化日期有效性为True,然后根据条件修改 *)
- dateValid = True;
- If[year < 1900 || year > 2100, dateValid = False];
- If[month < 1 || month > 12, dateValid = False];
- If[(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day < 1 || day > 31), dateValid = False];
- If[(month == 4 || month == 6 || month == 9 || month == 11) && (day < 1 || day > 30), dateValid = False];
- If[month == 2,
- If[(Mod[year, 4] == 0 && Mod[year, 100] != 0) || Mod[year, 400] == 0,
- If[(day < 1 || day > 29), dateValid = False],
- If[(day < 1 || day > 28), dateValid = False]
- ]
- ];
- (* 综合校验码和日期有效性判断身份证是否有效 *)
- dateValid && (checkDigit === checkCodes[[remainder + 1]])
- ];
复制代码
根除身份证号码是整数的bug |
|