梦想吧技术论坛's Archiver

似水年华 发表于 2007-4-22 06:12 PM

AU3-大陆身份证号码校验工具

#NOTRAYICON  ;;;不显示托盘图标
;;;防止重复打开程序
$g_szVersion = "My Script 1.1"
If WinExists($g_szVersion) Then Exit
AutoItWinSetTitle($g_szVersion)

;;;创建GUI必须要加的
#include <GUIConstants.au3>
;;;创建程序主界面
GUICreate("大陆身份证号码校验系统  V1.0 Bate 1", 340, 130)
;;;创建左边三个输入框
$Input1 = GUICtrlCreateInput("", 8, 24, 129, 21,$ES_NUMBER)  ;;;$ES_NUMBER为只允许输入数字
GUICtrlSetLimit ( -1, 15)   ;;;限制最多输入十五位
$Input2 = GUICtrlCreateInput("", 8, 64, 129, 21,$ES_NUMBER)
GUICtrlSetLimit ( -1, 17)
$Input3 = GUICtrlCreateInput("", 8, 104, 129, 21,$ES_LOWERCASE)  ;;;$ES_LOWERCASE一律转换为小写
GUICtrlSetLimit ( -1, 18)

;;;创建三个按钮
$Button1 = GUICtrlCreateButton("转换", 144, 24, 45, 21)
$Button2 = GUICtrlCreateButton("生成", 144, 64, 45, 21)
$Button3 = GUICtrlCreateButton("校验", 144, 104, 45, 21)

;;;创建标签,也就是一些文本提示信息
GUICtrlCreateLabel("十五位身份证号码转十八位:          程序制作:路人", 8, 8, 313, 15)
GUICtrlCreateLabel("根椐前十七位生成校验码:", 8, 48, 148, 15)
GUICtrlCreateLabel("十八位身份证号码校验:", 8, 88, 136, 15)

;;;创建右边的三个输入框
$Input4 = GUICtrlCreateInput("", 200, 24, 129, 21, -1)
$Input5 = GUICtrlCreateInput("", 200, 64, 129, 21, -1)
$Input6 = GUICtrlCreateInput("", 200, 104, 129, 21, -1)

GUISetState(@SW_SHOW)
;;;主循坏;;;等待用户操作

While 1
$msg = GuiGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE  ;;;点右上角关闭则退出
  ExitLoop
Case $msg = $button1          ;;;点"生成"按钮则
  $idINPUT1 = GUICTRLREAD($INPUT1)   ;;读取第一个输入框的内容,赋到$idINPUT1
  $FUNCALL = 1                       ;;使$funcall的值为1,下面初次校验函数会根椐他的值的不同来转到不同的函数
  firstcheck($idINPUT1)              ;;转到firstcheck()函数.并传送$IDINPUT1的值过去
Case $msg = $button2                       ;;下略,根椐上面三行的来理解
  $idINPUT2 = GUICTRLREAD($INPUT2)
  $FUNCALL = 2
  firstcheck($idINPUT2)              
Case $msg = $button3
  $idINPUT3 = GUICTRLREAD($INPUT3)
  $FUNCALL = 3
  firstcheck($idINPUT3)
EndSelect
WEnd
Exit

;;;下面一个函数为初次校验函数,全面校验用户输入的数据的有效性
;;;然后转到各个函数执行
;;;;;;;;;;;;;;;;;;;;;;;;;
FUNC firstcheck($X)        ;;;接收上面调用时传过来的值存入$x
LOCAL $IDLEN,$YEAR,$mon,$day        ;;;定义局部变量,局部变量只在本函数内有效
$idlen = STRINGLEN($x)     ;;;取用户输入内容的长度


;;;身份证号码第一位不是会9,9开头暂时还没用到,所以如果第一位为9的话肯定是错的
if STRINGLEFT($x,1) = 9 then
msgbox (0,"错误_code01","你输入了错误的身份证号码!")
return
ENDIF
;;;;;;;;;;;;;;;
;;;下面这个看出错提示就可以了.
IF $idlen = 15 THEN
$YMD = 0
ELSE
$YMD = 2
ENDIF
$YEAR = StringMid($X,7,2+$YMD)      ;;;取年份信息
IF STRINGLEN($YEAR) = 2 THEN $YEAR = "19" & $YEAR
IF $YEAR < 1900 OR $YEAR > 2008 then     ;;;如果年分小于1900或大于2008则提示出错
msgbox (0,"错误_code03","你输入的身份证号码年份信息有误!")
return
ENDIF
$mon = StringMid($X,9+$ymd,2)      ;;;取月份信息
IF $mon < 1 OR $mon > 12 then
msgbox (0,"错误_code03","你输入的身份证号码月份信息有误!")
return
ENDIF
$day = StringMid($X,11+$ymd,2)      ;;;取月份信息
IF $day < 1 OR $day > 31 then     ;;;想更准确的话你就算一下哪个月有多少天,平年还是闰年,再来比较,更准确;变态
msgbox (0,"错误_code03","你输入的身份证号码生日信息有误!")
return
ENDIF

SELECT
CASE  $FUNCALL =1                      ;;;如果$FUNCALL的值为1,见主循环部分
IF $IDLEN <> 15 THEN           ;;;如果输入的为不十五位,那么就提示出错并返回
  msgbox (0,"错误_code02","你输入的身份证号码位数不为十五位!")
  return
ENDIF
CONVERSION($X)
CASE  $FUNCALL =2
IF $IDLEN <> 17 THEN
  msgbox (0,"错误_code04","你输入的身份证号码位数不为十七位!")
  return
ENDIF
MAKE($X)
CASE  $FUNCALL =3
IF $IDLEN <> 18 THEN
  msgbox (0,"错误_code06","你输入的身份证号码位数不为十八位!")
  return
ENDIF
CHECKOUT($X)
ENDSELECT
ENDFUNC
;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;15位转18位函数,调用了另一个根椐前十七位算校验码的自定义函数
;;;;;;;;;;;;;;;;;;;;;;;;;
FUNC conversion($IDNUM15)    ;;接收上面调用时传过来的参数存到$IDNUM15
LOCAL $checkcode,$idnum17,$idnum18    ;;;局部变量
$idnum17 = stringleft($IDNUM15,6) & "19" & stringmid($idnum15,7)    ;;;添为字符串"19"到6位与7位之间,这样就变成了十七位
$idnum18 = $idnum17 &  MAKECHECKCODE($idnum17)   ;;;再拿上面生成的十七位生成效验码再连接到这十七位后面,就是完整的18位身份证号码了
guictrlsetdata ($input4,$idnum18)                ;;;使$INPUT4文件框的显示的值为生成后的十八位号码
return
ENDFUNC
;;;;;;;;;;;;;;;;;;;;;;;;
FUNC make($x)
$CHECKCODE = MAKECHECKCODE($X)    ;;;生成校验码
IF $CHECKCODE = -1 THEN           ;;;如果返回-1则提示错误,实际上经过初校以后,这里不可能返回-1了
  msgbox (0,"错误_code11","生成效验码时发生错误!")
  return
ELSE
  $X = $X & $CHECKCODE      ;;;用户输入的十七位加校验码=完整身份证号码
ENDIF
GUICTRLSETDATA($INPUT5,$X)              ;;;使$INPUT5输入框的显示完整号码
ENDFUNC
;;;;;;;;;;;;;;;;;;;;;;;;;
FUNC checkout($x)          ;;;校验18位号码最后一位的校验码是否正确的函数
local $idnum,$checkcode
$idnum = stringleft ($x,17)   ;;取前十七位
$checkcode = MAKECHECKCODE($iDnum)    ;;;根椐上面取的十七位来算校验码
if $checkcode = stringright($x,1) then   ;;;如果算的校验码等于本身的校验码则
  GUIctrlsetdata($input6,"校验码正确")  ;;在$INPUT6文本输入框中显示,正确
ELSE
  GUIctrlsetdata($input6,stringleft ($x,17) & $checkcode)  ;;;否则显示出新的号码.
ENDIF
RETURN
ENDFUNC

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;本函数为身份证号码校验码生成函数,也是本程序的核心部分
;;;调用方式MAKECHECKCODE($ID),$ID为身份证号码前十七位,
;;;传过来的字符串不为十七位则返回-1,成功则返回校验码
;;;其它信息都未进行校验,请调用时先自行校验
;;;郁闷,请问怎么样在定义数组的时候赋初值
;;;难道真的像我这样一个个赋值吗
;;;假如先定义一个长的字符串如:$x = "7,9,10,5,8,4,2,1,6,3"
;;;然后再用$W1 = stringsplit($x,",")分开,哪个效率更高?
FUNC MAKECHECKCODE($iD)
IF STRINGLEN($id) <> 17 THEN RETURN -1
LOCAL $W1[18],$code[12],$id,$A[18],$sum = 0,$y,$checkcode
$W1[1] = 7
$W1[2] = 9
$W1[3] = 10
$W1[4] = 5
$W1[5] = 8
$W1[6] = 4
$W1[7] = 2
$W1[8] = 1
$W1[9] = 6
$W1[10] = 3
$W1[11] = 7
$W1[12] = 9
$W1[13] = 10
$W1[14] = 5
$W1[15] = 8
$W1[16] = 4
$W1[17] = 2
$code[1] = 1
$code[2] = 0
$code[3] = "x"
$code[4] = 9
$code[5] = 8
$code[6] = 7
$code[7] = 5 这一个5应该改成6以前是我大意了。
$code[8] = 5
$code[9] = 4
$code[10] = 3
$code[11] = 2
for $I = 1 to stringlen($id)
$A[$I] = STRINGMID($id,$I,1)
$SUM = $sum + $A[$I] * $w1[$I]
NEXT
$y = MOD ($sum,11)
$checkcode = $code[$y + 1]
return $checkcode
ENDFUNC

页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.