- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章JavaScript+Regex 身份证号码的正则表达式及验证详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
简言 。
在做用户实名验证时,常会用到身份证号码的正则表达式及校验方案。本文列举了两种验证方案,大家可以根据自己的项目实际情况,选择适合的方案.
身份证号码说明 。
居民身份证号码,正确、正式的称谓应该是“公民身份号码”。根据【中华人民共和国国家标准 GB 11643-1999】中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码.
以北京市朝阳区一女性身份证号码为例,身份证号码所表示的含义如下图所示:
注:该身份证号码来源于国标【GB 11643-1999】.
下面我们就从零开始完成一个完整的身份证号码校验过程.
方案1 (简单) 。
1.1 分部规则 。
1.1.1 地址码规则: 地址码长6位 以数字1-9开头 后5位为0-9的数字 。
根据以上规则,写出地址码的正则表达式: /^[1-9]\d{5}/ 。
1.1.2 年份码规则: 年份码长4位 以数字18,19或20开头 剩余两位为0-9的数字 。
根据以上规则,写出年份码的正则表达式: /(18|19|20)\d{2}/。如果不需要18开头的年份,可以去掉18.
1.1.3 月份码规则: 月份码长2位 第一位数字为0,第二位数字为1-9 或者第一位数字为1,第二位数字为0-2 。
根据以上规则,写出月份码的正则表达式: /((0[1-9])|(1[0-2]))/.
1.1.4 日期码规则: 日期码长2位 第一位数字为0-2,第二位数字为1-9 或者是10,20,30,31 。
根据以上规则,写出日期码的正则表达式 :/(([0-2][1-9])|10|20|30|31)/.
1.1.5 顺序码规则: 顺序码长3位 顺序码是数字 。
根据以上规则,写出顺序码的正则表达式 :/\d{3}/.
1.1.6 校验码规则: 校验码长1位 可以是数字,字母x或字母X 。
根据以上规则,写出校验码的正则表达式 :/[0-9Xx]/.
1.2 方案1正则表达式 。
综合以上6条规则,给出完整的正则表达式及测试程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
//输出 true
console.log(p.test(
"11010519491231002X"
));
//输出 false 不能以0开头
console.log(p.test(
"01010519491231002X"
));
//输出 false 年份不能以17开头
console.log(p.test(
"11010517491231002X"
));
//输出 false 月份不能为13
console.log(p.test(
"11010519491331002X"
));
//输出 false 日期不能为32
console.log(p.test(
"11010519491232002X"
));
//输出 false 不能以a结尾
console.log(p.test(
"11010519491232002a"
));
|
1.3 方案1分析 。
方案1只是做了基本的格式判定,存在三个主要的不足: 地址码判定不够精确。例:我国并不存在16,26开头的地区,却可通过验证日期判定不够精确。例:19490231也可通过验证,而2月并不存在31日校验码是由17位本体码计算得出,方案1并未校验此码方案2 (全面) 根据方案1的不足,引入方案2进而改进方案1的不足.
2.1 省级地址码校验 。
华北:北京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,香港81,澳门82 。
根据上述地址码做身份证号码的前两位校验,进一步的提高准确率。当前的地址码以2013版的行政区划代码【GB/T2260】为标准。由于区划代码的历史演变,使得地址码后四位校验变得不太可能。以三胖的身份证号为例,本人号码是2321开头,而当前行政区划代码表中并无此代码。因此本文只做前两位省级地址码的校验.
也有说法表述91开头是外国人取得中国身份证号码的前两位编码,但本人并未得到证实。如有持91开头身份证或认识马布里的,请帮忙确认相关信息。 根据以上分析,给出省级地址码校验及测试程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
var
checkProv =
function
(val) {
var
pattern = /^[1-9][0-9]/;
var
provs = {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:
"澳门"
};
if
(pattern.test(val)) {
if
(provs[val]) {
return
true
;
}
}
return
false
;
}
//输出 true,37是山东
console.log(checkProv(37));
//输出 false,16不存在
console.log(checkProv(16));
|
2.2 出生日期码校验 。
出生日期码的校验不做解释,直接给出如下函数及测试程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var
checkDate =
function
(val) {
var
pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
if
(pattern.test(val)) {
var
year = val.substring(0, 4);
var
month = val.substring(4, 6);
var
date = val.substring(6, 8);
var
date2 =
new
Date(year+
"-"
+month+
"-"
+date);
if
(date2 && date2.getMonth() == (parseInt(month) - 1)) {
return
true
;
}
}
return
false
;
}
//输出 true
console.log(checkDate(
"20180212"
));
//输出 false 2月没有31日
console.log(checkDate(
"20180231"
));
|
2.3 校验码校验 。
校验码的计算略复杂,先给出如下公式:
其中 ai 表示身份证本体码的第 i 位值,而 Wi 表示第 i 位的加权因子值.
加权因子表 【表1】:
。
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
Wi | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
。
X与校验码换算表 【表2】 。
。
X | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
a18 | 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
。
算法过程:
校验码计算程序及测试见如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var
checkCode =
function
(val) {
var
p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
var
factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
var
parity = [ 1, 0,
'X'
, 9, 8, 7, 6, 5, 4, 3, 2 ];
var
code = val.substring(17);
if
(p.test(val)) {
var
sum = 0;
for
(
var
i=0;i<17;i++) {
sum += val[i]*factor[i];
}
if
(parity[sum % 11] == code.toUpperCase()) {
return
true
;
}
}
return
false
;
}
// 输出 true, 校验码相符
console.log(checkCode(
"11010519491231002X"
));
// 输出 false, 校验码不符
console.log(checkCode(
"110105194912310021"
));
|
2.4 方案2整体代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var
checkID =
function
(val) {
if
(checkCode(val)) {
var
date = val.substring(6,14);
if
(checkDate(date)) {
if
(checkProv(val.substring(0,2))) {
return
true
;
}
}
}
return
false
;
}
//输出 true
console.log(checkID(
"11010519491231002X"
));
//输出 false,校验码不符
console.log(checkID(
"110105194912310021"
));
//输出 false,日期码不符
console.log(checkID(
"110105194902310026"
));
//输出 false,地区码不符
console.log(checkID(
"160105194912310029"
));
|
以上为三胖对身份证号码验证的理解和分析,如有不足请大家予以指正.
原文链接:http://www.42du.cn/p/41 。
最后此篇关于JavaScript+Regex 身份证号码的正则表达式及验证详解的文章就讲到这里了,如果你想了解更多关于JavaScript+Regex 身份证号码的正则表达式及验证详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!