js校验用户身份证省市区年龄性别

一般正则校验不够严谨,只能比较泛泛,有的只校验长度

常规正则:/^(\d){17}([0-9xX])$/.test(code)
// code 身份证号码

本校验可以校验:格式、省市区、年龄、年月日、平闰年算法、末位校验
废话不多说,看代码:

const WI = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];

const VI = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];

const AI = [];

const AREA_CODE = ["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","91"];

const DAYS = [31, undefined, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

const dateMap = new Map();
const areaCodeMap = new Map();

let message = "";

(() => {
  dateMap.clear();
  DAYS.forEach((value, index) =>
    dateMap.set(`${index > 8 ? index + 1 : "0" + (index + 1)}`, value)
  );

  areaCodeMap.clear();
  AREA_CODE.forEach((value) => areaCodeMap.set(value, undefined));
})();

function verifyCodeType(code) {
  if (typeof code === "undefined" || code === null || `${code}`.length < 1) {
    message = "错误:未输入身份证号码";
    return false;
  }
  return true;
}

function verifyLength(code) {
  if (`${code}`.length !== 18) {
    message = "错误:身份证号码不是 18 位";
    return false;
  }
  return true;
}

function verifyRegex(code) {
  if (!/^(\d){17}([0-9xX])$/.test(code)) {
    message = "错误:身份证号码格式不正确";
    return false;
  }
  return true;
}

function verifyAreaCode(code) {
  const areaCode = `${code}`.substr(0, 2);
  if (!areaCodeMap.has(areaCode)) {
    message = `错误:输入的身份证号的地区码(1-2 位)[${areaCode}] 不符合中国行政区划分代码规定 (GB/T2260-1999)`;
    return false;
  }
  return true;
}

function verifyBirthdayCode(code) {
  const year = parseInt(code.substr(6, 4));
  const month = code.substr(10, 2);
  const day = parseInt(code.substr(12, 2));
  const currYear = new Date().getFullYear();
  const compareYear = 2021;
  const maxYear = Math.max(currYear, compareYear);
  if (year < 1900 || year > maxYear) {
    message = `错误:输入的身份证号(7-10 位)[${year}] 不符合要求`;
    return false;
  }
  if (!dateMap.has(month)) {
    message = `错误:输入的身份证号(11-12 位)"不存在[${month}]月份,不符合要求(GB/T7408)`;
    return false;
  }
  const maxDay = dateMap.get(month);
  if (maxDay) {
    if (day > maxDay || day < 1) {
      message = `错误:输入的身份证号(13-14位)[${day}] 不符合小月 1-30 天、大月 1-31 天的规定(GB/T7408)`;
      return false;
    }
  } else {
    if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
      if (day > 29 || day < 1) {
        message = `错误:输入的身份证号(13-14位)[${day}] 在闰年的情况下不符合 1-29 天的规定(GB/T7408)`;
        return false;
      }
    } else {
      if (day > 28 || day < 1) {
        message = `错误:输入的身份证号(13-14位)[${day}] 在闰年的情况下不符合 1-28 天的规定(GB/T7408)`;
        return false;
      }
    }
  }
  return true;
}

function getVerify(code) {
  let remaining = 0;
  const temp = code.substr(0, 17);
  let sum = 0;
  [...temp].forEach((value, index) => {
    AI[index] = parseInt(value);
    sum += WI[index] * AI[index];
  });
  remaining = sum % 11;
  return remaining === 2 ? "X" : VI[remaining] + "";
}

function verifyMOD(code) {
  const verifyCode = code.substr(-1).toUpperCase();
  if (verifyCode === getVerify(code)) return true;
  message = `错误:输入的身份证号最末尾的数字验证码错误`;
  return false;
}

function verify(code) {
  message = "";
  const tempCode = `${code}`.trim()

  if (!verifyCodeType(tempCode)) return false;
  if (!verifyLength(tempCode)) return false;
  if (!verifyRegex(tempCode)) return false;
  if (!verifyAreaCode(tempCode)) return false;
  if (!verifyBirthdayCode(tempCode)) return false;
  if (!verifyMOD(tempCode)) return false;
  return true;
}

export { verify as verifyIDCard, message as IDCardErrorMessage };

调用:

//引用:
import {verifyIDCard, IDCardErrorMessage} from './tool.js';

//使用:号码字符串--正常 、数字--不正常
console.log(verifyIDCard("111111111111111111"), IDCardErrorMessage)

//说明:
verifyIDCard("xxx"):返回true 或者false 用于判断是否通过校验。xxx 为字符串
IDCardErrorMessage:返回错误时,对应的提示


到处,校验已经完结。比常规校验要全面,缺点是有点长。有资格的公司可以调用工安系统校验,有点费,将近一块钱一次,但是比较准确能匹配到名字和号码。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值