浅析身份证号码校验在大数据审计中的应用
在大数据审计中,无论是从被审计单位采集的业务数据,还是从外部单位采集的关联数据,只要涉及具体人员信息,身份证号码都作为主关键字和唯一识别码在数据分析中发挥重要作用。例如在困难群众救助补助资金审计中,通过身份证号码将财政供养人员、工商登记、养老保险、公积金等相关数据与低保特困人员进行关联可以筛选出将财政供养人员或高收入等不符合条件人员纳入低保特困户的疑点数据。在企业领导干部经责审计中,通过身份证号码将企业中层及以上领导干部名单与工商登记信息比对,可以筛选出领导干部兼职取酬的疑点数据。但在审计实践中,很多存储身份证号码的数据为手工录入,难免产生差错,同时随着近年来大数据审计在社保、乡村振兴、教育、医疗等行业的普及,被审计单位篡改业务数据中身份证号码逃避审计的现象时有发生。因此,对业务数据中的身份证号码进行校验显得尤为重要。
一、身份证号码的构成
根据《中华人民共和国国家标准GB11643-1999》中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。第1-6位数字为常住户口所在县(市、旗、区)的行政区划代码;第7-14位数字为出生日期;第15-17位数字为顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号;第17位数字奇数表示男性,偶数表示女性;第18位数字为校验码,通过对前17位数字本位码加权求和生成校验码。
二、身份证号码错误和异常情况
根据身份证号码编码规则,结合历年审计经验,可将被审计单位提供的电子数据中身份证号码存在的问题归纳为五种错误类型和一种异常情况。
五种错误类型分别为:一是位数既不是15位也不是18位;二是前6位行政区划代码不存在;三是出现非数字的代码(最后一位为“X”的除外);四是出生日期不是有效日期;五是最后一位校验码不符合规则。一种异常情况为身份证号码相同但姓名不同。
三、身份证号码校验步骤
第一步:清理身份证号码字段中的空格或非打印字符;
update 人员信息表 set 身份证号码=replace(身份证号码,' ','') where 1=1 --清除空格
update 人员信息表 set 身份证号码=replace(身份证号码,char(13),'') where 1=1 --清除回车符\r
update 人员信息表 set 身份证号码=replace(身份证号码,char(10),'') where 1=1 --清除换行符\n
update 人员信息表 set 身份证号码=replace(身份证号码,char(9),'') where 1=1 --清除制表符\t
第二步:将相关数据进行关联比对,筛选出身份证号码相同姓名不同的异常数据;
select *
into 人员信息异常表 --身份证号相同姓名不同
from [人员信息表1] a join [人员信息表2] b on a.身份证号码=b.身份证号码
where a.姓名<>b.姓名
第三步:根据错误类型数据特征编写身份证号码校验函数;
if exists(select * from sys.objects where name='CodeCheck' and type='FN') drop function CodeCheck
go --身份证号码校验
create function CodeCheck(@Code as varchar(20)) returns varchar(40)
as
begin
set @Code=LTRIM(RTRIM(@Code))
declare @CheckResult as varchar(40)=''
if @Code is null set @CheckResult='身份证号为空!'
else if LEN(@Code) not in(15,18) set @CheckResult='长度不是位或位!'
else if len(@Code)=15 and @Code like '%[^0-9]%' set @CheckResult='15位长度存在无效数字!'
else if len(@Code)=18 and (LEFT(@Code,17) like '%[^0-9]%' or right(@code,1) like '%[^0-9xX]%' ) set @CheckResult='18位长度存在无效数字或最后位不是xX!'
else if ISDATE(CASE WHEN LEN(@Code)=15 THEN '19'+SUBSTRING(@Code,7,6) ELSE SUBSTRING(@Code,7,8) END)=0 SET @CheckResult='出生年月日不符合日历!'
else if left(@Code,2) NOT IN ('11','12','13','14','15','21','22','23','31','32','33','34','35','36','37','41','42','43','44','45','46','47',
'50','51','52','53','54','61','62','63','64','65','71','81', '82') set @CheckResult='行政区划代码不存在!'
else if(len(@code)=18)
begin
declare @k int, @m varchar(5)
set @k=(convert(int,left(@code,1))*7+convert(int,substring(@code,2,1))*9+convert(int,substring(@code,3,1))*10+convert(int,substring(@code,4,1))*5+convert(int,substring(@code,5,1))*8+convert(int,substring(@code,6,1))*4+convert(int,substring(@code,7,1))*2+convert(int,substring(@code,8,1))*1+convert(int,substring(@code,9,1))*6+convert(int,substring(@code,10,1))*3+convert(int,substring(@code,11,1))*7+convert(int,substring(@code,12,1))*9+convert(int,substring(@code,13,1))*10+convert(int,substring(@code,14,1))*5+convert(int,substring(@code,15,1))*8+convert(int,substring(@code,16,1))*4+ convert(int,substring(@code,17,1))*2)%11
set @m=case when @k=0 then '1' when @k=1then '0' when @k=2then 'X'when @k=3then '9' when @k=4then '8' when @k=5 then '7' when @k=6 then '6' when @k=7then '5' when @k=8then '4' when @k=9then '3' when @k=10 then '2' end
if Upper(right(@code,1))=@m set @CheckResult='正确'
else set @CheckResult='校验错误,最后一位应为'+@m+'!'
end
else set @CheckResult='正确'
return @CheckResult
end
GO
第四步:筛选出身份证号号码错误的数据。
select *,校验结果=dbo.CodeCheck(身份证号码)
into [人员信息-身份证号错误]
from 人员信息表
where dbo.CodeCheck(身份证号码)<>'正确'
四、结果展示
五、结束语
通过编写sql脚本创建身份证号码校验函数的方法简单高效,可实现创建一次永久使用,具有较强的推广性。采用此方法既可以在数据采集整理阶段验证数据质量,便于将校验错误的数据及时反馈至被审计单位进行改正提升数据质量,也可以在数据分析阶段作为疑点数据下发现场进行核实,重点关注其错误的原因,如果是被审计单位为了逃避审计故意修改,则背后可能隐藏问题。
作 者:电子数据审计处 付晓芳
上一篇: 实践中,审计报告撰写在哪些方面亟需改进
下一篇: 浙江:做加法 促整改