1、居民身份证号码的结构(转自百度百科)
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
-
地址码:表示编码对象常住户口所在县(县级市、旗、区)的行政区划代码。
-
八位数出生日期码:表示编码对象出生的年、月、日。
-
顺序码:表示在同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。
-
校验码:根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
-
计算方法:
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。
-
2、正则表达式以及详解
1、用起始标志“^”和结束标志"$"把身份证号限定在18位
2、地址码(6位):[1-9]\d{5}
- 六位数字,第一位不可以为0
- 后五位可以是0-9任意数字
3、出生日期码(8位):(18|19|20)\d{2}(0[1-8]|1[0-2])(0[1-9]|[12][0-9]|3[01])
- 年份范围:1800~2099
- 月份范围:01~12
- 日范围:01~31
4、顺序码(三位):\d{3}
- 三位任意数字
5、校验码(一位):[0-9xX]
- 任意数字或x或X
所以最终的正则表达式为:
^[1-9]\d{5}(18|19|20)\d{2}(0[1-8]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[0-9xX]$
存在不足之处
- 地址码前两位可以精确定位省份或者直辖市,该式未能精确匹配
- 某些月份没有29,30,31日,但是仍然能匹配成功
- 未能用最后一位校验位检验这是否是一个正确的身份证号
下次有空写个程序解决一下这个问题