标题:[原创]关于身份证号处理相关代码
只看楼主
oopp
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-8-11
 问题点数:0 回复次数:8 
[原创]关于身份证号处理相关代码

初学VFP,请大家多多指教!!!!!
不足之处请指点。

因很多程序的人员记录会用到身份证号,为了减少录入错误而制定代码
代码如下:

*-----------------------------------------------------
* 从18位身份证号中提取生日
* 提取年 SUBSTR(ALLTRIM(Id_card),7,4)
* 提取月 SUBSTR(ALLTRIM(Id_card),11,2)
* 提取日 SUBSTR(ALLTRIM(Id_card),13,2)
* 从15位身份证号中提取生日
* 提取年 SUBSTR(ALLTRIM(Id_card),7,2)
* 提取年 SUBSTR(ALLTRIM(Id_card),9,2)
* 提取年 SUBSTR(ALLTRIM(Id_card),11,2)
* id_card是表单中的身份证号变量。以下同
*-----------------------------------------------------
local d_ok,
IF len(ALLTRIM(Id_card))=18
d_ok=SUBSTR(ALLTRIM(Id_card),7,4);
+"-"+SUBSTR(ALLTRIM(Id_card),11,2);
+"-"+SUBSTR(ALLTRIM(Id_card),13,2)
ELSE
d_ok="19"+SUBSTR(ALLTRIM(Id_card),7,2);
+"-"+SUBSTR(ALLTRIM(Id_card),9,2);
+"-"+SUBSTR(ALLTRIM(Id_card),11,2)
ENDIF
CTOD(d_ok)

*-----------------------------------------------------
* 接上:判断月份和日
* 返回真值身份证号正确,返回假值身份证号的出生月份或日期有误
* 不足之处:未能提示出一些小月的错误(如某月只有29日),可加入日期进行判断(请教)
*-----------------------------------------------------
BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),5,2)),1,12) .or. BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),7,2)),1,31)

*-----------------------------------------------------
*   18位的身份证号校验程序
* 假定身份证号的变量为Id_card
*   此代码未运行过,刚写完,请指教有没有更方便的方法?
*----------------------------------------------------
local cardsum,okc,yy
dimension Ai(17),Wi(17)
if len(ALLTRIM(Id_card))=18
store VAL(SUBSTR(ALLTRIM(Id_card),1,1)) to Ai(1)
store VAL(SUBSTR(ALLTRIM(Id_card),2,1)) to Ai(2)
store VAL(SUBSTR(ALLTRIM(Id_card),3,1)) to Ai(3)
store VAL(SUBSTR(ALLTRIM(Id_card),4,1)) to Ai(4)
store VAL(SUBSTR(ALLTRIM(Id_card),5,1)) to Ai(5)
store VAL(SUBSTR(ALLTRIM(Id_card),6,1)) to Ai(6)
store VAL(SUBSTR(ALLTRIM(Id_card),7,1)) to Ai(7)
store VAL(SUBSTR(ALLTRIM(Id_card),8,1)) to Ai(8)
store VAL(SUBSTR(ALLTRIM(Id_card),9,1)) to Ai(9)
store VAL(SUBSTR(ALLTRIM(Id_card),10,1)) to Ai(10)
store VAL(SUBSTR(ALLTRIM(Id_card),11,1)) to Ai(11)
store VAL(SUBSTR(ALLTRIM(Id_card),12,1)) to Ai(12)
store VAL(SUBSTR(ALLTRIM(Id_card),13,1)) to Ai(13)
store VAL(SUBSTR(ALLTRIM(Id_card),14,1)) to Ai(14)
store VAL(SUBSTR(ALLTRIM(Id_card),15,1)) to Ai(15)
store VAL(SUBSTR(ALLTRIM(Id_card),16,1)) to Ai(16)
store VAL(SUBSTR(ALLTRIM(Id_card),17,1)) to Ai(17)

store 7 to Wi(1)
store 9 to Wi(2)
store 10 to Wi(3)
store 5 to Wi(4)
store 8 to Wi(5)
store 4 to Wi(6)
store 2 to Wi(7)
store 1 to Wi(8)
store 6 to Wi(9)
store 3 to Wi(10)
store 7 to Wi(11)
store 9 to Wi(12)
store 10 to Wi(13)
store 5 to Wi(14)
store 8 to Wi(15)
store 4 to Wi(16)
store 2 to Wi(17)
cardsum=(Ai(1)*Wi(1)+Ai(2)*Wi(2)+Ai(3)*Wi(3)+Ai(4)*Wi(4)+Ai(5)*Wi(5)+Ai(6)*Wi(6)+Ai(7)*Wi(7);
+Ai(8)*Wi(8)+Ai(9)*Wi(9)+Ai(10)*Wi(10)+Ai(11)*Wi(11)+Ai(12)*Wi(12)+Ai(13)*Wi(13);
+Ai(14)*Wi(14)+Ai(15)*Wi(15)+Ai(16)*Wi(16)+Ai(17)*Wi(17))
yy=MOD(cardsum,11)
DO case
CASE yy=0
okc='1'
CASE yy=1
okc='0'
CASE yy=2
okc='X'
CASE yy=3
okc='9'
CASE yy=4
okc='8'
CASE yy=5
okc='7'
CASE yy=6
okc='6'
CASE yy=7
okc='5'
CASE yy=8
okc='4'
CASE yy=9
okc='3'
CASE yy=9
okc='2'
endcase
if okc=SUBSTR(ALLTRIM(Id_card),18,1)
MESSAGEBOX("校验通过",48,"提示窗口标题")
else
MESSAGEBOX("校验不通过",48,"提示窗口标题")
else
MESSAGEBOX("只能校验18位的身份证号",48,"提示窗口标题")
endif


*-----------------------------------------------------
* 从18位身份证号中提取判断性别数字
* VAL(SUBSTR(ALLTRIM(Id_card),17,1)
* 从15位身份证号中提取判断性别数字
* VAL(SUBSTR(ALLTRIM(Id_card),15,1)
*-----------------------------------------------------
IF len(ALLTRIM(Id_card))=18
cardsex=VAL(SUBSTR(ALLTRIM(Id_card),17,1))
ELSE
cardsex=VAL(SUBSTR(ALLTRIM(Id_card),15,1))
ENDIF
IIF(MOD(cardsex,2)=1,'男','女')

[此贴子已经被作者于2006-9-1 10:16:57编辑过]

搜索更多相关主题的帖子: 身份证号 SUBSTR card ALLTRIM 代码 
2006-09-01 08:30
啸凡
Rank: 8Rank: 8
等 级:贵宾
威 望:45
帖 子:1356
专家分:885
注 册:2006-2-22
得分:0 
如果 cardsex=SUBSTR(ALLTRIM(Id_card),15,1))通过,
那么 IIF(MOD(cardsex,2)=1,'男','女') 能通过吗?

两人行已有我师……
2006-09-01 08:47
oopp
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-8-11
得分:0 
以下是引用啸凡在2006-9-1 8:47:35的发言:
如果 cardsex=SUBSTR(ALLTRIM(Id_card),15,1))通过,
那么 IIF(MOD(cardsex,2)=1,'男','女') 能通过吗?

可以通过,因为15位的身份证号的最后一位是判别性别的。
cardsex=SUBSTR(ALLTRIM(Id_card),15,1))
cardsex是截取了15位的身份证号的最后一位
所以IIF(MOD(cardsex,2)=1,'男','女') 是成立的

2006-09-01 08:53
Tiger5392
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:88
帖 子:2775
专家分:2237
注 册:2006-5-17
得分:0 
楼主肯定没有运行你的代码,你在3楼写的两行语句中第1行取出了一个字符,在第2行中用MOD()对这个字符进行运算就错了。

感言:学以致用。 博客:http://www./blog/user14/65009/index.shtml email:Tiger5392@
2006-09-01 09:31
啸凡
Rank: 8Rank: 8
等 级:贵宾
威 望:45
帖 子:1356
专家分:885
注 册:2006-2-22
得分:0 

呵呵,老虎就是老虎,我说的就是这个问题。我知道他根本就没有运行过,只是想让他自己去运行一下,找找原因。

[此贴子已经被作者于2006-9-1 10:02:03编辑过]


两人行已有我师……
2006-09-01 09:58
oopp
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-8-11
得分:0 

不好意思,少了VAL()函数,我边写边放上去的。还在学习当中。
顶贴少了身份证号校验码
我贴下我这个“保存”命令按键的代码吧。
*------------------------------------------------------
* 保存按键Click事件代码
* 作用:保存记录前进行一些检查,减少录入信息出错机率
*---------------------------------------------------------

LOCAL ok,dyok,cardsex,cardsum,yy,okc
dimension Ai(17),Wi(17)
*-----------------------------------------------------
* 从18位身份证号中提取生日
* 提取年 SUBSTR(ALLTRIM(thisform.txtId_card.Value),7,4)
* 提取月 SUBSTR(ALLTRIM(thisform.txtId_card.Value),11,2)
* 提取日 SUBSTR(ALLTRIM(thisform.txtId_card.Value),13,2)
* 从15位身份证号中提取生日
* 提取年 SUBSTR(ALLTRIM(thisform.txtId_card.Value),7,2)
* 提取年 SUBSTR(ALLTRIM(thisform.txtId_card.Value),9,2)
* 提取年 SUBSTR(ALLTRIM(thisform.txtId_card.Value),11,2)
*-----------------------------------------------------
IF len(ALLTRIM(thisform.txtId_card.Value))=18
dyok=SUBSTR(ALLTRIM(thisform.txtId_card.Value),7,4);
+"-"+SUBSTR(ALLTRIM(thisform.txtId_card.Value),11,2);
+"-"+SUBSTR(ALLTRIM(thisform.txtId_card.Value),13,2)
ELSE
dyok="19"+SUBSTR(ALLTRIM(thisform.txtId_card.Value),7,2);
+"-"+SUBSTR(ALLTRIM(thisform.txtId_card.Value),9,2);
+"-"+SUBSTR(ALLTRIM(thisform.txtId_card.Value),11,2)
ENDIF
*-----------------------------------------------------
* 接上:判断月份和日
*-----------------------------------------------------
*BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),5,2)),1,12) .or. BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),7,2)),1,31)
*-----------------------------------------------------
* 从18位身份证号中提取判断性别数字
* SUBSTR(ALLTRIM(thisform.txtId_card.Value),17,1)
* 从15位身份证号中提取判断性别数字
* SUBSTR(ALLTRIM(thisform.txtId_card.Value),15,1)
*-----------------------------------------------------
IF len(ALLTRIM(thisform.txtId_card.Value))=18
cardsex=VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),17,1))
ELSE
cardsex=VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),15,1))
ENDIF

*-----------------------------------------------------
* 18位身份证号校验
*-----------------------------------------------
if len(ALLTRIM(Id_card))=18
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),1,1)) to Ai(1)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),2,1)) to Ai(2)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),3,1)) to Ai(3)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),4,1)) to Ai(4)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),5,1)) to Ai(5)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),6,1)) to Ai(6)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),7,1)) to Ai(7)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),8,1)) to Ai(8)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),9,1)) to Ai(9)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),10,1)) to Ai(10)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),11,1)) to Ai(11)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),12,1)) to Ai(12)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),13,1)) to Ai(13)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),14,1)) to Ai(14)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),15,1)) to Ai(15)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),16,1)) to Ai(16)
store VAL(SUBSTR(ALLTRIM(thisform.txtId_card.Value),17,1)) to Ai(17)

store 7 to Wi(1)
store 9 to Wi(2)
store 10 to Wi(3)
store 5 to Wi(4)
store 8 to Wi(5)
store 4 to Wi(6)
store 2 to Wi(7)
store 1 to Wi(8)
store 6 to Wi(9)
store 3 to Wi(10)
store 7 to Wi(11)
store 9 to Wi(12)
store 10 to Wi(13)
store 5 to Wi(14)
store 8 to Wi(15)
store 4 to Wi(16)
store 2 to Wi(17)
cardsum=(Ai(1)*Wi(1)+Ai(2)*Wi(2)+Ai(3)*Wi(3)+Ai(4)*Wi(4)+Ai(5)*Wi(5)+Ai(6)*Wi(6)+Ai(7)*Wi(7);
+Ai(8)*Wi(8)+Ai(9)*Wi(9)+Ai(10)*Wi(10)+Ai(11)*Wi(11)+Ai(12)*Wi(12)+Ai(13)*Wi(13);
+Ai(14)*Wi(14)+Ai(15)*Wi(15)+Ai(16)*Wi(16)+Ai(17)*Wi(17))
yy=MOD(cardsum,11)
DO case
CASE yy=0
okc='1'
CASE yy=1
okc='0'
CASE yy=2
okc='X'
CASE yy=3
okc='9'
CASE yy=4
okc='8'
CASE yy=5
okc='7'
CASE yy=6
okc='6'
CASE yy=7
okc='5'
CASE yy=8
okc='4'
CASE yy=9
okc='3'
CASE yy=9
okc='2'
endcase
endif


ok=.T.
DO case
CASE EMPTY(ALLTRIM(thisform.txtId_word.Value))
MESSAGEBOX("上岗证号不能为空",48,"监巡考人员信息处理")
thisform.txtId_word.SetFocus
ok=.F.
CASE EMPTY(ALLTRIM(thisform.txtId_card.Value))
MESSAGEBOX("身份证号不能为空",48,"监巡考人员信息处理")
thisform.txtId_card.SetFocus
ok=.F.
CASE (BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),5,2)),1,12).or.BETWEEN(VAL(SUBSTR(ALLTRIM(dyok),7,2)),1,31))=.F.
MESSAGEBOX("身份证号中出生日期有误",48,"监巡考人员信息处理")
thisform.txtId_card.SetFocus
ok=.F.
CASE (len(ALLTRIM(thisform.txtId_card.Value))=15.or.len(ALLTRIM(thisform.txtId_card.Value))=18)=.F.
MESSAGEBOX("身份证号位数有误",48,"监巡考人员信息处理")
thisform.txtId_card.SetFocus
ok=.F.
CASE (okc=SUBSTR(ALLTRIM(thisform.txtId_card.Value),18,1))=.F.
MESSAGEBOX("身份证号校验有误",48,"监巡考人员信息处理")
thisform.txtId_card.SetFocus
ok=.F.
CASE EMPTY(ALLTRIM(thisform.txtName.Value))
MESSAGEBOX("姓名不能为空",48,"监巡考人员信息处理")
thisform.txtName.SetFocus
ok=.F.
CASE (IIF(MOD(cardsex,2)=1,'男','女')=ALLTRIM(thisform.txtSex.value))=.F.
MESSAGEBOX("性别有误",48,"监巡考人员信息处理")
thisform.txtsex.SetFocus
ok=.F.
CASE (CTOD(dyok)=thisform.txtBirthday.Value)=.F.
MESSAGEBOX("出生日期有误",48,"监巡考人员信息处理")
thisform.txtId_card.SetFocus
ok=.F.
CASE EMPTY(ALLTRIM(thisform.txtM_mobile.Value))
MESSAGEBOX("联系方式不能为空",48,"监巡考人员信息处理")
thisform.txtM_mobile.SetFocus
ok=.F.
ENDCASE
IF ok=.T.
yn=MESSAGEBOX("确定保存",4+32,"监巡考人员信息处理")
IF yn=6
IF TABLEUPDATE(.F.)=.F.
MESSAGEBOX("保存失败",4+32,"监巡考人员信息处理")
thisform.txtName.SetFocus

ELSE
MESSAGEBOX("保存成功",64,"监巡考人员信息处理")
SELECT EMPLOYEE
IF EOF() .or. BOF()
GO thisform.oldrecord
endif
thisform.mdbrowse
thisform.Refresh
ENDIF
ENDIF
ENDIF

2006-09-01 10:14
Tiger5392
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:88
帖 子:2775
专家分:2237
注 册:2006-5-17
得分:0 
oopp不错,继续努力

感言:学以致用。 博客:http://www./blog/user14/65009/index.shtml email:Tiger5392@
2006-09-01 10:16
oopp
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-8-11
得分:0 
转一个关于身份证号的贴子

希望对大家有点用。也请看看我写的代码有没有错。


$$$$$$$$$$$$$$

18位公民身份证号码的编排规则

  18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号码》中做了明确规定。

  GB11643-1999《公民身份号码》为GB11643-1989《社会保障号码》的修订版,其中指出将原标准名称“社会保障号码”更名为“公民身份号码”,另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。

  公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位校验码。其含义如下:

  1. 地址码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。

  2. 出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日分别用4位、2位、2位数字表示,之间不用分隔符。

  3. 顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。

  校验的计算方式:

  1. 对前17位数字本体码加权求和
  公式为:S = Sum(Ai * Wi), i = 0, ... , 16
  其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

  2. 以11对计算结果取模
  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

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
下面是C程序代码:
// char szSrc1[]="11010519491231002X";
// DoVerify(szSrc1);
// char szSrc2[]="440524188001010014";
// DoVerify(szSrc2);
char DoVerify(const char* pszSrc)
{
int iS = 0;
int iW[]={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
static char szVerCode[]="10X98765432";
int i;
for(i=0;i<17;i++)
{
iS += (int)(pszSrc[i]-'0') * iW[i];
}
int iY = iS%11;
// printf("%d %% 11 = iY = %d\n",iS, iY);
// printf("%c \n",szVerCode[iY]);
return szVerCode[iY];

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
<script language="vbscript">
<!--
'18位身份证号码验证函数
'By Y.Y.Shan
'2005-8-16
function checkid(idstr)
'位数验证
if len(idstr)<>"18" then
msgbox ("位数错误!该程序只验证18位身份证号码。")
else

dim checknum,cnu,idnum(18)
'权数
checknum=Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)
'校验码
cnu=Array("1","0","X","9","8","7","6","5","4","3","2")
csex=Array("","男","女")
for i = 1 to 18
idnum(i)=mid(idstr,i,1)
next

'求和
for i = 1 to 17
x=x+checknum(i-1)*idnum(i)
next
'取模
y=cnu(x mod 11)
'
if y=idnum(18) then
msgbox("验证通过!出生日期:"&mid(idstr,7,4)&"年"&mid(idstr,11,2)&"月"&mid(idstr,13,2)&"日,"&csex(cint(mid(idstr,17,1)))&"性。")
else
msgbox("验证未通过!")
end if
end if
end function

checkid("320926198112070016")
-->
</script>

2006-09-01 10:20
dong2dong
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2006-10-19
得分:0 
上面程序段中的这段代码:
DO case
CASE yy=0
okc='1'
CASE yy=1
okc='0'
CASE yy=2
okc='X'
CASE yy=3
okc='9'
CASE yy=4
okc='8'
CASE yy=5
okc='7'
CASE yy=6
okc='6'
CASE yy=7
okc='5'
CASE yy=8
okc='4'
CASE yy=9
okc='3'
CASE yy=9
okc='2'
endcase
可以这样简化为一句:
okc=subs('10X98765432',yy+1,1)

[此贴子已经被作者于2006-10-19 22:59:32编辑过]

2006-10-19 22:58



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-87321-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.101266 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved