123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- #
- # 读卡器读取身份证信息
- # 调用Dll
- # author: Scott Chen
- # date: 2019-12-13
- import ctypes
- import codecs
- from log_ware import LogWare
- logger = LogWare().get_logger()
- # 自定义异常
- class ReaderIdCardError:
- pass
- class IdCardReader:
- def __init__(self, dll_lib="apps/lib/dll/termb.dll", id_card_path="wz.txt"):
- # 要调用的动态链接库位置
- self.__dll_lib_local = dll_lib
- # 身份证信息保存文件路径,当前项目目录下
- self.__id_card_info_path = id_card_path
- # 调用公安部统一动态识别库
- self.__dll = ctypes.windll.LoadLibrary(self.__dll_lib_local)
- self.__id_car_info = self.__id_car_info_build()
- self.__sex_dict = self.__sex_dict_build()
- self.__nation_dict = self.__nation_dict_build()
- def recognize(self):
- t1 = self.__init_machine()
- if t1 is False:
- self.__id_car_info['error'] = '[10001]打开设备失败'
- return self.__id_car_info
- t2 = self.__authc()
- if t2 is False:
- self.__id_car_info['error'] = '[10002]未放卡或卡片放置不正确,身份证认证失败'
- return self.__id_car_info
- t3 = self.__read()
- if t3 is False:
- self.__id_car_info['error'] = '[10003]读卡发生错误'
- return self.__id_car_info
- return self.__id_car_info
- def __init_machine(self):
- # 初始化读卡器
- connPort = self.__dll.InitCommExt()
- if connPort == 0:
- logger.debug("查找并打开设备端口失败")
- self.__close()
- return False
- else:
- logger.debug("设备连接在%s", connPort)
- return True
- def __authc(self):
- # 读卡器身份证认证
- is_authc = self.__dll.Authenticate()
- if is_authc == 1:
- logger.debug("设备认证%s", is_authc)
- return True
- else:
- self.__error_print("未放卡或卡片放置不正确,身份证认证失败")
- self.__close()
- return False
- def __read(self):
- # 1 读基本信息,形成文字信息文件wz.txt、相片文件xp.wlt、zp.bmp,如果有指纹信息形成指纹信息文件fp.dat
- # 2 只读文字信息,形成文字信息文件wz.txt和相片文件xp.wlt
- # 3 读最新住址信息,形成最新住址文件newadd.txt
- read_result = self.__dll.Read_Content(2)
- if read_result != 1:
- self.__error_print("读卡发生错误")
- return False
- else:
- self.__read_id_card()
- logger.debug("身份证信息:%s", str(self.__id_car_info))
- self.__close()
- return True
- ####################################################################################################
- def __id_car_info_build(self):
- return {
- 'name': '',
- 'sex': '',
- 'nation': '',
- 'born_date': '',
- 'address': '',
- 'id_no': '',
- 'sign_gov': '',
- 'start_date': '',
- 'end_date': ''
- }
- def __sex_dict_build(self):
- return {
- '1': '男',
- '2': '女',
- }
- def __nation_dict_build(self):
- return {
- '01': '汉', '02': '汉', '03': '回', '04': '藏', '05': '维吾尔', '06': '苗',
- '07': '彝', '08': '壮', '09': '布依', '10': '朝鲜', '11': '满', '12': '侗',
- '13': '瑶', '14': '白', '15': '土家', '16': '哈尼', '17': '哈萨克', '18': '傣',
- '19': '黎', '20': '傈僳', '21': '佤', '22': '畲', '23': '高山', '24': '拉祜',
- '25': '水', '26': '东乡', '27': '纳西', '28': '景颇', '29': '柯尔克孜', '30': '土',
- '31': '达斡尔', '32': '仫佬', '33': '羌', '34': '布朗', '35': '撒拉', '36': '毛南',
- '37': '仡佬', '38': '锡伯', '39': '阿昌', '40': '普米', '41': '塔吉克', '42': '怒',
- '43': '乌孜别克', '44': '俄罗斯', '45': '鄂温克', '46': '德昂', '47': '保安', '48': '裕固',
- '49': '京', '50': '塔塔尔', '51': '独龙', '52': '鄂伦春', '53': '赫哲', '54': '门巴',
- '55': '珞巴', '56': '珞巴'
- }
- # 解码读取文件内容后的信息,共128个字符
- # "总钻风 10119800918广东省深圳市南山区前海路1080号海之景A座102 440305198009183074深圳市公安局南山分局 2014120520341205 "
- # 位置关系
- # 1-15 姓名
- # 16 性别
- # 17-18 民族
- # 19-26 出生
- # 27-61 住址
- # 62-79 身份证号
- # 80-94 签发机关
- # 95-102 有效期起始日期
- # 103-128 有效期截止日期
- # 读取文件信息
- def __read_id_card(self):
- try:
- with codecs.open(self.__id_card_info_path, 'r', 'utf-16-le') as f:
- content = f.read()
- info_map = self.__format(content)
- if (info_map is None):
- logger.debug("格式化身份信息文件内容出异常")
- logger.debug("身体份证信息读取成功")
- except Exception as e:
- info = "Error when read id card info from txt file."
- logger.debug("%s, error: %s", info, e)
- raise ReaderIdCardError(info)
- def __format(self, content):
- if (content is None):
- logger.debug("不能获取身份证信息,文件内容为空")
- return None
- if (len(content) != 128):
- logger.debug("文件内容解码错误,文本长度异常")
- return None
- self.__id_car_info['name'] = content[0:14].strip()
- self.__id_car_info['sex'] = self.__sex_dict[content[15]]
- # 数字要往后多取一位
- self.__id_car_info['nation'] = self.__nation_dict[content[16:18]]
- self.__id_car_info['born_date'] = content[18:26]
- self.__id_car_info['address'] = content[26:61].strip()
- self.__id_car_info['id_no'] = content[61:79]
- self.__id_car_info['sign_gov'] = content[79:93].strip()
- self.__id_car_info['start_date'] = content[93:102]
- self.__id_car_info['end_date'] = content[102:128].strip()
- return self.__id_car_info
- def __error_print(self, txt):
- logger.debug("%s,发生错误,请重新放置卡片", txt)
- def __close(self):
- if (self.__dll.CloseComm() == 1):
- logger.debug("读卡器关闭")
- else:
- logger.debug("读卡器关闭失败")
- # 单元测试
- if __name__ == '__main__':
- id_card_reader = IdCardReader()
- id_card_reader.recognize()
|