主题:查询身份证信息源代码(添校验功能),和身份证号与区域对照表
cbl518
[专家分:57140] 发布于 2007-07-06 04:29:00
数据表是根据:
中华人民共和国国家统计局,最新县及县以上行政区划代码(截止2006-12-31 08:56:35)整理的。
[color=008080][size=5]查询身份证信息源代码在六楼。[/size][/color]
[color=0000FF][size=4]源代码修改通知:
根据 0901chang 先生 2007-7-9 无私贡献的代码:
增添了核对校验码功能:
根据 jinlonggao 和 esailor 两位先生 2007-7-9 纠错指导:
修改了 18 位身份证性别出错的问题。
根据 esailor 先生 2007-7-8 意见;
添加了在众多表中自动搜索配套数据表功能。
[/size]
[size=5]对以上高手,我表示衷心得感谢!!![/size][/color]
[color=FF0000][size=4]凡是回帖说明使用结果者,或发表评论新帖子者, [/size] [/color] [color=0000FF][size=3]请将你的电子信箱号码发到。我的论坛信箱。我将不定期赠送不常见的编程实例。[/size][/color]
如:
在 vfp 中,怎样以控件方式操作运行 word 或 excel。
在 vfp 中,怎样构造各种最新界面。
怎样真正使用以数据库为中心的编程方法。
怎样维护和操作:windows 的各种进程。……
vfp 之所以强大,它不但是数据库编程环境,而且有强大的编程环境。别的语言能实现的功能 vfp 都能实现,这是我使用的 20 多年的编程经验。
最后更新于:2007-07-11 08:04:00
回复列表 (共69个回复)
12 楼
jinlonggao [专家分:17130] 发布于 2007-07-09 15:58:00
chibl先生,我已下载并运行成功,感谢您的无私奉献!只是关于性别的界定方法还不明白,包括后四位的意义,能否给解释一下?另外,对于过去办的证是15位的,应如何界定?
13 楼
cbl518 [专家分:57140] 发布于 2007-07-09 16:31:00
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。
头六位数字为地址码,
紧接着八位数字为出生日期码,
然后三位数字为顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
最后一位数字是校验码。目的在于检测身份证号码的正确性,是由计算机随机产生的,所以不再是男性为单数,女性为双数。
第一代身份证(15位)没有校验码。
我之所以取最后一位,当性别区分码,因为我问过有关朋友,他讲是一样的意义。我这次写这个程序,等着反馈,就是看看到底有无区别。
让老弟,你见笑了。谢谢你了。
14 楼
esailor [专家分:2650] 发布于 2007-07-09 17:23:00
谢谢
您的程序似乎无法处理最后校验位位是“X”的情况
15 楼
jinlonggao [专家分:17130] 发布于 2007-07-09 18:56:00
chibl先生解释得很清楚,我的身份证是15位,所以,你的程序不解析其中的地区,也不解析出生年月,我女儿的身份证后4位是0065,你的程序解析出的性别为"男".
我没有细续程序代码,只是把问题提出来.
16 楼
cbl518 [专家分:57140] 发布于 2007-07-09 20:00:00
[quote]谢谢
您的程序似乎无法处理最后校验位位是“X”的情况[/quote]
校验位:最后一位数字是校验码。成年人正式身份证还有“X”校验码,我只知道未成年人的身份证号码后四位是“XXXX”。谢谢你的提示。
[quote]我女儿的身份证后4位是0065[/quote]
老弟是第一个告诉我的顺序吗和校验码。是有区别的。
谢谢你的提示。
[color=FF0000][size=5]我已使用正确代码!性别:15位的最后一位数,18位倒数第二位,男单女双。[/size][/color]
17 楼
0901chang [专家分:10660] 发布于 2007-07-09 20:59:00
* 由国家标准【GB11643-1999《公民身份号码》】计算身份证校验码
* 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
15位转18位时,插入两位世纪数字之后,按上面地公式求出校验位。
18 楼
0901chang [专家分:10660] 发布于 2007-07-09 21:15:00
以下是乌鸦的人事软件中,实际应用的身份证校验程序,请参考。如果连接行政区划表,也可以求出发证的地名。
PROC 校验身份证号
para sfz_号码,sfz_连续
PRIV s_校验结果,m,ai,wi,r,i,c,m_省市区位,m_区位
sfz_连续=iif(type('sfz_连续')='C',sfz_连续,'')
* 在输入身份证号码之后,用本函数检查输入数据是否由错误
* 由国家标准【GB11643-1999《公民身份号码》】计算身份证校验码
* 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
i=''
i=i+'11北京 12天津 13河北 14山西 15内蒙'+chr(13)
i=i+'21辽宁 22吉林 23黑龙江'+chr(13)
i=i+'31上海 32江苏 33浙江 34安徽 35福建 36江西 37山东'+chr(13)
i=i+'41河南 42湖北 43湖南 44广东 45广西 46海南'+chr(13)
i=i+'50重庆 51四川 52贵州 53云南 54西藏'+chr(13)
i=i+'61陕西 62甘肃 63青海 64宁夏 65新疆'+chr(13)
m_省市区位=i
rele i
s_校验结果=''
sfz_号码=ALLTRIM(sfz_号码)
do case
case empty(sfz_号码)
s_校验结果='' && 未输入身份证号码,不校验
case LEN(sfz_号码)<15
s_校验结果='错误:身份证号码小于15位'
case LEN(sfz_号码)>15.and.LEN(sfz_号码)<18
s_校验结果='错误:身份证号码大于15位,但小于18位'
case LEN(sfz_号码)=15 && 15位的号码
FOR I=1 TO 15 &&检查每一位是否为数字
m=SUBSTR(sfz_号码,I,1)
IF m>='0'.and.m<='9' &&数字
ELSE
s_校验结果='错误:身份证号码为15位,但其中包含了不是数字的字符'
ENDIF
ENDFOR
if empty(s_校验结果)
m=val(left(sfz_号码,2))
do case
case m=71
s_校验结果='错误:身份证号码为15位,但区划代码是台湾'
case m=81
s_校验结果='错误:身份证号码为15位,但区划代码是香港'
case m=82
s_校验结果='错误:身份证号码为15位,但区划代码是澳门'
case m<11.or.m>65
s_校验结果='错误:身份证号码为15位,但区划代码应该在11~65之间'
endc
endi
if empty(s_校验结果)
m='19'+SUBSTR(sfz_号码,7,2)+'.'+SUBSTR(sfz_号码,9,2)+'.'+SUBSTR(sfz_号码,11,2)
m=CTOD(m)
IF ISNULL(m) .OR. ISBLANK(m)
s_校验结果='错误:身份证号码为15位,但出生日期填写错误'
ENDIF
endi
case LEN(sfz_号码)=18 && 18位的号码
FOR I=1 TO 17
m=SUBSTR(sfz_号码,I,1)
IF m>='0'.and.m<='9'
ELSE
s_校验结果='错误:身份证号码为18位,但前17位中包含了不是数字的字符'
ENDIF
ENDFOR
if empty(s_校验结果)
m=val(left(sfz_号码,2))
m_区位=left(sfz_号码,2)
do case
case m=71
s_校验结果='错误:身份证号码为18位,但区划代码是台湾'
case m=81
s_校验结果='错误:身份证号码为18位,但区划代码是香港'
case m=82
s_校验结果='错误:身份证号码为18位,但区划代码是澳门'
case m<11.or.m>66
s_校验结果='错误:身份证号码为18位,但区划代码应该在11~66之间'
case .not.m_区位$m_省市区位
s_校验结果='错误:身份证号码为18位,但你输入了不存在的省份区划代码'
endc
endi
if empty(s_校验结果)
m=SUBSTR(sfz_号码,7,4)+'.'+SUBSTR(sfz_号码,11,2)+'.'+SUBSTR(sfz_号码,13,2)
m=CTOD(m)
IF ISNULL(m) .OR. ISBLANK(m)
s_校验结果='错误:身份证号码为18位,但出生日期填写错误'
ENDIF
endi
if empty(s_校验结果)
r=0 && 计算校验位
FOR I=18 TO 2 STEP -1
ai=VAL(SUBSTR(sfz_号码,19-i,1))
wi=MOD(2^(i-1),11)
r=r+ai*wi
NEXT
r=MOD(r,11)
DO CASE
CASE r=0
c="1"
CASE r=1
c="0"
CASE r=2
c="X"
OTHERWISE
c=ALLTRIM(STR(12-r))
ENDCASE
IF UPPER(SUBSTR(sfz_号码,18,1))==c
ELSE
s_校验结果='错误:身份证号码为18位,但校验码错误'
ENDIF
endi
ENDCASE
if .not.empty(s_校验结果).and.empty(sfz_连续)
if s_校验结果='错误:身份证号码为18位,但你输入了不存在的省份区划代码'
=messagebox( m_省市区位,48,"你输入了不存在的省份区划代码")
else
=messagebox( s_校验结果+'',48,"")
endi
endi
RETURN s_校验结果
19 楼
cbl518 [专家分:57140] 发布于 2007-07-09 22:52:00
谢谢你,本来我只想编个小程序,看看校验码是不是和顺序码一样单男双女。经你解释我才明白!
老弟:我核对一下校验码。再修改。
20 楼
0901chang [专家分:10660] 发布于 2007-07-10 02:54:00
若要准确地求出身份证发证的地名,行政区划表必须是多记录的,因为行政区划每年都有变动,最新的表中没有被撤消的行政区划地域,若新更改了地名,单记录的行政区划表无法准确地求出以前发证的地名。
这种应属于基础应用,凡是基础应用,都涉及到国家标准代码。乌鸦早就反对国家颁布标准代码,建议改为颁布标准名称,而把代码做为标准名称的序列号。若行政区划按标准名称颁布,就可以很方便地保留已经撤消和被变更的地名。很遗憾,乌鸦没有文凭、没有职称,又没有吃过洋屁,他们不采纳,他们说不这样做无法和外国接轨。乌鸦驳曰:要全面接轨,只能禁止说汉语,强制推行英语。
其实,标准名称和代码并不冲突,就是一个对照表,实际应用的人主要取名称,计算机则两者都取。
我来回复