验证身份证号码是否正确,包括地区信息、出生年月日、性别、末位校验码。
先用qtDesigner生成 ui文件,然后用PySide2-uic把ui文件转换为py代码。再写一个类继承ui文件转换的类,这样ui和代码分离开,ui文件修改后不用重新写代码。
还用了一个sqlite数据库用来存放身份证前6位地区代码和对应文字内容,如下。链接:数据库链接
代码:
from sfz import Ui_Form
from PySide2 import QtWidgets, QtGui, QtCore
import sys
import datetime
import sqlite3
import os.path
class SfzDialog(Ui_Form, QtWidgets.QWidget):
cx = None
cu = None
def __init__(self):
super(SfzDialog, self).__init__()
self.setupUi(self)
if not os.path.exists('sfz.db'):
QtWidgets.QMessageBox.critical(None, '错误', '数据库文件 sfz.db 未找到!')
app.exec_()
else:
self.cx = sqlite3.connect('sfz.db')
self.cu = self.cx.cursor()
self.btnQuery.clicked.connect(self.query)
self.btnClear.clicked.connect(self.clear)
self.lEditNum.textChanged.connect(self.lEditNumTextChanged)
def closeEvent(self, event):
if self.cx is not None:
self.cx.close()
def clear(self):
self.lEditGender.setText('')
self.lEditRegion.setText('')
self.lEditBirth.setText('')
self.lEditResult.setText('')
self.lEditNum.setText('')
def query(self):
if not os.path.exists('sfz.db'):
QtWidgets.QMessageBox.critical(None, '警告', '数据库文件 sfz.db 未找到!程序将退出!')
app.exec_()
sfz = self.lEditNum.text()
self.lEditGender.setText('')
self.lEditRegion.setText('')
self.lEditBirth.setText('')
self.lEditResult.setText('')
# 长度
if len(sfz) != 18:
QtWidgets.QMessageBox.warning(None, '注意', '身份证长度错误!')
return
# 校验码
idCodeTuple = (7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
checkCodeTuple = ('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
if checkCodeTuple[sum((a * b for a, b in zip(idCodeTuple, (int(a) for a in sfz[:-1])))) % 11] != sfz[-1].upper():
self.lEditResult.setText('末位校验码错误')
return
# 地区
region = sfz[:6]
sql = self.cu.execute('select region from sfz_0 where number = ?', (region,)).fetchone()
if sql is None:
self.lEditResult.setText('地区错误')
return
else:
self.lEditRegion.setText(sql[0])
# 年月日
year = sfz[6:10]
month = sfz[10:12]
day = sfz[12:14]
try:
datetime.date(int(year), int(month), int(day))
except ValueError:
self.lEditResult.setText('出生年月日格式错误')
return
if year + month + day > datetime.datetime.now().strftime('%Y%m%d') or year<'1900':
self.lEditResult.setText('出生年月日错误')
return
self.lEditBirth.setText(year + '年' + month + '月' + day + '日')
# 性别
gender = sfz[16:17]
if int(gender) % 2 == 0:
self.lEditGender.setText('女')
else:
self.lEditGender.setText('男')
self.lEditResult.setText('身份证校验正确')
def lEditNumTextChanged(self):
preRegex = QtCore.QRegExp('^\d{17}[0-9xX]$') # 身份证正则预校验
preValidator = QtGui.QRegExpValidator(preRegex, self.lEditNum)
self.lEditNum.setValidator(preValidator)
if __name__ == '__main__':
app = QtWidgets.QApplication()
MainWindow = SfzDialog()
MainWindow.show()
sys.exit(app.exec_())
ui文件自动转换代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'sfz.ui',
# licensing of 'sfz.ui' applies.
#
# Created: Tue Jan 15 22:42:05 2019
# by: pyside2-uic running on PySide2 5.12.0
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(693, 424)
self.lEditResult = QtWidgets.QLineEdit(Form)
self.lEditResult.setGeometry(QtCore.QRect(190, 120, 331, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.lEditResult.setFont(font)
self.lEditResult.setReadOnly(True)
self.lEditResult.setObjectName("lEditResult")
self.label_5 = QtWidgets.QLabel(Form)
self.label_5.setGeometry(QtCore.QRect(110, 330, 71, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.btnQuery = QtWidgets.QPushButton(Form)
self.btnQuery.setGeometry(QtCore.QRect(560, 50, 93, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.btnQuery.setFont(font)
self.btnQuery.setObjectName("btnQuery")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(70, 120, 101, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.label_4 = QtWidgets.QLabel(Form)
self.label_4.setGeometry(QtCore.QRect(110, 260, 71, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.btnClear = QtWidgets.QPushButton(Form)
self.btnClear.setGeometry(QtCore.QRect(560, 120, 93, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.btnClear.setFont(font)
self.btnClear.setObjectName("btnClear")
self.label1 = QtWidgets.QLabel(Form)
self.label1.setGeometry(QtCore.QRect(50, 50, 131, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.label1.setFont(font)
self.label1.setObjectName("label1")
self.lEditBirth = QtWidgets.QLineEdit(Form)
self.lEditBirth.setGeometry(QtCore.QRect(190, 261, 331, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.lEditBirth.setFont(font)
self.lEditBirth.setReadOnly(True)
self.lEditBirth.setObjectName("lEditBirth")
self.lEditRegion = QtWidgets.QLineEdit(Form)
self.lEditRegion.setGeometry(QtCore.QRect(190, 190, 331, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.lEditRegion.setFont(font)
self.lEditRegion.setReadOnly(True)
self.lEditRegion.setObjectName("lEditRegion")
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setGeometry(QtCore.QRect(110, 190, 61, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.lEditGender = QtWidgets.QLineEdit(Form)
self.lEditGender.setGeometry(QtCore.QRect(190, 330, 331, 31))
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(12)
self.lEditGender.setFont(font)
self.lEditGender.setReadOnly(True)
self.lEditGender.setObjectName("lEditGender")
self.lEditNum = QtWidgets.QLineEdit(Form)
self.lEditNum.setGeometry(QtCore.QRect(190, 50, 331, 31))
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(14)
self.lEditNum.setFont(font)
self.lEditNum.setReadOnly(False)
self.lEditNum.setObjectName("lEditNum")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "身份证验证", None, -1))
self.label_5.setText(QtWidgets.QApplication.translate("Form", "性别:", None, -1))
self.btnQuery.setText(QtWidgets.QApplication.translate("Form", "查询", None, -1))
self.label_2.setText(QtWidgets.QApplication.translate("Form", "查询结果:", None, -1))
self.label_4.setText(QtWidgets.QApplication.translate("Form", "生日:", None, -1))
self.btnClear.setText(QtWidgets.QApplication.translate("Form", "清除", None, -1))
self.label1.setText(QtWidgets.QApplication.translate("Form", "18位身份证:", None, -1))
self.label_3.setText(QtWidgets.QApplication.translate("Form", "地区:", None, -1))
效果如下图: