代码写的是好,但是有bug。
(*
函数功能:
该函数用于全面检验中国身份证号码的有效性,包括校验码是否正确、出生年份是否在合理范围内(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:类型为字符串(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 :=
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,cardNumber=ToString,cardNumber=cardID];(*如果身份证号码是18位整数,则转化为字符串*)
If != 18,
Return];
(* 计算前17位数字与加权因子的乘积之和 *)
sum = 0;
For[i = 1, i <= 17, i++,
digit = FromDigits];(*此处有bug,原本是StringTake,表示提取前i个字符,而此处需要是第i个字符*)
sum = sum + digit * weights[];
];
remainder = Mod;(*求余数*)
checkDigit = StringTake;(*提取最后一位校验码*)
(* 提取出生年份、月份和日期 *)
year = FromDigits];
month = FromDigits];
day = FromDigits];
(* 初始化日期有效性为True,然后根据条件修改 *)
dateValid = True;
If;
If;
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 == 0 && Mod != 0) || Mod == 0,
If[(day < 1 || day > 29), dateValid = False],
If[(day < 1 || day > 28), dateValid = False]
]
];
(* 综合校验码和日期有效性判断身份证是否有效 *)
dateValid && (checkDigit === checkCodes[])
];
根除身份证号码是整数的bug " 函数功能:
" 该函数用于检验身份证号码的校验码是否正确,并且检查身份证号码中包含的出生日期是否合法。
" 合法的年份范围在1900年到2500年之间,同时会检查每个月的天数是否符合实际情况(如2月在平年有28天,闰年有29天等)。
" 函数用法:
" 调用函数时,传入一个字符串类型的身份证号码作为参数,函数会返回一个布尔值,
" 如果身份证号码校验码正确且日期合法则返回 1,否则返回 0。
" 输入参数:
" id_card_number:字符串类型,代表输入的身份证号码,长度应为18位。
" 返回值:
" 返回值为数值类型(0 或 1)。1 表示身份证号码校验码正确且日期合法,0 表示校验码错误或日期不合法。
" 输入值返回值例子:
" 例子1:输入一个正确的身份证号码(校验码正确且日期合法),函数返回 1。
" 例子2:输入一个校验码错误的身份证号码,函数返回 0。
" 例子3:输入一个日期不合法(年份不在1900到2500之间)的身份证号码,函数返回 0。
" 例子4:输入一个日期不合法(如2月有30天)的身份证号码,函数返回 0。
function! CheckIDCard(id_card_number)
" 定义权重数组,用于计算校验码
let weights =
" 定义校验码字符数组,对应不同的校验码值,兼容x和X
let check_codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
" 检查身份证号码长度是否为18位
if strlen(a:id_card_number) != 18
return 0
endif
" 计算校验码
let sum = 0
for i in range(0, 16)
let num = str2nr(substitute(a:id_card_number, '\D', '', ''))
let sum += num * weights
endfor
let check_index = sum % 11
let check_code = check_codes
" 转换输入身份证号码最后一位为大写,以便和校验码比较
let input_check_code = toupper(a:id_card_number)
" 检查校验码是否正确
if check_code != input_check_code
return 0
endif
" 提取身份证号码中的年份、月份、日期信息
let year_str = a:id_card_number
let year = str2nr(year_str)
let month_str = a:id_card_number
let month = str2nr(month_str)
let day_str = a:id_card_number
let day = str2nr(day_str)
" 检查年份是否在合法范围内
if year < 1900 || year > 2500
return 0
endif
" 检查月份是否在1到12之间
if month < 1 || month > 12
return 0
endif
" 定义每个月的天数数组,2月先按平年算
let days_in_month =
" 判断是否为闰年,如果是,2月有29天
if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
let days_in_month = 29
endif
" 检查日期是否在合法范围内
if day < 1 || day > days_in_month
return 0
endif
" 如果校验码正确且日期合法,返回 1
return 1
endfunction 本帖最后由 nyy 于 2025-3-5 22:04 编辑
nyy 发表于 2025-3-5 16:18
idCardVerify :=
Module[{weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2},
checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}},
If != 18, False,
Total, weights}]] //
Mod[#, 11] & // (checkCodes[[# + 1]] == StringTake) &
]
]
人工智能写的代码真短,但是我不知道他写的对不对
idCardVerify :=
Module[{weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2},
checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}},
If!= 18, False,
Total, weights}]] //
Mod[#, 11] & // (checkCodes[[# + 1]] == StringTake) &
]
] IDCheck:=With[{check=Mod]]]*{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},11],11]},check==Switch],"X",10,_,ToExpression]]]]
人工智能写的代码都让人讨厌
这个是deepseek写的 nyy 发表于 2025-3-5 22:13
IDCheck:=With[{check=Mod]]]*{7,9,10,5,8,4, ...
第1行应该是12-,而不是11-,人工智能就喜欢制造bug nyy 发表于 2025-3-5 22:27
第1行应该是12-,而不是11-,人工智能就喜欢制造bug
人工智能真的有些智能,
我基本上每天都用人工智能
哪怕是和人工智能聊聊天 nyy 发表于 2025-3-5 22:13
IDCheck:=With[{check=Mod]]]*{7,9,10,5,8,4, ...
IDCheck:=With[{check=Mod[]*{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}],11]},check==Switch[],"X",10,_,ToExpression[]]]]
这个是根除代码后的代码,还优化了一下 nyy 发表于 2025-3-6 09:02
这个是根除代码后的代码,还优化了一下
IDCheck := Module[
{weights, checkCode, sum, remainder, calculatedCheck,idlist},
(* 定义权重系数 *)
weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
(*形成18位字符列表*)
idlist=Characters;
(* 提取前17位并转换为数字列表 *)
sum = Total]]*weights];
(* 计算余数 *)
remainder = Mod;
(* 计算校验码 *)
calculatedCheck = Mod;
(* 处理最后一位校验码(如果是X,则转换为10) *)
checkCode=Switch],
"X", 10,
"x", 10,(*小写字母也加上*)
_, ToExpression]]
];
(* 比较计算值与实际校验码 *)
calculatedCheck == checkCode
]
deepseek写的代码,被我根除bug,以及优化后的代码! 人工智能写的代码,经过我的稍微修改与美化与完善,加上生成的测试用例(人工智能生成的测试用例,居然也用错误!)
" 函数功能:
" 该函数用于检验身份证号码的校验码是否正确,并且检查身份证号码中包含的出生日期是否合法。
" 合法的年份范围在1900年到2500年之间,同时会检查每个月的天数是否符合实际情况(如2月在平年有28天,闰年有29天等)。
" 函数用法:
" 调用函数时,传入一个字符串类型的身份证号码作为参数,函数会返回一个布尔值,
" 如果身份证号码校验码正确且日期合法则返回 1,否则返回 0。
" 输入参数:
" id_card_number:字符串类型,代表输入的身份证号码,长度应为18位。
" 返回值:
" 返回值为数值类型(0 或 1)。1 表示身份证号码校验码正确且日期合法,0 表示校验码错误或日期不合法。
" 输入值返回值例子:
" 例子1:输入一个正确的身份证号码(校验码正确且日期合法),函数返回 1。
" 例子2:输入一个校验码错误的身份证号码,函数返回 0。
" 例子3:输入一个日期不合法(年份不在1900到2500之间)的身份证号码,函数返回 0。
" 例子4:输入一个日期不合法(如2月有30天)的身份证号码,函数返回 0。
function! CheckIDCard(id_card_number)
"默认的信息输出间隔符号
echo "-------------------------------------------------\n"
"先给出默认返回值1,如果有错误,则修改成0
let out=1
" 定义权重数组,用于计算校验码
let weights =
" 定义校验码字符数组,对应不同的校验码值,兼容x和X
let check_codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
" 检查身份证号码长度是否为18位
if strlen(a:id_card_number) != 18
echo "身份证号码必须18位字符串\n"
let out=0
return out
endif
" 计算校验码
let sum = 0
for i in range(0, 16)
let num = str2nr(a:id_card_number)
let sum += num * weights
endfor
let check_index = sum % 11
let check_code = check_codes
" 转换输入身份证号码最后一位为大写,以便和校验码比较
let input_check_code = toupper(a:id_card_number)
" 检查校验码是否正确
if check_code != input_check_code
echo "第18位校验码应该是".check_code."\n"
let out=0
endif
" 提取身份证号码中的年份、月份、日期信息
let year = str2nr(a:id_card_number)
let month = str2nr(a:id_card_number)
let day = str2nr(a:id_card_number)
" 检查年份是否在合法范围内
if year < 1900 || year > 2500
echo "年份需要在1900-2500年之间\n"
let out=0
endif
" 检查月份是否在1到12之间
if month < 1 || month > 12
echo "月份不合法!\n"
let out=0
endif
" 定义每个月的天数数组,2月先按平年算
let days_in_month =
" 判断是否为闰年,如果是,2月有29天
if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
let days_in_month = 29
endif
" 检查日期是否在合法范围内
if day < 1 || day > days_in_month
echo "日期不合法!\n"
let out=0
endif
" 如果校验码正确且日期合法,返回 1
return out
endfunction
" 测试用例 1:正确的身份证号码 预期输出: 1
let test_id1 = '11010519491231002X'
echo CheckIDCard(test_id1)
" 测试用例 2:校验码错误的身份证号码 预期输出: 0
let test_id2 = '110105194912310021'
echo CheckIDCard(test_id2)
" 测试用例 3:年份小于 1900 的身份证号码 预期输出: 0
let test_id3 = '11010518991231002X'
echo CheckIDCard(test_id3)
" 测试用例 4:年份大于 2500 的身份证号码 预期输出: 0
let test_id4 = '11010525011231002X'
echo CheckIDCard(test_id4)
" 测试用例 5:身份证号码长度错误 预期输出: 0
let test_id5 = '11010519491231002'
echo CheckIDCard(test_id5)
" 测试用例 6:2月有29天的闰年身份证号码 预期输出: 0
let test_id6 = '310109202002290011'
echo CheckIDCard(test_id6)
" 测试用例 7:2月有28天的平年身份证号码 预期输出: 0
let test_id7 = '310109202102280011'
echo CheckIDCard(test_id7)
" 测试用例 8:2月有30天的非法日期身份证号码 预期输出: 0
let test_id8 = '310109202102300011'
echo CheckIDCard(test_id8)
" 测试用例 9:月份为0的非法日期身份证号码 预期输出: 0
let test_id9 = '310109202100300011'
echo CheckIDCard(test_id9)
" 测试用例 10:日期为0的非法日期身份证号码 预期输出: 0
let test_id10 = '310109202101000011'
echo CheckIDCard(test_id10)
nyy 发表于 2025-3-6 15:16
人工智能写的代码,经过我的稍微修改与美化与完善,加上生成的测试用例(人工智能生成的测试用例,居然也用 ...
还可以继续优化!把所有的错误信息连接成一个字符串,这样方便调试测试!
页:
1
[2]