var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];// 加权因子 var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];// 身份证验证位值.10代表X function IdCardValidate(idCard) { idCard = trim(idCard.replace(/ /g, "")); if (idCard.length == 15) { return isValidityBrithBy15IdCard(idCard); } else if (idCard.length == 18) { var a_idCard = idCard.split("");// 得到身份证数组 if(isValidityBrithBy18IdCard(idCard)&&isTrueValidateCodeBy18IdCard(a_idCard)){ return true; }else { return false; } } else { return false; } } /** * 判断身份证号码为18位时最后的验证位是否正确 * @param a_idCard 身份证号码数组 * @return */ function isTrueValidateCodeBy18IdCard(a_idCard) { var sum = 0; // 声明加权求和变量 if (a_idCard[17].toLowerCase() == 'x') { a_idCard[17] = 10;// 将最后位为x的验证码替换为10方便后续操作 } for ( var i = 0; i < 17; i++) { sum += Wi[i] * a_idCard[i];// 加权求和 } valCodePosition = sum % 11;// 得到验证码所位置 if (a_idCard[17] == ValideCode[valCodePosition]) { return true; } else { return false; } } /** * 通过身份证判断是男是女 * @param idCard 15/18位身份证号码 * @return 'female'-女、'male'-男 */ function maleOrFemalByIdCard(idCard){ idCard = trim(idCard.replace(/ /g, ""));// 对身份证号码做处理。包括字符间有空格。 if(idCard.length==15){ if(idCard.substring(14,15)%2==0){ return 'female'; }else{ return 'male'; } }else if(idCard.length ==18){ if(idCard.substring(14,17)%2==0){ return 'female'; }else{ return 'male'; } }else{ return null; } // 可对传入字符直接当作数组来处理 // if(idCard.length==15){ // alert(idCard[13]); // if(idCard[13]%2==0){ // return 'female'; // }else{ // return 'male'; // } // }else if(idCard.length==18){ // alert(idCard[16]); // if(idCard[16]%2==0){ // return 'female'; // }else{ // return 'male'; // } // }else{ // return null; // } } /** * 验证18位数身份证号码中的生日是否是有效生日 * @param idCard 18位书身份证字符串 * @return */ function isValidityBrithBy18IdCard(idCard18){ var year = idCard18.substring(6,10); var month = idCard18.substring(10,12); var day = idCard18.substring(12,14); var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day)); // 这里用getFullYear()获取年份,避免千年虫问题 if(temp_date.getFullYear()!=parseFloat(year) ||temp_date.getMonth()!=parseFloat(month)-1 ||temp_date.getDate()!=parseFloat(day)){ return false; }else{ return true; } } /** * 验证15位数身份证号码中的生日是否是有效生日 * @param idCard15 15位书身份证字符串 * @return */ function isValidityBrithBy15IdCard(idCard15){ var year = idCard15.substring(6,8); var month = idCard15.substring(8,10); var day = idCard15.substring(10,12); var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day)); // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法 if(temp_date.getYear()!=parseFloat(year) ||temp_date.getMonth()!=parseFloat(month)-1 ||temp_date.getDate()!=parseFloat(day)){ return false; }else{ return true; } } //去掉字符串头尾空格 function trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); }
使用ORACLE函数,网上有很多~~~
我的验证函数如下,但是却验证不出来? FUNCTION fun_VerifyIdCard(prm_IdCard VARCHAR2) RETURN VARCHAR2 IS v_structuralStr VARCHAR2(100); v_ConstStr VARCHAR2(20); v_ReturnStr VARCHAR2(50); v_GetDate VARCHAR2(10); i NUMBER; v_IdCard18 VARCHAR2(18); v_sum VARCHAR2(20); v_valid VARCHAR2(20); --地区代码 v_areacode VARCHAR2 (2000) := '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,'; BEGIN --初始化变量 v_structuralStr := '070910050804020106030709100508040201'; v_ConstStr := '10X98765432'; v_ReturnStr := NULL; IF prm_IdCard IS NULL THEN v_ReturnStr := '身份证号为空。'; GOTO LABLE_NEXT; END IF;
--验证身份证号长度 IF NOT (LENGTH(prm_IdCard) = 15 OR LENGTH(prm_IdCard) = 18) THEN v_ReturnStr := '身份证号长度不正确。'; GOTO LABLE_NEXT; END IF;
--地区代码校验 IF instrb(v_areacode, substr(prm_IdCard, 1, 2)||',') = 0 THEN v_ReturnStr := '地区代码错误。'; GOTO LABLE_NEXT; END IF;
--校验身份证号格式是否正确 IF LENGTH(prm_IdCard) = 15 THEN IF NVL(TRANSLATE(prm_IdCard,'\1234567890', '\'), '0') != '0' THEN v_ReturnStr := '15位身份证号存在非法字符。'; GOTO LABLE_NEXT; END IF; END IF; IF LENGTH(prm_IdCard) = 18 THEN IF NVL(TRANSLATE(prm_IdCard,'\1234567890', '\'), '0') = '0' OR (NVL(TRANSLATE(SUBSTR(prm_IdCard, 1, 17),'\1234567890', '\'), '0') = '0' AND UPPER(SUBSTR(prm_IdCard, 18, 1)) = 'X') THEN NULL; ELSE v_ReturnStr := '18位身份证号存在非法字符。'; GOTO LABLE_NEXT; END IF; END IF;
--验证日期是否正确 IF LENGTH(prm_IdCard) = 15 THEN v_GetDate := '19' || SUBSTR(prm_IdCard, 7, 2) || '-' ||SUBSTR(prm_IdCard, 9, 2) || '-' || SUBSTR(prm_IdCard, 11, 2); ELSE v_GetDate := SUBSTR(prm_IdCard, 7, 4) || '-' || SUBSTR(prm_IdCard, 11, 2) || '-' || SUBSTR(prm_IdCard, 13, 2); END IF; IF NVL(REGEXP_SUBSTR(v_GetDate, '(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)'), '0') = '0' THEN v_ReturnStr := '身份证出生日期不合法。'; GOTO LABLE_NEXT; END IF;
--校验位验证 v_IdCard18 := prm_IdCard; IF LENGTH(v_IdCard18) = 15 THEN v_IdCard18 := SUBSTR(prm_IdCard,1, 6) ||+ '19' ||SUBSTR(prm_IdCard,7,9); END IF; i := 1; v_sum := 0; WHILE i <= 17 LOOP v_sum := v_sum+ TO_NUMBER(SUBSTR(v_IdCard18, i, 1)) * TO_NUMBER(SUBSTR(v_structuralStr, (i-1)*2+1, 2)); i := i + 1; END LOOP; v_Valid := SUBSTR(v_ConstStr,(MOD(v_sum, 11) + 1),1); IF LENGTH(prm_IdCard) = 18 THEN IF UPPER(SUBSTR(prm_IdCard,18, 1)) <> UPPER(v_Valid) THEN v_ReturnStr := '身份证校验位不正确,正确的校验位为['||v_Valid||']'; GOTO LABLE_NEXT; END IF; END IF; <<LABLE_NEXT>> RETURN v_ReturnStr; END fun_VerifyIdCard;
使用substr进行截取然后比较也行的
IdCard-Validate.js代码如下:
/**
* 身份证15位编码规则:dddddd yymmdd xx p
* dddddd:地区码
* yymmdd: 出生年月日
* xx: 顺序类编码,无法确定
* p: 性别,奇数为男,偶数为女
* <p />
* 身份证18位编码规则:dddddd yyyymmdd xxx y
* dddddd:地区码
* yyyymmdd: 出生年月日
* xxx:顺序类编码,无法确定,奇数为男,偶数为女
* y: 校验码,该位数值可通过前17位计算获得
* <p />
* 18位号码加权因子为(从右到左) Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,1 ]
* 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
* 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
* i为身份证号码从右往左数的 2...18 位; Y_P为脚丫校验码所在校验码数组位置
*
*/
var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];// 加权因子
var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];// 身份证验证位值.10代表X
function IdCardValidate(idCard) {
idCard = trim(idCard.replace(/ /g, ""));
if (idCard.length == 15) {
return isValidityBrithBy15IdCard(idCard);
} else if (idCard.length == 18) {
var a_idCard = idCard.split("");// 得到身份证数组
if(isValidityBrithBy18IdCard(idCard)&&isTrueValidateCodeBy18IdCard(a_idCard)){
return true;
}else {
return false;
}
} else {
return false;
}
}
/**
* 判断身份证号码为18位时最后的验证位是否正确
* @param a_idCard 身份证号码数组
* @return
*/
function isTrueValidateCodeBy18IdCard(a_idCard) {
var sum = 0; // 声明加权求和变量
if (a_idCard[17].toLowerCase() == 'x') {
a_idCard[17] = 10;// 将最后位为x的验证码替换为10方便后续操作
}
for ( var i = 0; i < 17; i++) {
sum += Wi[i] * a_idCard[i];// 加权求和
}
valCodePosition = sum % 11;// 得到验证码所位置
if (a_idCard[17] == ValideCode[valCodePosition]) {
return true;
} else {
return false;
}
}
/**
* 通过身份证判断是男是女
* @param idCard 15/18位身份证号码
* @return 'female'-女、'male'-男
*/
function maleOrFemalByIdCard(idCard){
idCard = trim(idCard.replace(/ /g, ""));// 对身份证号码做处理。包括字符间有空格。
if(idCard.length==15){
if(idCard.substring(14,15)%2==0){
return 'female';
}else{
return 'male';
}
}else if(idCard.length ==18){
if(idCard.substring(14,17)%2==0){
return 'female';
}else{
return 'male';
}
}else{
return null;
}
// 可对传入字符直接当作数组来处理
// if(idCard.length==15){
// alert(idCard[13]);
// if(idCard[13]%2==0){
// return 'female';
// }else{
// return 'male';
// }
// }else if(idCard.length==18){
// alert(idCard[16]);
// if(idCard[16]%2==0){
// return 'female';
// }else{
// return 'male';
// }
// }else{
// return null;
// }
}
/**
* 验证18位数身份证号码中的生日是否是有效生日
* @param idCard 18位书身份证字符串
* @return
*/
function isValidityBrithBy18IdCard(idCard18){
var year = idCard18.substring(6,10);
var month = idCard18.substring(10,12);
var day = idCard18.substring(12,14);
var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));
// 这里用getFullYear()获取年份,避免千年虫问题
if(temp_date.getFullYear()!=parseFloat(year)
||temp_date.getMonth()!=parseFloat(month)-1
||temp_date.getDate()!=parseFloat(day)){
return false;
}else{
return true;
}
}
/**
* 验证15位数身份证号码中的生日是否是有效生日
* @param idCard15 15位书身份证字符串
* @return
*/
function isValidityBrithBy15IdCard(idCard15){
var year = idCard15.substring(6,8);
var month = idCard15.substring(8,10);
var day = idCard15.substring(10,12);
var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));
// 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
if(temp_date.getYear()!=parseFloat(year)
||temp_date.getMonth()!=parseFloat(month)-1
||temp_date.getDate()!=parseFloat(day)){
return false;
}else{
return true;
}
}
//去掉字符串头尾空格
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
}
FUNCTION fun_VerifyIdCard(prm_IdCard VARCHAR2)
RETURN VARCHAR2
IS
v_structuralStr VARCHAR2(100);
v_ConstStr VARCHAR2(20);
v_ReturnStr VARCHAR2(50);
v_GetDate VARCHAR2(10);
i NUMBER;
v_IdCard18 VARCHAR2(18);
v_sum VARCHAR2(20);
v_valid VARCHAR2(20);
--地区代码
v_areacode VARCHAR2 (2000) := '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,';
BEGIN
--初始化变量
v_structuralStr := '070910050804020106030709100508040201';
v_ConstStr := '10X98765432';
v_ReturnStr := NULL;
IF prm_IdCard IS NULL THEN
v_ReturnStr := '身份证号为空。';
GOTO LABLE_NEXT;
END IF;
--验证身份证号长度
IF NOT (LENGTH(prm_IdCard) = 15 OR LENGTH(prm_IdCard) = 18) THEN
v_ReturnStr := '身份证号长度不正确。';
GOTO LABLE_NEXT;
END IF;
--地区代码校验
IF instrb(v_areacode, substr(prm_IdCard, 1, 2)||',') = 0 THEN
v_ReturnStr := '地区代码错误。';
GOTO LABLE_NEXT;
END IF;
--校验身份证号格式是否正确
IF LENGTH(prm_IdCard) = 15 THEN
IF NVL(TRANSLATE(prm_IdCard,'\1234567890', '\'), '0') != '0' THEN
v_ReturnStr := '15位身份证号存在非法字符。';
GOTO LABLE_NEXT;
END IF;
END IF;
IF LENGTH(prm_IdCard) = 18 THEN
IF NVL(TRANSLATE(prm_IdCard,'\1234567890', '\'), '0') = '0'
OR (NVL(TRANSLATE(SUBSTR(prm_IdCard, 1, 17),'\1234567890', '\'), '0') = '0'
AND UPPER(SUBSTR(prm_IdCard, 18, 1)) = 'X') THEN
NULL;
ELSE
v_ReturnStr := '18位身份证号存在非法字符。';
GOTO LABLE_NEXT;
END IF;
END IF;
--验证日期是否正确
IF LENGTH(prm_IdCard) = 15 THEN
v_GetDate := '19' || SUBSTR(prm_IdCard, 7, 2) || '-' ||SUBSTR(prm_IdCard, 9, 2) || '-' || SUBSTR(prm_IdCard, 11, 2);
ELSE
v_GetDate := SUBSTR(prm_IdCard, 7, 4) || '-' || SUBSTR(prm_IdCard, 11, 2) || '-' || SUBSTR(prm_IdCard, 13, 2);
END IF;
IF NVL(REGEXP_SUBSTR(v_GetDate, '(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)'), '0') = '0' THEN
v_ReturnStr := '身份证出生日期不合法。';
GOTO LABLE_NEXT;
END IF;
--校验位验证
v_IdCard18 := prm_IdCard;
IF LENGTH(v_IdCard18) = 15 THEN
v_IdCard18 := SUBSTR(prm_IdCard,1, 6) ||+ '19' ||SUBSTR(prm_IdCard,7,9);
END IF;
i := 1;
v_sum := 0;
WHILE i <= 17 LOOP
v_sum := v_sum+ TO_NUMBER(SUBSTR(v_IdCard18, i, 1)) * TO_NUMBER(SUBSTR(v_structuralStr, (i-1)*2+1, 2));
i := i + 1;
END LOOP;
v_Valid := SUBSTR(v_ConstStr,(MOD(v_sum, 11) + 1),1);
IF LENGTH(prm_IdCard) = 18 THEN
IF UPPER(SUBSTR(prm_IdCard,18, 1)) <> UPPER(v_Valid) THEN
v_ReturnStr := '身份证校验位不正确,正确的校验位为['||v_Valid||']';
GOTO LABLE_NEXT;
END IF;
END IF;
<<LABLE_NEXT>>
RETURN v_ReturnStr;
END fun_VerifyIdCard;