haizlin/fe-interview

[js] 第20天 写一个验证身份证号的方法

haizhilin2013 opened this issue · 12 comments

第20天 写一个验证身份证号的方法

分析:身份证号码的组成:地址码6位+年份码4位+月份码2位+日期码2位+顺序码3位+校验码1位

function check(val){
    var reg=/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(10|20|30|31))\d{3}[0-9Xx]$/;
     return reg.test(val);
}

检测省份码
function checkProvice(val)
{
    var patten=/^[1-9][0-9]/;
    if(patten.test(val))
    {
        var prov={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:"**",81:"香港",82:"澳门",83:"**"};
        if(prov[val])
        {
            return true;
        };
    }


   return false;
}


检测出生日期
function checkBirthDay(val)
{
    var patten=/^(19|20)\d{2}((0[1-9])|1[0-2])(([0-2][1-9])|(10|20|30|31))/;
    if(patten.test(val))
    {
        var year=val.substring(0,4);
        var month=val.substring(4,6);
        var day=val.substring(6,8);
         
        var date=new Date(year+"-"+month+"-"+day);
        if(date&&date.getMonth()==(parseInt(month)-1))
        {
            return true;
        }
 
    }
    return false;
}

检测校验码
function checkVerifyCode(val)
{
    var patten=/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(10|20|30|31))\d{3}[0-9X]$/;
    var ratio=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
    var codeArr=[1,0,"X",9,8,7,6,5,4,3,2];
    var code=val.substring(17);
    if(patten.test(val))
    {
        var sum=0;
        for(var i=0;i<17;i++)
        {
            sum+=val[i]*ratio[i];
        }
        console.log(sum)
        var remainder=sum%11;
        if(codeArr[remainder]==code)
        {
            return true;
        }
    }
    return false;
}

function checkIndetityCardNo(val){
    var province=val.substring(0,2);
    if(checkProvice(province))
    {
         var date=val.substring(6,14);
         if(checkBirthDay(date))
         { 
             return checkVerifyCode(val);
         }
    }
    return false;
}

不是很清楚 身份证号码的规则 写不出来正则

  1. 粗暴型: 只考虑位数、最后的 x \d{17}[\dXx]
  2. 一般型:
  • 前 6 位区号 \d{6}
  • 中间年份 \d{4} 可以增加年份判断
  • 月份 01-12 月 0[1-9]|1[0-2]
  • 日期 01-31 日 0[1-9]|[12][0-9]|3[01]
  • 顺序码 \d{3}
  • 校验码 [\dXx] 其实有校验算法,可以根据算法再做一次检查 https://zhuanlan.zhihu.com/p/21286417
const isValidIdentity = (id) => {
  if (
    /^\d{6}\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[\dXx]$/.test(id)
  ) {
    return true;
  } else {
    return false;
  }
};

console.log(isValidIdentity(123456789012345678));
console.log(isValidIdentity(123456190011301234));
console.log(isValidIdentity("123456190013301234"));
console.log(isValidIdentity("123456190010321234"));
console.log(isValidIdentity('12345619001130123x'));
console.log(isValidIdentity('12345619001130123X'));
const isValidID = (id)=> {
   var id_reg = /^\d{6}(1[8-9]|2[0-9])\d{2}(0[1-9]|1[0-2])([012][0-9]|3[01])\d{3}[\dXx]$/
   return id_reg.test(id)? true:false
}

这个不清楚规则

不太清楚规则
var reg=/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(10|20|30|31))\d{3}[0-9Xx]$/;
reg.test(val);
还是贴个上面的答案把

function fn(x) {
            return /^\d{6}\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[\dXx]$/.test(x) ? true : false;
        }

粗暴型: 只考虑位数、最后的 x \d{17}[\dXx]
一般型:
前 6 位区号 \d{6}
中间年份 \d{4} 可以增加年份判断
月份 01-12 月 0[1-9]|1[0-2]
日期 01-31 日 0[1-9]|[12][0-9]|3[01]
顺序码 \d{3}
校验码 [\dXx] 其实有校验算法,可以根据算法再做一次检查 https://zhuanlan.zhihu.com/p/21286417
const isValidIdentity = (id) => {
if (
/^\d{6}\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[\dXx]$/.test(id)
) {
return true;
} else {
return false;
}
};

console.log(isValidIdentity(123456789012345678));
console.log(isValidIdentity(123456190011301234));
console.log(isValidIdentity("123456190013301234"));
console.log(isValidIdentity("123456190010321234"));
console.log(isValidIdentity('12345619001130123x'));
console.log(isValidIdentity('12345619001130123X'));

还有15位的身份证。。。

function checkIndetityCard(val) {
    let province = val.toString().substring(0, 2);

    if (checkProvince(province)) {
        let date = val.substring(6, 14);
        if (checkBirthday(date)) {
            return checkVerifyCode(val);
        }
    }

    return false;
}

// 验证省份
function checkProvince(val) {
    let reg = /^[1-9][0-9]/;
    if (reg.test(val)) {
        let province ={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:"**",81:"香港",82:"澳门",83:"**"};
        if (provence[val]) {
            return true;
        }
    }
    return false;
}

// 检测出生日期
function checkBirthday(val) {
    let reg = /^(19|20)\d{2}((0[1-9])|1(0-2))(([0-2][1-9])|(10|20|30|31))/;
    if (reg.test(val)) {
        let year = val.substring(0, 4);
        let month = val.substring(4, 6);
        let day = val.substring(6, 8);
        let date = new Date(year + "-" + month + "-" + day);
        if (date && date.getMonth() + 1 == parseInt(month)) {
            return true;
        }
    }
    return false;
}

// 检测校验码
function checkIndetityCard(val) {
    let reg =
        /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(10|20|30|31))\d{3}[0-9X]$/;
    let ratio = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    let codeArr = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
    let code = val.substring(17);
    if (reg.test(val)) {
        let sum = 0;
        for (let i = 0; i < 17; i++) {
            sum += val[i] * ratio[i];
        }
        if (codeArr[sum % 11] == code) {
            return true;
        }
    }
    return false;
}

简易写法
function IsUserID(data){
let reg = /\d{17}[\dXx]/g;
return reg.test(data);
}

function checkIndetityCard(val) {
    let province = val.toString().substring(0, 2);

    if (checkProvince(province)) {
        let date = val.substring(6, 14);
        if (checkBirthday(date)) {
            return checkVerifyCode(val);
        }
    }

    return false;
}

// 验证省份
function checkProvince(val) {
    let reg = /^[1-9][0-9]/;
    if (reg.test(val)) {
        let province ={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:"**",81:"香港",82:"澳门",83:"**"};
        if (provence[val]) {
            return true;
        }
    }
    return false;
}

// 检测出生日期
function checkBirthday(val) {
    let reg = /^(19|20)\d{2}((0[1-9])|1(0-2))(([0-2][1-9])|(10|20|30|31))/;
    if (reg.test(val)) {
        let year = val.substring(0, 4);
        let month = val.substring(4, 6);
        let day = val.substring(6, 8);
        let date = new Date(year + "-" + month + "-" + day);
        if (date && date.getMonth() + 1 == parseInt(month)) {
            return true;
        }
    }
    return false;
}

// 检测校验码
function checkIndetityCard(val) {
    let reg =
        /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(10|20|30|31))\d{3}[0-9X]$/;
    let ratio = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    let codeArr = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
    let code = val.substring(17);
    if (reg.test(val)) {
        let sum = 0;
        for (let i = 0; i < 17; i++) {
            sum += val[i] * ratio[i];
        }
        if (codeArr[sum % 11] == code) {
            return true;
        }
    }
    return false;
}

mark一下。