资讯详情

资讯详情

访客系统源码实战:身份证识别登记全流程解析

简介这套访客系统源码聚焦“身份证识别登记”场景适合需要搭建访客管理系统的开发人员、安防集成商或园区物业技术团队。它以身份证件信息作为识别入口替代手工抄登能提升访客登记效率与核验准确性可应用于办公楼、小区、政务大厅等需要出入登记的场所。资源压缩包约37.58MB未公布文件总数与具体类型解压后可查看完整工程源码及资源文件有一定Java/C#等开发经验者更易上手。源码围绕身份信息采集、登记记录、出入授权等基础功能展开涵盖身份证识别结果处理逻辑、数据持久化方案以及前端交互界面开发者可对照理解各模块的调用关系也可按业务需求调整界面风格、增加黑名单校验或对接第三方平台同时需自备身份证读写设备或识别SDK。目前已有611人学习/浏览该资源可参考其中身份证识别、数据存储与界面交互的实现思路快速开展二次开发或功能定制。1. 访客系统源码到底在解决什么事身份证识别登记不是拍照存图访客系统源码里身份证识别登记看起来是件小事——来访的人掏出身份证机器读一下名字和证件号跳出来再补个手机号就能进门。但真去落地你会发现“读一下”后面全是问题用读卡器直读芯片还是摄像头拍照OCR识别识别出来的身份证号要不要校验黑名单怎么拦数据往哪存这正是这个源码方向最有价值的地方它把身份证识别从一个动作变成了一套可校验、可追溯、能联动的登记流程而不是拍张照片存个档。适合谁做毕设课设的在校生、要给园区写字楼搭访客管理的小团队、以及想帮门卫换掉纸质登记本的一线运维。这篇按选型、实现、部署、踩坑、进阶往下拆读完你能自己跑出一版能用的访客系统。2. 身份证识别选型与工程结构先定硬件再写代码访客系统的第一个岔路口不在代码在硬件的选择。身份证识别当前就两条技术路线选错了后面所有代码都要返工。这章先把路线选型讲透再定工程结构这是我看过很多翻车案例之后总结出来的顺序。2.1 身份证识别选型读卡器直读和OCR拍照识别先分清再动手第一条路线是身份证读卡器正式名叫二代证阅读器。它内置SAM模块访客把身份证平放在设备上读卡器直接读取芯片里的姓名、身份证号、住址、证件照。准确率百分之百速度快大约三四百毫秒出结果。代价是要买硬件一台主流型号几百元SDK基本只提供Windows版本的DLL在Linux服务器上调用不了必须配一台Windows前台机。另一个限制是读卡器只认芯片如果访客拿的是复印件、手机翻拍照或者证件芯片本身损坏它什么都读不出来。第二条路线是OCR拍照识别。USB摄像头或高拍仪给身份证拍张照再用OCR引擎把文字信息抽出来。开源的PaddleOCR、云端的百度OCR都可以。优点是硬件成本低设备灵活缺点是识别准确率到不了100%身份证号、姓名这类关键字段偶尔会错而且它只认图片上的字不能验证这张证是不是原件。访客系统源码里一般建议两条路都留读卡器为主OCR兜底。比如访客没带实体证但有手机里的证件照片门卫拍一下也能登记系统日志里标记“OCR路线”就行。访客量小一天几十人可以只上OCR访客量大就一定选读卡器。我的经验是不要指望门卫去核对屏幕上的识别结果识别错了他们看不出来系统必须用校验位自动卡住明显错误。源码里最好把读卡器和OCR封装成同一个返回结构比如都返回IdCardInfo对象下面的业务逻辑不判断数据来源这样换设备、换识别引擎时只改对接层不动登记流程。很多从网上下载的访客系统源码把OCR写死在业务代码里这是最让人头疼的改法。2.2 基于Spring Boot Vue的工程结构源码跑起来前先定这些事访客系统的技术栈常见做法是Java Spring Boot做后端、Vue做前端、MySQL存数据。理由很实在Java在课设和企业小系统里生态最熟遇到问题能找到的参考最多读卡器SDK对接正好用JNA调用DLLJava做这个很顺。用Python Flask不是不行但对接读卡器和部署Windows服务这两个环节坑会比Java多不少建议别拿复杂场景去试。工程结构我一般拆成三块device-agentWindows前台机上跑的独立Java程序负责和读卡器DLL交互。读卡器DLL没法跨平台所以它必须单独部署在门卫那台Windows机器上。读到的身份证信息封装成JSON用HTTP POST发给后端。serverSpring Boot后端提供访客登记、查询、黑名单、离场确认接口数据全部落MySQL。webVue 3 Element Plus操作页面面向门卫功能要少而清晰——刷证自动填充、补手机号和被访人、显示黑名单拦截原因、历史记录查询。三块之间的调用链是device-agent读到身份证POST JSON给serverserver做校验、黑名单判断、建档、写来访记录最后前端页面拿到结果展示。这个结构的好处是读卡器只和device-agent有关系换读卡器品牌只改agent那一个模块server和web完全不用动。反过来如果前端页面直接去调读卡器DLL那台机器既要装浏览器又要装硬件驱动出问题之后很难排查到底是页面代码的锅还是驱动的锅。Maven工程按三个module组织父pom里放依赖版本管理子模块之间靠Spring的HTTP接口通信不搞RPC。device-agent独立打包成jar门卫机装一个JDK17就能跑。两个进程之间加一个简单的Token鉴权device-agent每次POST时带一个固定的AccessKeyserver端用拦截器校验。访客系统的安全级别不需要上OAuth2那套太重了一个请求头里的校验字段足够防止内网里的误调用。3. 身份证识别登记的核心实现建表、识别接口与登记流程这一章直接给可用的代码结构。三个小节分别解决三件事数据往哪放、识别结果怎么进系统、登记时做了哪些校验。代码按我前面说的Spring Boot结构组织你可以对照着自己的源码改。3.1 数据库三张表访客、来访记录、黑名单的建表SQL与索引设计访客系统核心数据就是三块谁来过、什么时候来的、下次还能不能进。我一般建三张表业务复杂以后再加预约表最小可用版本三张足够。最重要的设计决策是把身份证号当成业务主键来用而不是只看自增ID。CREATE DATABASE visitor_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE visitor ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL COMMENT 姓名, id_card_no CHAR(18) NOT NULL COMMENT 身份证号统一转大写, phone VARCHAR(20) DEFAULT COMMENT 手机号首次登记时人工补录, address VARCHAR(255) DEFAULT COMMENT 住址来自证件, photo_hash CHAR(32) DEFAULT COMMENT 证件照片的MD5用于查重, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_id_card (id_card_no) ) ENGINEInnoDB COMMENT访客基础档案表; CREATE TABLE visit_record ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, visitor_id BIGINT UNSIGNED NOT NULL, employee_id BIGINT UNSIGNED DEFAULT 0 COMMENT 被访人ID0表示未指定, reason VARCHAR(200) DEFAULT COMMENT 来访事由, come_time DATETIME NOT NULL, leave_time DATETIME DEFAULT NULL COMMENT 离开时间离场时更新, status TINYINT NOT NULL DEFAULT 0 COMMENT 0登记未入场 1在园 2已离场, KEY idx_visitor_time (visitor_id, come_time), KEY idx_status (status) ) ENGINEInnoDB COMMENT来访记录表; CREATE TABLE blacklist ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id_card_no CHAR(18) NOT NULL, reason VARCHAR(255) DEFAULT COMMENT 拉黑原因, expire_at DATETIME DEFAULT NULL COMMENT 到期时间NULL为永久, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_id_card (id_card_no) ) ENGINEInnoDB COMMENT黑名单表;关于设计里的几个关键点id_card_no用CHAR(18)定长身份证号是固定长度的文本用定长类型避免存储碎片。所有写入和查询都统一转大写身份证号末位校验码有可能是X如果不统一大小写同一个人的证件号可能存储成两条记录黑名单就拦不住。visitor表对id_card_no建唯一索引这是后面去重和防重复登记的基础没有这个索引并发请求一来就出重复档案。visit_record用visitor_id和come_time做复合索引因为门卫查“这人在什么时间段进来过”是最频繁的操作。字符集用utf8mb4而不是utf8姓名里有生僻字比如“王䶮”utf8的3字节编码存不下来写进去直接变问号。3.2 识别接口实现DeviceAgent调用读卡器后端用Service收口device-agent的职责是把读卡器SDK读到的结果转成JSON再传给后端。读卡器SDK拿到的字符串是GBK编码不做编码转换就会在Linux后端里变成乱码。下面是一段用JNA调用读卡器DLL的示例DLL名称和函数名以你手上的开发包为准。// DeviceAgent 里用 JNA 调用读卡器 DLL 的示例 public class IdCardReaderAgent { // 以某款读卡器 DLL 为例导出函数名为 ReadCard public interface IdCardDll extends Library { IdCardDll INSTANCE Native.load(idcard, IdCardDll.class); int ReadCard(int cmd, byte[] name, byte[] idNo, byte[] address); } public MapString, String read() throws Exception { byte[] name new byte[64]; byte[] idNo new byte[36]; byte[] address new byte[128]; int result IdCardDll.INSTANCE.ReadCard(0, name, idNo, address); if (result ! 1) { throw new RuntimeException(读卡失败请检查身份证是否放平); } // 读卡器返回的字符串是 GBK 编码需要显式转成 UTF-8 String realName new String(name, GBK).trim(); String idCard new String(idNo, GBK).trim().toUpperCase(); String addr new String(address, GBK).trim(); return Map.of(name, realName, idCardNo, idCard, address, addr); } }这段代码用JNA把DLL里的导出函数映射成Java接口方法Native.load会按类路径下的idcard.dll去加载。name、idNo、address是byte数组由DLL往里面写字节所以要先分配好固定大小。GBK转UTF-8那步不能省读卡器SDK普遍按Windows本地字符集返回而Linux后端和MySQL都是UTF-8不转的话姓名和住址字段进库就是乱码。toUpperCase()是为了统一身份证号里的X大写这步防止了后面查重时大小写对不上。server端用一个Controller收口。device-agent读到身份证后POST一个JSON过来后端只认这个JSON结构不关心数据是读卡器拿到的还是OCR识别的。这样做的收益是后端不需要引入任何硬件SDK依赖纯净的业务代码。RestController RequestMapping(/api/visitor) public class VisitorController { PostMapping(/detect) public Result detect(RequestBody IdCardInfo info) { // 读卡器和 OCR 拿到的数据都统一走这个入口 return visitorService.register(info); } }这里IdCardInfo就是一个简单的DTO包含name、idCardNo、address、photoBase64、sourceType五个字段sourceType标记是READER还是OCR。业务逻辑只面向这个对象识别方式的变化被完全隔离在device-agent和OCR服务里。以后要是把本地OCR换成云识别或者把读卡器换成新款register方法一行都不用改。3.3 登记逻辑身份证号校验、自动填充与黑名单拦截的完整代码登记逻辑是整个系统的核心我按顺序拆成四步校验身份证号合法性查黑名单查访客档案决定建档还是更新最后生成一条来访记录。第一步的身份证号校验尤其重要它能拦下一大批OCR误识别。public class IdCardValidator { // 身份证前17位的加权因子 private static final int[] WEIGHT {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 余数对应的校验码 private static final char[] CHECK_CODE {1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2}; public static boolean isValid(String idCard) { if (idCard null || !idCard.matches(^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dX]$)) { return false; } int sum 0; for (int i 0; i 17; i) { sum (idCard.charAt(i) - 0) * WEIGHT[i]; } return CHECK_CODE[sum % 11] idCard.charAt(17); } }正则负责过滤格式前6位地区码、出生日期、顺序码和校验位18或19或20开头的年份日期范围也做了基本限制。加权因子算法负责验证最后一位校验码是否合法这一层能拦住绝大多数把X识别成0、把1识别成l的OCR错误。注意charAt(17)取到的是原字符串的末位字符如果OCR是把X识别成小写x这里会直接不通过所以device-agent里统一toUpperCase是前置条件。然后是register方法本体。这一步里黑名单判断要放在建档之前不然被拦截的访客也会留下档案记录。Service public class VisitorService { Transactional public Result register(IdCardInfo info) { // 1 身份证号合法性校验 if (!IdCardValidator.isValid(info.getIdCardNo())) { return Result.fail(身份证号校验不通过请在页面人工核对); } // 2 黑名单校验只查未过期的记录 if (blacklistMapper.countActiveByIdCard(info.getIdCardNo()) 0) { return Result.fail(该证件在访客黑名单中请联系安保处); } // 3 查档案第一次来插入再来就复用 Visitor visitor visitorMapper.selectByIdCard(info.getIdCardNo()); if (visitor null) { visitor new Visitor(); visitor.setName(info.getName()); visitor.setIdCardNo(info.getIdCardNo()); visitor.setAddress(info.getAddress()); visitor.setPhotoHash(md5(info.getPhotoBase64())); visitorMapper.insert(visitor); } // 4 生成一条来访记录状态为待入场 VisitRecord record new VisitRecord(); record.setVisitorId(visitor.getId()); record.setReason(info.getReason()); record.setComeTime(LocalDateTime.now()); record.setStatus(0); visitRecordMapper.insert(record); return Result.ok(visitor); } }这段逻辑里访客身份完全以身份证号为准。第一次来的访客自动建档姓名、住址、证件照片直接从识别结果里来第二次以后只新增visit_record不再重复插入visitor。黑名单的count查询条件必须是“未过期”也就是expire_at为空或者大于当前时间如果黑名单表里挂了一堆过期记录不带这个条件会误拦正常访客。注意先查后插在并发场景下不是原子操作。如果两台设备同时读到同一个身份证号可能都查到visitor为空然后都执行insert唯一索引会报Duplicate entry。解决方式有两种一是捕获DuplicateKeyException后重查一次再走更新分支二是把insert语句改成INSERT ... ON DUPLICATE KEY UPDATE。访客系统高峰期集中在早上和下班前这种并发真实存在不能靠“应该不会撞上”糊弄过去。4. 从本机联调到园区上线部署步骤与Nginx参数源码跑通和现场能用是两回事。这一章先讲本机最小闭环怎么跑再讲真实施工时的分层部署和几个关键参数。踩过的坑集中在启动顺序和网络超时上我都会标注出来。4.1 本机跑通最小闭环读卡器、后端、前端的启动顺序与联调命令本机联调需要准备这些Windows 10机器一台装好读卡器厂商驱动USB口插上硬件JDK 17和Maven 3.8Node.js 16以上MySQL 8.0新建visitor_system库并导入建表SQL从读卡器开发包里把idcard.dll复制到device-agent的resources目录下。整体准备时间大约半小时卡壳基本都在读卡器驱动上。启动顺序有讲究后端要等数据库就绪前端要等后端接口起来device-agent要等服务器地址配置好再拉起来。顺序反了会出现端口没监听导致的前端白屏排查起来费时间。# 1 导入数据库表结构 mysql -uroot -p visitor_system schema.sql # 2 启动后端服务默认端口 8080 mvn spring-boot:run -pl server -Dserver.port8080 # 3 启动前端开发服务端口 5173 cd web npm install npm run dev # 4 启动读卡器代理 java -jar device-agent.jar联调时按三步验证。第一步看device-agent控制台刷证后应打印出姓名、证件号、地址的JSON第二步直接POST到后端接口验证黑名单拦截和身份证校验逻辑第三步在前端页面确认自动填充后的信息能正常提交。如果第二步就报错不要急着查前端先用curl或Postman定位是后端的问题还是网络的问题。我个人习惯先验证接口再碰页面前端报错信息往往会把人引到错误的方向。4.2 部署到园区Windows前台机 Linux服务器的分层架构与Nginx参数真实园区里部署和本机联调差别很大。常见拓扑是门卫室一台Windows小主机带读卡器和摄像头机房一台Linux服务器放后端和数据库。因为读卡器DLL只能在Windows调用device-agent必须留在前台机上业务服务和数据库放Linux机器前端页面也部署到Linux服务器通过Nginx托管。门卫只需要打开浏览器访问一个网址不需要每台前台机都装一套前端。Nginx配置里有两个参数必须调不调现场必出问题。第一是client_max_body_size访客登记页面要上传证件照片和现场照一张照片2到5MBNginx默认只允许1MB的请求体不调大前端一传图就返回413。第二是proxy_read_timeout识别接口不像普通查询那样秒回读卡器等待访客把证件放好有一个交互过程前端两秒没等到响应就报超时门卫会以为系统坏了。server { listen 443 ssl; server_name visit.example.com; # 前端静态文件 root /data/visitor-web/dist; index index.html; # 后端 API 反向代理 location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 身份证照片最大 10MB client_max_body_size 10m; # 识别接口等待放证耗时较长给足 30 秒 proxy_read_timeout 30s; proxy_connect_timeout 5s; proxy_send_timeout 30s; } }client_max_body_size设成10m是因为高拍仪或手机上传的证件照片原图经常超过2MB1MB默认值在正式环境撑不住。proxy_read_timeout设30s是因为读卡器等待和人工配合的过程耗时长接口本身计算只要几百毫秒但访客放证可能花两三秒加上网络传输超时设短了会在高峰期误报。这个30s不是拍脑袋是观察实际访客操作节奏后定的。后端这边application.yml里数据源参数同样不能照搬默认值。访客系统平时并发不高但上下班高峰和大型活动入场时会有几百人排队刷证连接池太小就会把请求堵在数据库连接上。server: port: 8080 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/visitor_system?characterEncodingutf8mb4useSSLfalseserverTimezoneAsia/Shanghai hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 5000连接池最大20、最小5这个配置对访客系统足够。MySQL连接数和内存是成正比的开太大不会提高性能反而把服务器内存吃光。connection-timeout设5秒超过就快速失败让前端页面向门卫提示“系统繁忙请重试”而不是让请求无限期挂在后台。我说一下判断依据一台2核4G的云服务器后端Tomcat 200线程MySQL连接池20实测能扛住几百人集中刷证入场瓶颈从来不在数据库连接数。提示如果现场网络环境较差比如门卫室到机房要走Wi-Fi建议device-agent和server之间改走内网有线。无线网络丢包会导致刷证后界面偶发转圈这个问题排查起来极其费劲因为它不是必现的。5. 访客系统身份证识别登记的5个高频坑这一章把我在访客系统上踩过的坑按“现象→原因→解决”写清楚每条都是真实发生过、需要花时间排查的问题。提前看完能省掉一半的调试时间。5.1 读卡器识别不到身份证驱动冲突和串口号配置现象读卡器指示灯亮但device-agent控制台始终提示“读卡失败请重试”换了好几张证件都一样。原因这类设备常见的是USB转串口方案插上以后系统里出现一个COM口。如果同时插过两台读卡器或者之前装过别的品牌驱动COM口号会漂移。SDK默认读COM1但实际设备在COM4两边对不上自然读不到。解决到Windows设备管理器里找“端口(COM和LPT)”节点确认读卡器实际分配到的COM口号然后改配置文件指定端口不要依赖SDK默认值。device: reader: com-port: COM4 baud-rate: 115200另外读卡器优先插主机后置USB口。前置USB口的供电不稳读卡器会间歇性掉线这个属于玄学但发生频率不低。如果换了个USB口COM号可能又变了所以配置里把这个参数独立出来现场调试时只改这里不用动代码。5.2 OCR把身份证号识别成0和X的字符混淆现象摄像头拍照识别时身份证号末位是X被识别成数字0号码里的字母O也被识别成0姓名里的生僻字“佀”被识别成“侣”。原因OCR引擎对同字号相似字形分得不够细。身份证号码里的X、0、O这几个字在小字体下肉眼都容易混机器更不例外。这不是换一个OCR引擎能彻底解决的属于领域固有误差。解决三条措施一起上。第一服务端用IdCardValidator做校验码验证校验不过直接拒绝登记第二校验不通过时前端弹一个人工确认框把证件原图放大让门卫比对第三对姓名这类自由文本字段识别结果后面带相似字候选列表门卫勾选一次就记住下次识别到同样的字自动用上次的选择。第三个机制实现不复杂在系统词典表里存一条映射即可却能明显减少重复人工核对。5.3 访客表越积越多黑名单查不到人现象Visitor表已经几万条数据某天发现一个以前被黑名单拦截过的访客居然登记成功了放进了园区。原因visitor表建表时没给id_card_no加唯一索引同一个身份证号被插入了多行。黑名单拦截代码关联到的是最新一行visitor_id但黑名单核对用的却是另一行的ID两边错位拦截失效。这个问题的根源是数据模型没把身份证号当成业务主键而是依赖了自增ID。解决先补唯一索引再合并历史数据。合并规则保留created_at最早的一行作为主档案其余作废visit_record里的visitor_id统一迁移过去。这段SQL在数据量大的时候要在凌晨执行业务高峰期跑会锁表。ALTER TABLE visitor ADD UNIQUE KEY uk_id_card (id_card_no);改完之后所有按人维度的查询和判断都以身份证号为准自增ID只作为关联字段存在不再承担业务标识职责。5.4 登记高峰期接口超时现象早上9点园区门口排队门卫连刷十几张证前端页面出现“请求超时请重试”后面排队的人等得越来越烦躁。原因默认Tomcat最大线程数200正常情况下足够但每个识别请求都包含图片上传和数据库写入。如果前端不做压缩一张原图5MB直接传上来加上网络差一个请求就能占住一个线程十几秒线程池很快被打满后续请求只能排队等超时。解决前端把图片压缩后再传用canvas把证件图最长边缩到1280pxJPG质量0.85一张图压到200KB以内后端把图片存储改成异步先返回登记成功再慢慢落盘照片文件。识别本身只有几百毫秒瓶颈不在读卡在传输和IO。Tomcat线程数不需要无脑调大200够用主要靠压缩图片来释放线程。5.5 数据库里的身份证号变成问号乱码现象visitor表里的姓名字段显示“王?”身份证号正常只有姓名和住址变成问号前端页面显示也是这样。原因读卡器SDK返回的姓名字符串是GBK编码而数据库表是utf8mb4。device-agent里没做编码转换直接把GBK的字节当UTF-8传给后端。身份证号只有数字和X不受编码影响所以看起来“一半正常一半乱码”很容易被误判成数据库问题。解决在device-agent的read方法里name和address字段要按GBK解码一次再发送同时HTTP请求显式设置Content-Type为application/json;charsetutf-8。JNA那边用new String(bytes, GBK)即可注意按实际字符串长度截断否则会带一堆空白字符。这个坑在Windows中文系统下必踩因为Windows本地字符集默认就是GBKLinux服务器上纯UTF-8的代码反而不容易遇到。6. 进阶人脸比对做“人证合一”合规存储身份证号基础版访客系统能跑通以后有两个进阶方向价值最高人证合一和身份证号合规存储。人证合一解决的是“拿了别人的身份证也能进”的问题合规存储解决的是身份证号这类敏感信息怎么落地的问题。人脸比对的做法是登记时用摄像头拍一张现场照和读卡器读出来的证件照片做1:1比对。读卡器拿到的是标准证件照摄像头拍的是坐姿照两者曝光、角度都不同不能直接做像素对比实际方案是各自提取人脸特征向量再算余弦相似度阈值设在0.6左右。实现上用现成的人脸识别SDK比从零训练模型划算得多识别耗时在200到500毫秒之间不会拖慢登记流程。身份证号属于敏感个人信息不能明文落库。常见做法是AES-GCM加密存储查询时按需解密页面显示只露出前6位和后4位。加密粒度按字段做不要把整张表加密否则按身份证号查重的索引会失效。密钥独立配置在环境变量里不要写在源码或配置文件里。// AES-GCM 加密身份证号再落库字段类型改为 VARCHAR(255) String encrypted aesGcm.encrypt(idCardNo); // 页面显示脱敏110***********1234 String mask idCardNo.replaceAll(^(\\d{6})\\d{8}(\\d{4})$, $1********$2);加密后visitor表的id_card_no字段不能再做唯一索引查重逻辑改成先对身份证号做哈希用哈希值建唯一索引。哈希值不可逆又能保证同一个身份证号对应同一个索引值查重和联动的需求都保住了。脱敏正则里的分组写法是固定套路前6位后4位这个规则要跟门卫确认过再落地有些场景要求显示后6位需要在合规要求和实际核验便利之间取舍。我做了几套访客系统之后养成的习惯是先定硬件、确认SDK能力再写建表SQL。读卡器的COM口号、DLL的编码方式、OCR的误识别率这些硬件层的限制决定了代码怎么写顺序反了就是返工。身份证识别登记这个方向不难但细节都在这些别人不太会写进源码笔记的地方。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →