這是一個用Python/ target=_blank class=infotextkey>Python開發的GUI實戰項目:居民身份證信息校驗系統
一、總體介紹
本項目使用Tkinter作為GUI模塊,充分利用Python面向對象的思想,開發一款實現身份證號碼校驗的應用程序。具備解析用戶輸入的身份證號碼中的地區信息、出生日期、以及身份證號碼是否合法等功能。是練習Python面向對象思想、tkinter GUI模塊的優質練手項目。
項目演示
項目整體效果
以上,如果我們輸入一個正確的身份證號碼,系統可以正常解析;但是篡改其中一位的話,校驗結果直接顯示無效;如果少輸入一位的話,系統會提示“請輸入18位”。
二、認識身份證號碼
身份證號碼的構成如下:
身份證號碼的構成
(1)地區碼:身份證前6位就是地區碼,中國每一個地區都對應一個地區碼,按照GB/T2260執行。通常1開頭為華北地區、2開頭為東北地區、3開頭為華東地區、4開頭為華中地區和華南地區、5開頭為西南地區、6開頭為西北地區、7和8開頭為特別地區。
(2)出生日期碼:表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年月日代碼之間不用分隔符。
(3)順序碼:表示在同一地址碼所標識的區域范圍內,對同年同月同日出生的人編訂的順序號,順序碼的奇數分配給男性、偶數分配給女性。
(4)校驗碼:身份證第18位是校驗碼,對前17位做一個運算,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼得到第18位的數字。
校驗方法:
圖解身份證號碼最后一位校驗碼的計算過程
文字詳細描述
三、實現界面類:IDCheckGUI
在工程項目中新建一個idcheckgui.py的文件用來生成GUI界面
from tkinter import *
from tkinter.ttk import *
import os
class IDCheckGUI(Tk):
def __init__(self):
super().__init__()
self.title("身份證信息校驗系統")
self.geometry("800x510+400+200")
self.resizable(0,0)
self["bg"] = "whitesmoke"
self.setup_UI()
def setup_UI(self):
self.style01 = Style()
self.style01.configure("input.TLabel",font=("微軟雅黑",20,"bold"))
self.style01.configure("TLabel",font=("微軟雅黑",20,"bold"),foreground = "navy")
self.style01.configure("TButton",font=("微軟雅黑",20,"bold"),background = "lightblue")
# 圖片
self.Login_image = PhotoImage(file = "."+os.sep+"img"+os.sep+"id2.png")
self.Label_image = Label(self,image = self.Login_image)
self.Label_image.place(x=5,y=5)
# 輸入信息
self.Label_id_input = Label(self,text = "請輸入身份證號碼:",style="input.TLabel")
self.Label_id_input.place(x=400,y=20)
self.var_input = StringVar()
self.Entry_id_input = Entry(self,textvariable = self.var_input,width=20,font=("微軟雅黑",18,"bold"))
self.Entry_id_input.place(x = 400,y=70)
self.Button_id_input = Button(self,text="校驗",command = self.get_info)
self.Button_id_input.place(x = 660,y = 70)
# 具體信息
self.Label_is_exsit = Label(self,text = "是否有效:")
self.Label_is_exsit.place(x=400,y=170)
self.var_enable = StringVar()
self.Entry_is_exsit = Entry(self, state=DISABLED,textvariable=self.var_enable, width=10, font=("微軟雅黑", 18, "bold"))
self.Entry_is_exsit.place(x=530, y=165)
self.Label_is_gender = Label(self, text="性 別:")
self.Label_is_gender.place(x=400, y=220)
self.var_gender = StringVar()
self.Entry_is_gender = Entry(self, state=DISABLED,textvariable=self.var_gender, width=10, font=("微軟雅黑", 18, "bold"))
self.Entry_is_gender.place(x=530, y=215)
self.Label_is_birthday = Label(self, text="出生日期:")
self.Label_is_birthday.place(x=400, y=270)
self.var_birthday = StringVar()
self.Entry_is_birthday = Entry(self, state=DISABLED,textvariable=self.var_birthday, width=18, font=("微軟雅黑", 19, "bold"))
self.Entry_is_birthday.place(x=530, y=265)
self.Label_is_area = Label(self, text="所 在 地:")
self.Label_is_area.place(x=400, y=320)
self.var_area = StringVar()
self.Entry_is_area = Entry(self,state=DISABLED, textvariable=self.var_area, width=18, font=("微軟雅黑", 19, "bold"))
self.Entry_is_area.place(x=530, y=315)
self.Button_close = Button(self,text = "關閉",command = self.close_window)
self.Button_close.place(x = 650, y= 450)
def close_window(self):
self.destroy()
def get_info(self):
self.var_enable.set("有效!")
由于我們使用面向對象的思想開發,我們把主函數放在另一個文件中startcheck.py中,在startcheck模塊下導入我們實現GUI的模塊idcheckgui
from idcheckgui import *
if __name__ == '__main__':
check_gui = IDCheckGUI()
check_gui.mainloop()
運行演示
GUI界面搭建
現在我們只是搭建了GUI界面,并沒有真正的進行校驗操作。
注意:在使用面向對象思想導入自定義模塊時,如果出現導入的包無法讀取的情況。
方法一:最好在新建一個空工程的根目錄下就放上所有的python程序文件;
方法二:或者鼠標選中工程目錄,右鍵菜單選擇Mark Directory as然后選擇Sources Root即可。
四、實現功能類:IDCheck
1. 檢查校驗碼
(1) 對身份證號碼進行切片 首先我們把獲取到的身份證號碼分成地區碼、生日碼、順序碼、校驗碼,四個部分,存儲在列表id_list[]中。
通過get_id_list方法對身份證號碼字符串進行切片:
def get_id_list(self):
# 地區碼
self.id_list.Append(self.id_number[:6])
# 出生日期碼
self.id_list.append(self.id_number[6:14])
# 順序碼
self.id_list.append(self.id_number[14:17])
# 校驗碼
self.id_list.append(self.id_number[17:])
return self.id_list
(2)根據前17位計算校驗碼 獲取身份證號碼的前17位存儲在number中,然后對17位數字分別乘以系數[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2],累加得出結果后對11進行取余,將獲得的結果作為索引取出列表["1","0","x","9","8","7","6","5","4","3","2"]中的值即為校驗碼。
def get_check_number(self):
"""
取出校驗碼
:return: 返回的校驗碼
"""
number = self.id_number[:17]
xi_list = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2] # 每個位上乘的系數列表
check_number = ["1","0","x","9","8","7","6","5","4","3","2"] # 返回的校驗碼列表
sum_of_number = 0
for index in range(len(number)):
sum_of_number += int(number[index]) * xi_list[index]
# 余數
yu_number = sum_of_number % 11
return check_number[yu_number]
(3) 將計算出的校驗碼與身份證最后一位比較,我們提前在構造函數設置靜態屬性self.is_true_id_number = 0,如果校驗碼核對成功,便將其值設為1
def validate_check_number(self):
if self.get_check_number() == self.id_list[3]:
self.is_true_id_number = 1
2. 檢查出生日期
我們規定出生日期必須介于1900-01-01到當前的日期,只要時間在這個區間內就算有效,超過這個范圍就算無效。
def validate_birthday(self):
date_from = datetime(year=1900,month=1,day=1)
date_to = datetime.today()
id_birthday = datetime(year=int(self.id_number[6:10]),month=int(self.id_number[10:12]),day=int(self.id_number[12:14]))
if id_birthday > date_from and id_birthday < date_to:
self.birthday = self.id_number[6:10]+"年"+self.id_number[10:12]+"月"+self.id_number[12:14]+"日"
3. 校驗地區碼
校驗身份證號碼中的地區碼是否合法,我們主要需要完成兩步操作:
(1)從文件導入地區碼,存儲在列表area_list中;
由于地區碼與地區名的對應關系我們存儲在一個id_area.txt的文件中
身份證號碼前6位與其對應的行政區域
我們可以通過讀取文件中每一行的數據,使用逗號作為分隔符生成一個列表,再將該列表添加到area_list列表中。
def import_area_id(self):
try:
with open(file=self.file_path,mode="r",encoding="UTF-8") as fd:
current_line = fd.readline()
while current_line:
current_area_list = current_line.split(",")
if len(current_area_list[0]) == 6:
self.area_list.append(current_area_list)
current_line = fd.readline()
except:
showinfo("系統提醒","地區文件讀取失敗")
(2)校驗當前身份證上的地區碼是否在列表中;
我們定義一個validate_area_id的方法,將從輸入的身份證號碼中的地區碼與area_list中的地區碼進行比對,從而獲取對應的地區名
def validate_area_id(self):
for index in range(len(self.area_list)):
if self.area_list[index][0] == self.id_list[0]:
self.area_name = self.area_list[index][1]
break
4. 識別身份證號碼的性別
我們可以直接根據身份證號碼的第三部分判斷其奇偶數來確定性別,id_list列表的第三部分存儲的是順序碼,將順序碼先轉為整型然后對2取余。如果等于0說明是偶數,即女性;如果等于1說明是奇數,即男性。
def get_gender(self):
if int(self.id_list[2]) % 2 == 0:
self.gender = "女"
else:
self.gender = "男"
五、完成身份證的校驗
我們在id_checkgui模塊中,定義一個get_info函數用于對輸入的身份證號碼進行校驗。 我們需要導入前面寫的idcheck模塊,使用該模塊下的IdCheck類構造一個檢驗對象check_id,傳入的參數為本模塊GUI中輸入框獲取到的值。
校驗邏輯為:
身份證校驗的邏輯
def get_info(self):
id_number = self.var_input.get()
if len(id_number) == 18:
check_id = idcheck.IdCheck(id_number)
if check_id.is_true_id_number == 0 or len(check_id.birthday) == 0 or len(check_id.area_name) == 0:
self.var_enable.set("無效!")
else:
self.var_enable.set("有效")
self.var_gender.set(check_id.gender)
self.var_birthday.set(check_id.birthday)
self.var_area.set(check_id.area_name)
else:
self.var_enable.set("無效")
self.var_gender.set("")
self.var_birthday.set("")
self.var_area.set("")
showinfo("系統消息", "輸入的身份證號碼不滿18位,請重新輸入!")
最后再將GUI模塊中的校驗按鈕添加command參數其值設置為get_info即可。
效果演示:
情況一:輸入的身份證號碼不滿18位(我們故意輸入17位):
身份證號碼位數不足時
情況二:最后一位校驗位錯誤(本來是7我們故意輸入8)
最后一位身份證號碼故意輸錯時
情況三:輸入正確的身份證號碼的情況
正確輸入身份證號碼的情況
最后
本項目利用Tkinter開發了一個身份證號碼校驗系統,能夠識別用戶輸入的身份證號碼的有效性,并且解析身份證號碼的地區、出生日期、性別等有效信息,感興趣的小伙伴可以私信我獲取全套的源碼、素材、及數據源,一起上手練習一下。
小伙伴們,如果覺得文章還不錯的話,希望能點個贊;如果覺得很有用的話那就轉發一下;如果覺得這個作者很棒那就關注一下,你們的支持是我更新最大的動力!