SqlServer2000+ 身份证合法校验函数的示例代码

时间:2021-10-27 00:47:09

下面看下sqlserver2000身份证校验的代码,具体代码如下所示:

?
1
2
3
4
5
6
7
8
9
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
身份校验行数
*/
if exists(select * from sysobjects where name='fun_utils_idnumberoprater' and type='FN')
    drop function fun_utils_idnumberoprater
go
create function fun_utils_idnumberoprater
(
@idnumber varchar(50)=''
)
returns varchar(500)
as
/*
公民身份号码是由17位数字码和1位校验码组成。排列顺序从左至右分别为:6位地址码,8位出生日期码,3位顺序码和1位校验码。
地址码(身份证地址码对照表见下面附录)和出生日期码很好理解,顺序码表示在同一地址码所标识的区域范围内,对同年同月同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
身份证最后一位校验码算法如下:
1. 将身份证号码前17位数分别乘以不同的系数,从第1位到第17位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
2. 将得到的17个乘积相加。
3. 将相加后的和除以11并得到余数。
4. 余数可能为0 1 2 3 4 5 6 7 8 9 10这些个数字,其对应的身份证最后一位校验码为1 0 X 9 8 7 6 5 4 3 2。
function
    1.校验身份证有效性
    2.15位身份证转18位
*/
begin
 
    declare @ReturnText varchar(1000) --返回值
            ,@Separator varchar(1) --分隔符
            
            ,@idnumberElement varchar(1) --身份证每位元素
            ,@CurrentIndex int --身份证号当前索引位
            ,@NextIndex int --身份证号下一个索引位
            
            ,@xsnumber varchar(50) --系数
            ,@xsElement varchar(2) --系数每位元素
            ,@xsCurrentIndex int --系数当前索引位
            ,@xsNextIndex int --系数下一个索引位
            
            ,@jym varchar(11) --校验码
            ,@sum int --身份证元素*系数求和
            ,@div int --合计对11求余数
            
            ,@CurrentJym varchar(1) --当前校验码
            ,@CurrentWs int --当前身份证位数
            ,@NewJym varchar(1000) --新校验码
            ,@NewWs int --新身份证位数
            ,@oldId varchar(20)
 
    --处理身份证号并校验位数有效性
    set @Separator =',';
    set @CurrentIndex = 1;
    set @xsnumber = '7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2';
    set @xsCurrentIndex = 1;
    set @jym = '10X98765432';
    set @sum = 0;
    set @CurrentWs = 0;
    set @CurrentJym = '';
    set @NewJym = '';
    set @NewWs = 0;
    set @CurrentWs=len(@idnumber);
    set @oldId = @idnumber;
    
    
    if @CurrentWs=15
    begin
        set @idnumber=stuff(@idnumber,7,0,case when substring(@idnumber,13,3) in ('999','998','997','996') then '18' else '19' end);
        
        SET @CurrentJym = '';
    end
    else if @CurrentWs>=18
    begin
        set @CurrentJym=substring(@idnumber,18,1);
        set @idnumber=substring(@idnumber,1,17);
    end
    else
    begin
        set @ReturnText='校验失败_'
        goto TheEnd;
    end
    if isdate(substring(@idnumber,7,8))=0
    begin
        set @ReturnText='校验失败_'
        goto TheEnd;
    end
    --计算身份证校验位
    while(@CurrentIndex<=len(@idnumber))
    begin
     set @NextIndex=@CurrentIndex+1;
        set @xsNextIndex=charindex(@Separator,@xsnumber,@xsCurrentIndex);
        
        if(@xsNextIndex=0 OR @xsNextIndex IS NULL)
            set @xsNextIndex=len(@xsnumber)+1;
        
        set @idnumberElement=substring(@idnumber,@CurrentIndex,@NextIndex-@CurrentIndex);
        set @xsElement=substring(@xsnumber,@xsCurrentIndex,@xsNextIndex-@xsCurrentIndex);
        
        if ISNUMERIC(@idnumberElement) > 0
            set @sum=@sum+cast(@idnumberElement as int)*cast(@xsElement as int)
        else
            begin
                set @ReturnText='校验失败_';
                goto TheEnd
            end
 
    
        set @CurrentIndex=@CurrentIndex+1;
        set @xsCurrentIndex=@xsNextIndex+1;
        
    end
    set @div=@sum%11;
    set @NewJym=substring(@jym,@div+1,1);
    --校验身份证校验位是否出错
    if (@CurrentJym<>'') and (@NewJym<>@CurrentJym)
    begin
        set @ReturnText='校验失败_';
        goto TheEnd
    end
    --输出新的身份证号
    if len(@oldId) > 18
        set @ReturnText='校验通过,原始身份证长度非15位或18位_'+(@idnumber+@NewJym)
    else
        set @ReturnText='校验通过,原始身份证长度为'+cast(len(@oldId) as varchar)+'位_'+(@idnumber+@NewJym)
    goto TheEnd
 
TheEnd:
    return @ReturnText
end
go
 
-- ----------------------以下存储过程是遍历整个表,添加字段并修改校验------------------------
 
 
/*
* 一下存储过程是在原表的基础上,添加字段保存校验结果,需要替换掉表明和字段名
*/
-- 表名:a_idcard , 列 idcard 原身份证, card 标准(新添加),result校验结果(新添加)
 
-- 添加标准身份证字段
begin
begin
if not exists (select * from syscolumns where id=object_id('a_idcard') and name='card')
        alter table a_idcard add [card] varchar(20);
end
-- 添加校验结果字段
begin
if not exists (select * from syscolumns where id=object_id('a_idcard') and name='result')
alter table a_idcard add [result] nvarchar(20);
end
end
go
 
--遍历结果
BEGIN
declare @id_card varchar(100), @res varchar(200),@c_index int
declare cur cursor
 
for
    select idcard from a_idcard -- 这里需要替换
 
open cur
fetch next from cur into @id_card
while @@FETCH_STATUS = 0
begin
set @res = dbo.fun_utils_idnumberoprater(@id_card)
set @c_index = charindex('_',@res)
print substring(@res,0,@c_index)
print substring(@res, @c_index+1, len(@res))
 
-- 这里需要替换
update a_idcard set card=substring(@res, @c_index+1, len(@res)),result=substring(@res,0,@c_index)
where idcard=@id_card
 
fetch next from cur into @id_card
end
close cur
deallocate cur
end
go

PS:下面看下身份证合法性校验模板

?
1
2
3
4
5
6
7
8
9
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//这个可以验证15位和18位的身份证,并且包含生日和校验位的验证。
//如果有兴趣,还可以加上身份证所在地的验证,就是前6位有些数字合法有些数字不合法。
function isIdCardNo(num) {
  if(num.indexOf("x")!=-1){
   return false;
  }
 
 num = num.toUpperCase();
 //身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X。  
 if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))) {
  alert('输入的身份证号长度不对,或者号码不符合规定!\n15位号码应全为数字,18位号码末位可以为数字或X。');
  return false;
 }
 //校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
 //下面分别分析出生日期和校验位
 var len, re;
 len = num.length;
 if (len == 15) {
  re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);
  var arrSplit = num.match(re);
  //检查生日日期是否正确
  var dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]);
  var bGoodDay;
  bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2]))
     && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3]))
     && (dtmBirth.getDate() == Number(arrSplit[4]));
  if (!bGoodDay) {
   alert('输入的身份证号里出生日期不对!');
   return false;
  } else {
   //将15位身份证转成18位
   //校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。  
   var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
   var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
   var nTemp = 0, i;
   num = num.substr(0, 6) + '19' + num.substr(6, num.length - 6);
   for (i = 0; i < 17; i++) {
    nTemp += num.substr(i, 1) * arrInt[i];
   }
   num += arrCh[nTemp % 11];
   return num;
  }
 }
 if (len == 18) {
  re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);
  var arrSplit = num.match(re);
  //检查生日日期是否正确
  var dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4]);
  var bGoodDay;
  bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2]))
     && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3]))
     && (dtmBirth.getDate() == Number(arrSplit[4]));
  if (!bGoodDay) {
   alert(dtmBirth.getYear());
   alert(arrSplit[2]);
   alert('输入的身份证号里出生日期不对!');
   return false;
  } else {
   //检验18位身份证的校验码是否正确。
   //校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
   var valnum;
   var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
   var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
   var nTemp = 0, i;
   for (i = 0; i < 17; i++) {
    nTemp += num.substr(i, 1) * arrInt[i];
   }
   valnum = arrCh[nTemp % 11];
   if (valnum != num.substr(17, 1)) {
    alert('18位身份证的校验码不正确!应该为:' + valnum);
    return false;
   }
   return num;
  }
 }
 return false;
}

总结

到此这篇关于SqlServer2000+ 身份证合法校验函数的示例代码的文章就介绍到这了,更多相关sqlserver2000身份证校验内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/afgasdg/article/details/106257475