[程序设计]前端Web页面使用原生JavaScript实现校验身份证号码在算法层面是否合法

中国大陆居民身份证号码第18位为校验码,用来验证本体码的准确性

校验码采用ISO 7064:1983,MOD 11-2校验码系统。

因此可以对身份证号码第18位进行校验,来验证身份证号码在算法层面是否合法

由于校验码系统算法的原因,如果身份证号码前17位中有多位错误,仍有可能通过验证

GB11643-1999中对校验码描述如下图

GB11643-1999:5.1.4
JavaScript实现代码如下

开发版本

/*
 * File: MOD11-2.js
 * Author: 张泽楠
 * Copyright ©2020 张泽楠, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 * Time: 2020-‎11‎-‎8‎ 18:25
 */

/*
 * ISO 7064:1983,MOD 11-2 校验码系统
 * 
 * @param: 
 * 			id	待校验身份证号码,请使用字符串传入
 * @return: 
 * 			ture	通过MOD11-2校验
 * 			false	未通过MOD11-2校验
 * 			NaN		传入参数存在无法解析的非数字字符
 * 			-1		传入参数长度有误
 */

function MOD11_2(id) {
	/*
	 * ISO 7064:1983,MOD 11-2 校验码系统的校验算法
	 * 
	 *  i: 位置索引
	 * wi: 权重
	 * ai: 身份证号码(身份证号码中使用罗马数字"Ⅹ"代替数字10)
	 * 
	 * 权重wi: 
	 * wi = 2^(18-i) mod 11
	 * 
	 * 校验码a18: 
	 * ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
	 * │i │1 │2 │3 │4 │5 │6 │7 │8 │9 │10│11│12│13│14│15│16│17│18│
	 * ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
	 * │wi│7 │9 │10│5 │8 │4 │2 │1 │6 │3 │7 │9 │10│5 │8 │4 │2 │  │
	 * ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
	 * │ai│  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │
	 * └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
	 * 
	 * 计算公式:
	 *                ┌            ┐
	 *                │ 17         │ 
	 * a18 = ( 12 - ( │ ∑  (wi*ai) │ mod 11 ) ) mod 11
	 *                │ i=1        │
	 *                └            ┘
	 */

	// --------------- 判断传入参数长度 -----------------
	if (18 != id.length) {
		console.error(`
		<MOD11-2.js>
		error:     传入参数长度有误
		parameter: id = ${id}
		require:   id.length == ${18}
		found:     id.length == ${id.length}
		return:    -1
		`);
		return -1;
	}
	// --------------- 将字符串转换为数组 -----------------
	var idList = id.split('');
	if ('X' == idList[17] || 'x' == idList[17] || 'Ⅹ' == idList[17]) {
		idList[17] = '10'
	}

	for (var i = 0; i < 18; i++) {
		idList[i] = parseInt(idList[i]);
		if (isNaN(idList[i])) {
			console.error(`
		<MOD11-2.js>
		error:     传入参数存在无法解析的非数字字符
		parameter: id[${i+1}] = ${id[i]}
		require:   isNaN(id[${i+1}]) == ${false}
		found:     isNaN(id[${i+1}]) == ${true}
		return:    NaN
			`);
			return NaN;
		}
	}
	// --------------- 权重wi -----------------
	// wi只与位置索引有关,在此不做重复计算,直接声明weightList并赋值
	// var weightList = [];
	// for(var i=1; i<18; i++){
	// 	weightList.push((Math.pow(2, 18-i))%11);
	// }
	var weightList = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
	// --------------- 根据计算公式计算 -----------------
	var sum = 0;
	for (var i = 0; i < 17; i++) {
		sum += weightList[i] * idList[i];
	}
	var checkCode = sum % 11;
	checkCode = 12 - checkCode;
	checkCode %= 11;
	// --------------- 校验完成 -----------------
	if (checkCode != idList[17]) {
		console.error(`
		<MOD11-2.js>
		error:     未通过MOD11-2校验
		parameter: id = ${id}
		require:   id[18] == ${checkCode}
		found:     id[18] == ${idList[17]}
		return:    false
		`);
	} else {
		console.log(`
		<MOD11-2.js>
		success:   通过MOD11-2校验
		parameter: id = ${id}
		require:   id[18] == ${checkCode}
		found:     id[18] == ${idList[17]}
		return:    true
		`);
	}
	return checkCode == idList[17];
};

console.info(
`===============================================
File: MOD11-2.js
Author: 张泽楠
Copyright ©2020 张泽楠, All Rights Reserved
SPDX-License-Identifier: Apache-2.0
Time: 2020-‎11‎-‎8‎ 18:25
===============================================
function MOD11_2(id)
-----------------------------------------------
ISO 7064:1983,MOD 11-2 校验码系统
@param:
        id  待校验身份证号码,请使用字符串传入
@return:
        ture	通过MOD11-2校验
        false	未通过MOD11-2校验
        NaN		传入参数存在无法解析的非数字字符
        -1		传入参数长度有误
===============================================`);

生产版本

function MOD11_2(id) {
	/*
	 * File: MOD11-2.js
	 * Author: 张泽楠
	 * Copyright ©2020 张泽楠, All Rights Reserved
	 * SPDX-License-Identifier: Apache-2.0
	 * Time: 2020-‎11‎-‎8‎ 18:25
	 */
	if (18 != id.length) {
		return -1;
	}
	var idList = id.split('');
	if ('X' == idList[17] || 'x' == idList[17] || 'Ⅹ' == idList[17]) {
		idList[17] = '10'
	}
	for (var i = 0; i < 18; i++) {
		idList[i] = parseInt(idList[i]);
		if (isNaN(idList[i])) {
			return NaN;
		}
	}
	var weightList = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
	var sum = 0;
	for (var i = 0; i < 17; i++) {
		sum += weightList[i] * idList[i];
	}
	var checkCode = sum % 11;
	checkCode = 12 - checkCode;
	checkCode %= 11;
	return checkCode == idList[17];
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值