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