身份证验证 / 身份证提取生日等

/*
* IDValidator.js v1.2.0
* 中国身份证号验证 Chinese Personal ID Card Validation
* Author: mc@mc-zone.me
* E-mail: mc@mc-zone.me
* Released under the MIT license
*/

;(function(factory){

var isWindow = ( typeof window !== 'undefined'?true:false );
var global = ( isWindow ? window : this );

var instance = function(){ return factory(isWindow,global); };

// AMD / RequireJS
if (typeof define !== 'undefined' && define.amd) {
define('IDValidator', [], instance );
}
// CMD / Seajs
else if (typeof define === "function" && define.cmd) {
define( function(require, exports, module) {
module.exports = factory(isWindow,global);
});
}
// CommonJS
else if (typeof module !== 'undefined' && module.exports) {
module.exports = factory(isWindow,global);
}
else {
global.IDValidator = factory(isWindow,global);
}

})(function(isWindow,global){

var param = {
error:{
longNumber:'长数字存在精度问题,请使用字符串传值! Long number is not allowed, because the precision of the Number In JavaScript.'
}
};

var util = {
checkArg:function(id){
var argType = (typeof id);

switch( argType ){
case 'number':
//long number not allowed
id = id.toString();
if( id.length > 15 ){
this.error(param.error.longNumber);
return false;
}
break;
case 'string':
break;
default:
return false;
}

id = id.toUpperCase();

var code = null;
if( id.length === 18 ){
//18位
code = {
body : id.slice(0,17),
checkBit : id.slice(-1),
type : 18
};
}else if( id.length === 15 ){
//15位
code = {
body : id,
type : 15
};
}else{
return false;
}

return code;
}
//地址码检查
,checkAddr:function(addr,GB2260){
var addrInfo = this.getAddrInfo(addr,GB2260);
return ( addrInfo === false ? false : true );
}
//取得地址码信息
,getAddrInfo:function(addr,GB2260){
GB2260 = GB2260 || null;
//查询GB/T2260,没有引入GB2260时略过
if( GB2260 === null ){
return addr;
}
if( !GB2260.hasOwnProperty(addr) ){
//考虑标准不全的情况,搜索不到时向上搜索
var tmpAddr;
tmpAddr = addr.slice(0,4) + '00';
if( !GB2260.hasOwnProperty(tmpAddr) ){
tmpAddr = addr.slice(0,2) + '0000';
if( !GB2260.hasOwnProperty(tmpAddr) ){
return false;
}else{
return GB2260[tmpAddr] + '未知地区';
}
}else{
return GB2260[tmpAddr] + '未知地区';
}
}else{
return GB2260[addr];
}
}
//生日码检查
,checkBirth:function(birth){
var year, month, day;
if( birth.length == 8 ){
year = parseInt( birth.slice(0,4),10 );
month = parseInt( birth.slice(4,6),10 );
day = parseInt( birth.slice(-2),10 );
}else if( birth.length == 6 ){
year = parseInt( '19' + birth.slice(0,2),10 );
month = parseInt( birth.slice(2,4),10 );
day = parseInt( birth.slice(-2),10 );
}else{
return false;
}
// TODO 是否需要判断年份
/*
if( year<1800 ){
return false;
}
*/
//TODO 按月份检测
if( month > 12 || month === 0 || day > 31 || day === 0 ){
return false;
}

return true;
}
//顺序码检查
,checkOrder:function(order){
//暂无需检测

return true;
}
//加权
,weight:function(t){
return Math.pow(2,t-1)%11;
}
//随机整数
,rand:function(max,min){
min = min || 1;
return Math.round( Math.random() * (max-min) ) + min;
}
//数字补位
,str_pad:function(str,len,chr,right){
str = str.toString();
len = len || 2;
chr = chr || '0';
right = right || false;
if( str.length >= len ){
return str;
}else{
for( var i=0,j=len-str.length;i<j;i++ ){
if( right ){
str = str+chr;
}else{
str = chr+str;
}
}
return str;
}
}
//抛错
,error:function(msg){
var e = new Error();
e.message = 'IDValidator: ' + msg;
throw e;
}
};

var _IDValidator = function(GB2260){
if( typeof GB2260 !== "undefined" ){
this.GB2260 = GB2260;
}
//建立cache
this.cache = {};
};

_IDValidator.prototype = {

isValid:function(id){
var GB2260 = this.GB2260 || null;
var code = util.checkArg(id);
if( code === false ){
return false;
}
//查询cache
if( this.cache.hasOwnProperty(id) && typeof this.cache[id].valid !== 'undefined' ){
return this.cache[id].valid;
}else{
if( !this.cache.hasOwnProperty(id) ){
this.cache[id] = {};
}
}

var addr = code.body.slice(0,6);
var birth = ( code.type === 18 ? code.body.slice(6,14) : code.body.slice(6,12) );
var order = code.body.slice(-3);

if( !( util.checkAddr(addr,GB2260) && util.checkBirth(birth) && util.checkOrder(order) ) ) {
this.cache[id].valid = false;
return false;
}

//15位不含校验码,到此已结束
if( code.type === 15 ){
this.cache[id].valid = true;
return true;
}

/* 校验位部分 */

//位置加权
var posWeight = [];
for(var i=18;i>1;i--){
var wei = util.weight(i);
posWeight[i] = wei;
}

//累加body部分与位置加权的积
var bodySum = 0;
var bodyArr = code.body.split('');
for(var j=0;j<bodyArr.length;j++){
bodySum += ( parseInt( bodyArr[j],10 ) * posWeight[18 - j] );
}

//得出校验码
var checkBit = 12 - ( bodySum % 11 );
if( checkBit == 10 ){
checkBit = 'X';
}else if( checkBit>10 ){
checkBit = checkBit%11;
}
checkBit = ( typeof checkBit === 'number'?checkBit.toString():checkBit );

//检查校验码
if( checkBit !== code.checkBit ){
this.cache[id].valid = false;
return false;
}else{
this.cache[id].valid = true;
return true;
}

}

//分析详细信息
,getInfo:function(id){
var GB2260 = this.GB2260 || null;
//号码必须有效
if( this.isValid(id) === false ){
return false;
}
//TODO 复用此部分
var code = util.checkArg(id);

//查询cache
//到此时通过isValid已经有了cache记录
if( typeof this.cache[id].info !== 'undefined' ){
return this.cache[id].info;
}

var addr = code.body.slice(0,6);
var birth = ( code.type === 18 ? code.body.slice(6,14) : code.body.slice(6,12) );
var order = code.body.slice(-3);

var info = {};
info.addrCode = addr;
if( GB2260 !== null ){
info.addr = util.getAddrInfo(addr,GB2260);
}
info.birth = ( code.type === 18 ? (
([birth.slice(0,4),birth.slice(4,6),birth.slice(-2)]).join('-') ) :
(['19'+birth.slice(0,2),birth.slice(2,4),birth.slice(-2)]).join('-')
);
info.sex = (order%2===0?0:1);
info.length = code.type;
if( code.type === 18 ){
info.checkBit = code.checkBit;
}

//记录cache
this.cache[id].info = info;

return info;
}

//仿造一个号
,makeID:function( isFifteen ){
var GB2260 = this.GB2260 || null;

//地址码
var addr = null;
if( GB2260 !== null ){
var loopCnt = 0;
while( addr === null ){
//防止死循环
if( loopCnt>10 ){
addr = 110101;
break;
}
var prov = util.str_pad( util.rand( 50 ), 2, '0' );
var city = util.str_pad( util.rand( 20 ), 2, '0' );
var area = util.str_pad( util.rand( 20 ), 2, '0' );
var addrTest = [prov,city,area].join('');
if( GB2260[addrTest] ){
addr = addrTest;
break;
}
}
}else{
addr = 110101;
}

//出生年
var yr = util.str_pad( util.rand( 99,50 ), 2, '0' );
var mo = util.str_pad( util.rand( 12,1 ), 2, '0' );
var da = util.str_pad( util.rand( 28,1 ), 2, '0' );
if( isFifteen ){
return addr + yr + mo + da + util.str_pad( util.rand( 999,1 ),3,'1' );
}

yr = '19' + yr;
var body = addr + yr + mo + da + util.str_pad( util.rand( 999,1 ),3,'1' );

//位置加权
var posWeight = [];
for(var i=18;i>1;i--){
var wei = util.weight(i);
posWeight[i] = wei;
}

//累加body部分与位置加权的积
var bodySum = 0;
var bodyArr = body.split('');
for(var j=0;j<bodyArr.length;j++){
bodySum += ( parseInt( bodyArr[j],10 ) * posWeight[18 - j] );
}

//得出校验码
var checkBit = 12 - ( bodySum % 11 );
if( checkBit == 10 ){
checkBit = 'X';
}else if( checkBit>10 ){
checkBit = checkBit%11;
}
checkBit = ( typeof checkBit === 'number'?checkBit.toString():checkBit );

return (body + checkBit);
}

};//_IDValidator

return _IDValidator;

});

 

 

使用方法:

var validator = new IDValidator()
  $('input[name=idcard]').blur(function(){
  var val = $(this).val()
  val = $.trim(val)
  $(this).val(val)
  if (val.length > 0) {
    if (validator.isValid(val)) {
      var info = validator.getInfo(val)
      console.log(info.birth)
    }else{
      alert("身份证输入有误!")
    }
  }else{
    alert("不能为空")
  }
})

posted @ 2016-12-07 19:54  菜鸟提升记  阅读(325)  评论(0编辑  收藏  举报