技术

前端身份证校验和个人信息数据模拟

微信扫一扫,分享到朋友圈

前端身份证校验和个人信息数据模拟
收藏 0 0

 

现在的网站、应用、APP只要用到用户信息,尤其是涉及到订票啊,付费之类的,都会让用户填写身份证号码,而关于身份证号码的校验工作,应该说校验程度比较高的就是四要素检测了,银行卡、身份证号码、手机号、姓名去做指定的API进行校验,一般都是付费的。

比如聚合API最便宜的是0.3元/次,管你校验通过不通过反正一次3毛钱。

还有上传身份证照片,使用图形识别技术识别出来进行校验。

当然,有的是费人工去检查对不对。

或者其他合作校验方式就各家归各家了。

只要没有去做付费四要素检测的话,剩下的就只能自己来检查是否有效了。简单的校验就只是校验位数,15位一代身份证,18位二代身份证。不过现在一代应该是很少了,本文只讨论二代身份证校验了。

身份证号码的组成

公民身份号码是特征组合码,排列顺序从左至右依次为:六位地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码

地址码

地址码是常住户口所在(县级市、旗、区)的行政区划代码,按GB/T2260的规定执行。更详细规则如下:

第一、二位表示省(自治区、直辖市、特别行政区)。

华北地区: 北京市|11,天津市|12,河北省|13,山西省|14,内蒙古自治区|15
东北地区: 辽宁省|21,吉林省|22,黑龙江省|23
华东地区: 上海市|31,江苏省|32,浙江省|33,安徽省|34,福建省|35,江西省|36,山东省|37
华中地区华南地区: 河南省|41,湖北省|42,湖南省|43, 广东省 |44,广西壮族自治区|45,海南省|46
西南地区: 四川省|51,贵州省|52,云南省|53,西藏自治区|54,重庆市|50
西北地区: 陕西省|61,甘肃省|62,青海省|63,宁夏回族自治区|64,新疆维吾尔自治区|65
台湾地区: 台湾省|71  (886)   (应该属于华东地区)
港澳地区: 香港特别行政区|81(852)  澳门特别行政区|82 (853)  (应该属于华南地区)

第三、四位表示市(地级市、自治州、地区、盟及直辖市所属区和县的汇总码)。其中,01-20,51-70表示地级市;21-50表示地区(自治州、盟)。
第五、六位表示县(区、县级市、旗)。01-18表示地级市、自治州、地区、盟辖县级市;21-80表示县(旗);81-99表示省直辖县级行政单位。

生日期码

(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。

顺序码

(身份证号码第十五位到十七位)地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。

校验码

作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且中国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
所以最起码从身份证号码里面可以看出来你原来的户籍所在地,出生年月日,性别信息。

校验码计算方法

1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2、将这17位数字和系数相乘的结果相加。
3、用加出来和除以11,看余数是多少?
4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X…)
5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。
例如:某男性的身份证号码为【53010219200508011X】, 我们看看这个身份证是不是合法的身份证。
首先我们得出前17位的乘积和【(5*7)+(3*9)+(0*10)+(1*5)+(0*8)+(2*4)+(1*2)+(9*1)+(2*6)+(0*3)+(0*7)+(5*9)+(0*10)+(8*5)+(0*8)+(1*4)+(1*2)】是189,然后用189除以11得出的结果是189/11=17—-2,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

es6的身份证校验函数

下面使用es6做的基于校验码简单的判断。想要更深层次的还可以对地址码和生日码都进行校验。

const idCardCheck6 = function(card){
    if(!card || card.length != 18){
        return false
    }
    let cards = card.toString().split('')
    let sign = (12 - cards.reduce((total,value,index)=>{
        return total + (index === 17 ? 0 : Math.pow(2,17-index) % 11 * value)
    },0) % 11 ) % 11
    sign = sign === 10 ? 'x' : sign
	console.log(sign)
    return cards[17] == sign
}

身份信息模拟数据

做开发或者做测试的时候,模拟数据的生成也是很必要的,不然每次都录入“111”,“222”,“测试”,“测试不要动”……的数据,看着界面实在是影响心情,尤其是强迫症还着。这时候,就可以根据身份证生成规则来生成个人信息了。包含姓名,电话,性别,身份证号码,生日,籍贯的生成了。

身份证号码模拟

身份号码模拟就是前面的地区前两位按照地区来模拟,中间四位暂时就纯随机了,有兴趣的话可以去差所有的区县标准数据了,生日码的话就按照现在时间的前一百年间的随机生日,当然也可以自行设置,3位顺序码也随机,纯随机,校验码根据前面随机生成的数据生成,然后组合就是了,注意输出的是字符串,数字的话会造成超出范围的数字类型错误显示的。

下面是简单的生成代码,讲身份信息做成对象来进行输出

const randomPerson = function(){
	let areas = {
        11:"北京市",12:"天津市",13:"河北省",14:"山西省",15:"内蒙古自治区",
        21:"辽宁省",22:"吉林省",23:"黑龙江省",
        31:"上海市",32:"江苏省",33:"浙江省",34:"安徽省",35:"福建省",36:"江西省",37:"山东省",
        41:"河南省",42:"湖北省",43:"湖南省",44:"广东省",45:"广西壮族自治区",46:"海南省",
        50:"重庆市",51:"四川省",52:"贵州省",53:"云南省",54:"西藏自治区",
        61:"陕西省",62:"甘肃省",63:"青海省",64:"宁夏回族自治区",65:"新疆维吾尔自治区",
        71:"台湾省",81:"香港特别行政区",82:"澳门特别行政区"
    }
	let areaIds = Object.keys(areas)
	let areasId = areaIds[Math.floor(Math.random()*areaIds.length)]
    let areaCode = Math.floor(Math.random() * 9999)
	let birthday = new Date(new Date().getTime() - Math.random() * 1000 * 60 * 60 * 24 * 365 * 100)
	let year = birthday.getFullYear()
	let month = birthday.getMonth() > 8 ?  birthday.getMonth()+1 : "0" + (birthday.getMonth()+1) 
    let day = birthday.getDate() > 9 ?  birthday.getDate() : "0" + birthday.getDate() 
    let seqCode = Math.floor(Math.random() * 999)
    let firstCard = areasId + areaCode + year + month + day + seqCode
	let sign = (12 - firstCard.split('').reduce((total,value,index)=>{
        return total + (index === 17 ? 0 : Math.pow(2,17-index) % 11 * value)
    },0) % 11 ) % 11
    sign = sign === 10 ? 'x' : sign
    return {
         area:areas[areasId],
         birthday:year + "-" + month + "-" + day,
         sex: seqCode % 2 === 1 ? "男":"女",
         idCard:firstCard + sign,
         age: new Date().getFullYear() - year
     }
}

对应生成的数据格式是这样的

{area: "香港特别行政区", birthday: "1982-11-05", sex: "女", idCard: "81463419821105826x", age: 37}

姓名生成

为了看着比较像正式的数据,姓名分开取用的比较多的字。比如姓,取不知道某年排行的国人
姓前100,“李王张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段漕钱汤尹黎易常武乔贺赖龚文”,然后从中来抓取随机抓取。
名字的话,也有个常用字排行 “英梅华兰珍芳伟军丽敏荣勇静燕娟婷强云杰平超红艳磊丹萍霞斌波玲涛明峰浩飞辉俊鑫鹏林慧颖洋国刚莉倩娜龙亮琴凯帅雪琳晶阳博兵洁芝宇宁健建岩帆瑞花佳香欢欣莹坤利旭文雷彬柳晨凤璐瑜畅玉想楠东杨成”
根据规则随机生成就是了。
下面是个简单的代码
const randomName = function(){
	let first = "李王张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段漕钱汤尹黎易常武乔贺赖龚文"
    let last = "英梅华兰珍芳伟军丽敏荣勇静燕娟婷强云杰平超红艳磊丹萍霞斌波玲涛明峰浩飞辉俊鑫鹏林慧颖洋国刚莉倩娜龙亮琴凯帅雪琳晶阳博兵洁芝宇宁健建岩帆瑞花佳香欢欣莹坤利旭文雷彬柳晨凤璐瑜畅玉想楠东杨成"
	let randomTxt = function(str){
		return str.charAt(Math.random()*str.length)
	}
	
	return randomTxt(first) + randomTxt(last) + (Math.random() > 0.3 ? randomTxt(last) : "")
}

手机号码生成

这个就简单一点,11位生成,目前的号段如下,更新潮的不追赶了,模拟嘛,前面取号段,后面号码随机,一拼结束。

移动号段:134 135 136 137 138 139 147 148 150 151 152 157 158 159  165 172 178 182 183 184 187 188 198

联通号段:130 131 132 145 146 155 156 166 171 175 176 185 186

电信号段:133 149 153 173 174 177 180 181 189  191  199

虚拟运营商: 170

随机个代码代码如下:
let randomPhone = function(){
	const head = [134,135,136,137,138,139,147,148,150,151,152,157,158,159 ,165,172,178,182,183,184,187,188,198,130,131,132,145,146,155,156,166,171,175,176,185,186,133,149,153,173,174,177,180,181,189,191,199,170]
	let cont = ""
	for(let i = 0; i<8; i++){
		cont += Math.floor(Math.random()*10)
	}
    return head[Math.floor(Math.random()*head.length)] + cont

}
然后把上面的信息合并到一起就基本上可以模拟个人信息数据了!
做个demo留着自己用,哈哈,地址: https://notes.tingno.com/demo/mock/person.html
文内部分内容来源网络
展开阅读全文
半拉子前端的自留地,发际线逐渐后移的抠脚大叔!

【填坑日记】Form Validate 多重复杂组件校验滞后

上一篇

从vue-test-utils入门前端单元测试

下一篇

你也可能喜欢

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00

      微信扫一扫

      微信扫一扫