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

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

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

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

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

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

GB11643-1999_公民身份号码_校验码
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.log(`
		<MOD11-2.js>
		error:     传入参数长度有误
		parameter: id = ${id}
		require:   id.length == ${18}
		found:     id.length == ${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])) {
			console.log(`
			<MOD11-2.js>
			error:     传入参数存在无法解析的非数字字符
			parameter: id = ${id}
			require:   isNaN(id) == ${false}
			found:     isNaN(id) == ${true}
			`);
			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.log(`
		<MOD11-2.js>
		error:     未通过MOD11-2校验
		parameter: id = ${id}
		require:   id[18] == ${checkCode}
		found:     id[18] == ${idList[17]}
		`);
	} else {
		console.log(`
		<MOD11-2.js>
		success:   通过MOD11-2校验
		parameter: id = ${id}
		require:   id[18] == ${checkCode}
		found:     id[18] == ${idList[17]}
		`);
	}
	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];
};

版权声明:本文为qq_25619143原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。