身份证校验算法

blue_linus 2006-07-19 12:07:39
VFP的身份证校验算法!
...全文
874 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
十豆三 2006-07-19
  • 打赏
  • 举报
回复
详细请参考:

http://blog.csdn.net/apple_8180/archive/2006/07/19/941626.aspx
十豆三 2006-07-19
  • 打赏
  • 举报
回复
*-----------------------------
*
*此函数功能:输入的15位或17位或18位的身份证号,返回校验后的最后一位
*
*-----------------------------
FUNCTION sfzjy
Parameters cID
DO CASE
CASE LEN(ALLTRIM(cID)) = 15
cID = STUFF(ALLTRIM(cID),7,0,"19")
CASE LEN(ALLTRIM(cID)) = 18 OR LEN(ALLTRIM(cID)) = 17
cID =LEFT(ALLTRIM(cID),17)
OTHERWISE
RETURN .F.
ENDCASE
If Len(ALLTRIM(cID))#17
Return .f.
Endif
nSum= Val(SubStr(cID,1,1)) * 7 ;
+ Val(SubStr(cID,2,1)) * 9 ;
+ Val(SubStr(cID,3,1)) * 10 ;
+ Val(SubStr(cID,4,1)) * 5 ;
+ Val(SubStr(cID,5,1)) * 8 ;
+ Val(SubStr(cID,6,1)) * 4 ;
+ Val(SubStr(cID,7,1)) * 2 ;
+ Val(SubStr(cID,8,1)) * 1 ;
+ Val(SubStr(cID,9,1)) * 6 ;
+ Val(SubStr(cID,10,1)) * 3 ;
+ Val(SubStr(cID,11,1)) * 7 ;
+ Val(SubStr(cID,12,1)) * 9 ;
+ Val(SubStr(cID,13,1)) * 10 ;
+ Val(SubStr(cID,14,1)) * 5 ;
+ Val(SubStr(cID,15,1)) * 8 ;
+ Val(SubStr(cID,16,1)) * 4 ;
+ Val(SubStr(cID,17,1)) * 2
*计算校验位
check_number=INT((12-nSum % 11)%11)
If check_number=10
check_number='X'
Endif
Return check_number
Endfunc
十豆三 2006-07-19
  • 打赏
  • 举报
回复
*-----------------------------
*
*此函数功能:检验输入的15位或18位身份证号码是否为合法
*
*-----------------------------

FUNCTION MyIdentityCardVerify &&校验身份证号是否合法
LPARAMETERS lstr &&参数:lstr 传入的号码
PRIVATE lstr,relyn,tsfz,m1,m2,m3,m4,m,I,r,c,ai,wi
relyn=.F. &&返回值
tsfz=ALLTRIM(lstr)
*分别用m1,m2,m3,m4表示四个条件是否成立
STOR .T. TO m1,m2,m3,m4
*条件1:只能是15或18位
m1=IIF(LEN(tsfz)=15 OR LEN(tsfz)=18,.T.,.F.)
IF LEN(tsfz)=15 && 15位的号码
FOR I=1 TO 15 &&检查每一位是否为数字
m=ASC(SUBSTR(tsfz,I,1))
IF m<48 OR m>57 &&数字
m2=.F. &&若有一位不是就不再查
EXIT
ENDIF
ENDFOR
m="19" +SUBSTR(tsfz, 7,2) &&早期的号都是上个世纪的
m=m+"."+SUBSTR(tsfz, 9,2)
m=m+"."+SUBSTR(tsfz,11,2)
m=CTOD(m)
IF ISNULL(m) OR ISBLANK(m)
m3=.F. &&生日不正确
ENDIF
ENDIF
IF LEN(tsfz)=18 && 18位的号码
FOR I=1 TO 17
m=ASC(SUBSTR(tsfz,I,1))
IF m<48 OR m>57
m2=.F.
EXIT
ENDIF
ENDFOR
m=SUBSTR(tsfz,7,4)
m=m+"."+SUBSTR(tsfz,11,2)
m=m+"."+SUBSTR(tsfz,13,2)
m=CTOD(m)
IF ISNULL(m) OR ISBLANK(m)
m3=.F.
ENDIF
r=0 &&计算校验位
FOR I=18 TO 2 STEP -1
ai=VAL(SUBSTR(tsfz,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(tsfz,18,1))<>c
m4=.F. &&校验位与原码最末位不同
ENDIF
ENDIF
*四个条件全成立,则返回.t.
relyn=IIF(m1 AND m2 AND m3 AND m4,.T.,.F.)
RETURN relyn
ENDFUNC
十豆三 2006-07-19
  • 打赏
  • 举报
回复
关于身份证号码最后一位的校验码的算法如下:

我国现行使用公民身份证号码有两种尊循两个国家标准,〖GB 11643-1989〗和〖GB 11643-1999〗。
〖GB 11643-1989〗中规定的是15位身份证号码:排列顺序从左至右依次为:六位数字地址码,六位数字出生日期码,三位数字顺序码,其中出生日期码不包含世纪数。
〖GB 11643-1999〗中规定的是18位身份证号码:公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
公式如下:
  ∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1)
  "*" 表示乘号
  i--------表示身份证号码每一位的序号,从右至左,最左侧为18,最右侧为1。
  a[i]-----表示身份证号码第 i 位上的号码
  W[i]-----表示第 i 位上的权值 W[i] = 2^(i-1) mod 11
  计算公式 (1) 令结果为 R
根据下表找出 R 对应的校验码即为要求身份证号码的校验码C。
  R 0 1 2 3 4 5 6 7 8 9 10
  C 1 0 X 9 8 7 6 5 4 3 2
由此看出 X 就是 10,罗马数字中的 10 就是X,所以在新标准的身份证号码中可能含有非数字的字母X。
blue_linus 2006-07-19
  • 打赏
  • 举报
回复
顶下...
blue_linus 2006-07-19
  • 打赏
  • 举报
回复
将一个数值转换成字符串咋办? 123456789转换成"123456789"
十月鹰飞 2006-07-19
  • 打赏
  • 举报
回复
看过,学习

2,749

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧