用Python寫一個身份證號碼校驗系統

這是一個用Python開發的GUI實戰項目:居民身份證信息校驗系統python

1、整體介紹

本項目使用Tkinter做爲GUI模塊,充分利用Python面向對象的思想,開發一款實現身份證號碼校驗的應用程序。具有解析用戶輸入的身份證號碼中的地區信息、出生日期、以及身份證號碼是否合法等功能。是一款練習Python面向對象思想、tkinter GUI模塊的優質練手項目。web

項目演示

以上,若是咱們輸入一個正確的身份證號碼,系統能夠正常解析;可是篡改其中一位的話,校驗結果直接顯示無效;若是少輸入一位的話,系統會提示「請輸入18位」。編程

2、認識身份證號碼

身份證號碼的構成以下:

(1)地區碼:身份證前6位就是地區碼,中國每個地區都對應一個地區碼,按照GB/T2260執行。一般1開頭爲華北地區、2開頭爲東北地區、3開頭爲華東地區、4開頭爲華中地區和華南地區、5開頭爲西南地區、6開頭爲西北地區、7和8開頭爲特別地區。 微信

(2)出生日期碼:表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年月日代碼之間不用分隔符。 app

(3)順序碼:表示在同一地址碼所標識的區域範圍內,對同年同月同日出生的人編訂的順序號,順序碼的奇數分配給男性、偶數分配給女性。編輯器

 (4)校驗碼:身份證第18位是校驗碼,對前17位作一個運算,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼獲得第18位的數字。函數

校驗方法oop

身份證號碼末尾校驗碼的計算原理

3、實現界面類: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的模塊idcheckguiflex

from idcheckgui import *
if __name__ == '__main__':
    check_gui = IDCheckGUI()
    check_gui.mainloop()

運行演示

如今咱們只是搭建了GUI界面,並無真正的進行校驗操做。

注意:在使用面向對象思想導入自定義模塊時,若是出現導入的包沒法讀取的狀況。 

方法一:最好在新建一個空工程的根目錄下就放上全部的python程序文件;方法二:或者鼠標選中工程目錄,右鍵菜單選擇Mark Directory as而後選擇Sources Root便可。

4、實現功能類: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的文件中咱們能夠經過讀取文件中每一行的數據,使用逗號做爲分隔符生成一個列表,再將該列表添加到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 = "男"

5、完成身份證的校驗

咱們在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開發了一個身份證號碼校驗系統,可以識別用戶輸入的身份證號碼的有效性,而且解析身份證號碼的地區、出生日期、性別等有效信息,感興趣的小夥伴能夠直接後臺私信「身份證信息校驗系統」獲取全套的源碼、素材、及數據源,一塊兒上手體驗一下這個項目。



·END·

小雨編程

分享有價值的學習教程



O(∩_∩)O哈哈~感謝你的關注


若是以爲還不錯的話,點個「」和「在看」支持一下~

本文分享自微信公衆號 - 小雨編程(xiaoxiaoyu1926)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索