首先看一下《公民身份号码》中做了明确的规定:
18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号码》中做了明确的规定。 GB11643-1999《公民身份号码》为GB11643-1989《社会保障号码》的修订版,其中指出将原标准名称"社会保障号码"更名为"公民身份号码",另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。GB11643-1999《公民身份号码》主要内容如下:
一、范围
该标准规定了公民身份号码的编码对象、号码的结构和表现形式,使每个编码对象获得一个唯一的、不变的法定号码。
二、编码对象
公民身份号码的编码对象是具有中华人民共和国国籍的公民。
三、号码的结构和表示形式
1、号码的结构
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3、出生日期码
表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4、顺序码
表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5、校验码
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

(2)计算模
Y = mod(S, 11)

(3)通过模得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
四、举例如下:
北京市朝阳区: 11010519491231002X
广东省汕头市: 440524188001010014

再看一下身份证的含义:

'15位身份证号码含义:
'----------------------------------------
'113343 450321 432(身份证号:只作假设,可能此号并不存在,请勿对号入座)
'前6位 中间6位 后三位
'地区代码 生日:年月日 奇为男,偶为女
'----------------------------------------
'其中:
'各省市地区国家代码前两位代码是:
'----------------------------------
'北京 11 吉林 22 福建 35 广东 44 云南 53 天津 12 黑龙江 23 江西 36 广西 45 西藏 54 河北 13 上海 31
'山东 37 海南 46 陕西 61 山西 14 江苏 32 河南 41 重庆 50 甘肃 62 内蒙古 15 浙江 33 湖北 42
'四川 51 青海 63 辽宁 21 安徽 34 湖南 43 贵州 52 宁夏 64 新疆 65 台湾 71 香港 81 澳门 82 国外 91

'18位身份证号:
'---------------------------------------------------
'113343 1945 03 21 432 9(身份证号:只作假设,可能此号并不存在,请勿对号入座)
'前6位 四位 两位 两位 三位 一位
'地区代码 年份 月份 生日 奇为男,偶为女 检验位
'---------------------------------------------------
'其他不详。
参考资料:http://hsdwf.vicp.net/Content,2005,9,9,101.aspx

###############################################################
15位升18的方法
###############################################################

根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。下面举例说明该计算方法。

15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19,但是这对于1900年出生的人不使用(这样的寿星不多了)

某男性公民身份号码本体码为34052419800101001,首先按照公式⑴计算:

∑(ai×Wi)(mod 11)……………………………………(1)

公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2(n-1)(mod 11)计算得出。

i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1

Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1

ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1

根据公式(1)进行计算:

∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189

189 ÷ 11 = 17 + 2/11

∑(ai×Wi)(mod 11) = 2

然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:

∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
根据上表,查出计算结果为2的校验码为所以该人员的公民身份号码应该为 34052419800101001X。

C#代码:

private string per15To18(string perIDSrc)
{
int iS = 0;

//加权因子常数
int[] iW=new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//校验码常数
string LastCode="10X98765432";
//新身份证号
string perIDNew;

perIDNew=perIDSrc.Substring(0,6);
//填在第6位及第7位上填上‘1’,‘9’两个数字
perIDNew += "19";

perIDNew += perIDSrc.Substring(6,9);

//进行加权求和
for( int i=0; i<17; i++)
{
iS += int.Parse(perIDNew.Substring(i,1)) * iW[i];
}

//取模运算,得到模值
int iY = iS%11;
//从LastCode中取得以模为索引号的值,加到身份证的最后一位,即为新身份证号。
perIDNew += LastCode.Substring(iY,1);

return perIDNew;
}

源代码如下:

CREATE OR REPLACE FUNCTION isidCard(str varchar2) RETURN varchar2 IS areaID char(6) :=substr(str,1,6); birthdayID char(8); sexID char(3); checkID char(1); areaStr varchar(20); birthdayStr1 char(10); birthdayStr2 char(10); birthdayStr3 char(10); birthdayStr4 char(10); sexStr char(3); flag char(2); personInfo varchar2(200); begin if(length(str)!=15 and length(str)!=18)then return '长度不对!'; else select checkarea(areaID) into areaStr from dual; if(areaStr!='NULL') then --地址码是否正确 if(length(str)=15) then --15位 birthdayStr1 :='19'||substr(str,7,6); birthdayStr2 :='20'||substr(str,7,6); select checkbrithday(birthdayStr1) into birthdayStr3 from dual; select checkbrithday(birthdayStr2) into birthdayStr4 from dual; if(birthdayStr3!='NULL' or birthdayStr4!='NULL')then sexID :=substr(str,13,3); select getSex(to_number(sexID)) into sexStr from dual; personInfo :='性别:'||sexStr||' 生日:'||birthdayStr3||'或者'||birthdayStr4||' 地区:'||areaStr; return personInfo; else return '日期错误!'; end if; else --18位 birthdayID :=substr(str,7,8); select checkbrithday(birthdayID) into birthdayStr1 from dual; if(birthdayStr1!='NULL')then select checkCode(str) into flag from dual; if(flag='p')then sexID :=substr(str,15,3); scott.myprint(sexid); select getSex(to_number(sexID)) into sexStr from dual; personInfo :='性别:'||sexStr||' 生日:'||birthdayStr1||' 地区:'||areaStr; return personInfo; else return '校验码错误!'; end if; else return '日期错误!'; end if; end if; else return '地址码错误!'; end if; end if; end; --地址码 CREATE OR REPLACE FUNCTION checkarea(str varchar2) return varchar2 is area varchar2(20); flag number(2); begin select checkarea1(str) into flag from dual; if(flag=1)then select substr(idc,7,(length(idc)-6)) into area from idcardinfo where substr(idc,0,6)=str; return area; else return 'NULL'; end if; end; CREATE OR REPLACE FUNCTION checkarea1(str varchar2) return number is area number(2); begin select count(1) into area from idcardinfo where substr(idc,0,6)=str; return area; end; --出生日期 CREATE OR REPLACE FUNCTION checkbrithday(str varchar2) return varchar2 is birthday varchar2(10); begin select isdate2(str) into birthday from dual; if(birthday!='NULL')then return birthday; else return 'NULL'; end if; end; ---- CREATE OR REPLACE FUNCTION isdate2(str varchar2) RETURN varchar IS v_date date; v_nls varchar2(100) default null; BEGIN SELECT 'NLS_DATE_LANGUAGE='''||value||'''' INTO v_nls FROM v$nls_parameters WHERE parameter='NLS_DATE_LANGUAGE'; v_date := to_date(str, 'yyyy-mm-dd', v_nls); RETURN to_char(v_date,'yyyy-mm-dd'); EXCEPTION WHEN OTHERS THEN /*如果你希望看到报错, 就把下面的注释行打开*/ --raise; RETURN 'NULL'; END; -------------------------------------------------------------------- --性别 CREATE OR REPLACE FUNCTION getSex(str number) RETURN varchar is begin if(str mod 2 =0)then return '女'; else return '男'; end if; end; --校验码 CREATE OR REPLACE FUNCTION checkCode(str varchar2) RETURN varchar is wi char(35) :='7*9*10*5*8*4*2*1*6*3*7*9*10*5*8*4*2'; checkstr char(11) :='10X98765432'; sumcode number(10); checkrel number(2); lastCode char(1); begin sumcode:=to_number(substr(str,1,1))*to_number(substr(wi,1,1))+to_number(substr(str,2,1))*to_number(substr(wi,3,1))+to_number(substr(str,3,1))*to_number(substr(wi,5,2))+to_number(substr(str,4,1))*to_number(substr(wi,8,1))+to_number(substr(str,5,1))*to_number(substr(wi,10,1))+to_number(substr(str,6,1))*to_number(substr(wi,12,1))+to_number(substr(str,7,1))*to_number(substr(wi,14,1))+to_number(substr(str,8,1))*to_number(substr(wi,16,1))+to_number(substr(str,9,1))*to_number(substr(wi,18,1))+to_number(substr(str,10,1))*to_number(substr(wi,20,1))+to_number(substr(str,11,1))*to_number(substr(wi,22,1))+to_number(substr(str,12,1))*to_number(substr(wi,24,1))+to_number(substr(str,13,1))*to_number(substr(wi,26,2))+to_number(substr(str,14,1))*to_number(substr(wi,29,1))+to_number(substr(str,15,1))*to_number(substr(wi,31,1))+to_number(substr(str,16,1))*to_number(substr(wi,33,1))+to_number(substr(str,17,1))*to_number(substr(wi,35,1)); checkrel :=(sumcode mod 11)+1; select substr(checkstr,checkrel,1) into lastCode from dual; if(upper(lastCode)=upper(substr(str,18,1)))then return 'p'; else return 'np'; end if; end; /* 110103198808081226 110103198808121224 11010719880812122x 110101198808121221 110117198808121222 421123198808121223 421125198808121226 42112419880812122x 421123198508121221 */

oracle验证公民身份号码相关推荐

  1. 【商业信息】GB 11643—1999 公民身份号码

    前      言 本标准是GB 11643-1989<社会保障号码>的修订版.为了使标准的内容适应我国国民经济和社会发展的需要,对原标准内容作了以下改动: 原标准名称"社会保障号 ...

  2. 公民身份号码 校验码 检证程序

    公民身份号码  校验码 检证程序 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  3. 公民身份号码校验码算法(C#版)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. 公民身份号码 校验码 检证程序

    公民身份号码  校验码 检证程序 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  5. 公民身份号码是一种由18位数字组成的特征组合码,其排列顺序从左至右依次为:6位数字地址码、8位数字出生日期码,3位数字顺序码和1位数字校验码(校验码若为10则用字符X来表示)。编写程序从键盘输入一个

    #include <stdio.h> int main() {int add,year,month,day;/*定义地址码,年月日*/int shunxuma;/*定义顺序码*/char ...

  6. Js实现中国公民身份证号码有效性验证

    2019独角兽企业重金招聘Python工程师标准>>> 参考: Java实现中国公民身份证号码有效性验证 Php实现中国公民身份证号码有效性验证 本文将使用JavaScript实现中 ...

  7. 公民身份证号码的编排规则

    现在普遍使用的都是18位的身份证号码,由17位数字本体码和1位校验码组成.作为尾位的校验码,采用ISO7064:1983,MOD11-2校验码系统,是根据校验公式,由本体码决定的,用来验证录入或转录过 ...

  8. java验证公民身份证真实性

    通过一定的算法规则校验身份证的真实性,不多说,上代码: package examples.cardId; import java.util.Scanner; /**  * 公民身份号码是特征组合码,由 ...

  9. cxf 实名认证---全国公民身份信息系统

    最近做了一个实名认证功能,需要调用公安部门接口进行认证,用到webService.期间查阅了很多资料.小结如下. 1.ws 客户端代码生成: 客户端代码是根据所给的url?wsdl文件生成的.该文件通 ...

最新文章

  1. yolo_model to output理解
  2. 【Android笔记】MediaPlayer基本使用方式
  3. 《你不知道的JavaScript》-- 精读(五)
  4. 信息奥赛一本通(1112:最大值和最小值的差)
  5. spring-boot-starter-parent 包maven依赖报错
  6. 显示隐藏、淡入淡出、上卷下展的区别
  7. 常见快速搜索算法图解
  8. 无人机的电调及其工作原理是什么?
  9. python京东抢购 github_GitHub - DevGuan/jd-autobuy: Python爬虫,京东自动登录,在线抢购商品...
  10. Python问题解决6:使用jupyter notebook时安装第三方库提示升级pip,pip升级不成功一直报错
  11. pl/sqp常用方法
  12. oracle执行计划相关
  13. Day 03-常用 Composition API_拉开序幕的setup()
  14. 汉字转拼音工具JPinyin的介绍和使用示例
  15. 为App签名(为apk签名)
  16. 算法时间复杂度计算方法
  17. Dorado5学习笔记
  18. 王者荣耀怎么删除在服务器上建立的账号,王者荣耀账号怎么注销 王者荣耀账号注销方法...
  19. 测试中文编码_如何通过带回家的编码测试
  20. 在vue中 鼠标移入 切换背景图片 移出时再次切换图片

热门文章

  1. 一般UI设计要学习的内容都有哪些
  2. 英语口语练习四之 You/We may/might (just) as well... (我们不妨……)用法
  3. [区块链] 密码学中Hash算法(基础)
  4. python字符串及其函数
  5. [转帖]详细讲解六大QQ病毒的特征以及清除方法
  6. 使用Windows自带“录音机”录制音乐(转)
  7. dnf服务器未响应怎么解决方法,科技知识:DNF地下城与勇士程序未响应怎么办——一招搞定...
  8. iphone忘记锁屏密码如何解决
  9. python写一段自动对焦AF的代码
  10. jaeger 是很么软件_jaeger 使用初探