function
checkIdcard(idcard)
{
var area = { 11 : " 北京 " , 12 : " 天津 " , 13 : " 河北 " , 14 : " 山西 " , 15 : " 内蒙古 " , 21 : " 辽宁 " , 22 : " 吉林 " , 23 : " 黑龙江 " , 31 : " 上海 " , 32 : " 江苏 " , 33 : " 浙江 " , 34 : " 安徽 " , 35 : " 福建 " , 36 : " 江西 " , 37 : " 山东 " , 41 : " 河南 " , 42 : " 湖北 " , 43 : " 湖南 " , 44 : " 广东 " , 45 : " 广西 " , 46 : " 海南 " , 50 : " 重庆 " , 51 : " 四川 " , 52 : " 贵州 " , 53 : " 云南 " , 54 : " 西藏 " , 61 : " 陕西 " , 62 : " 甘肃 " , 63 : " 青海 " , 64 : " 宁夏 " , 65 : " 新疆 " , 71 : " 台湾 " , 81 : " 香港 " , 82 : " 澳门 " , 91 : " 国外 " }
var idcard,Y,JYM;
var S,M;
var idcard_array = new Array();
idcard_array = idcard.split( "" );
// 地区检验
if (area[parseInt(idcard.substr( 0 , 2 ))] == null ) return 4 ;
// 身份号码位数及格式检验
switch (idcard.length){
case 15 :
if ( (parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 4 == 0 || ((parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 100 == 0 && (parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 4 == 0 )){
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 }[ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ]))[ 0 - 9 ]{ 3 }$ / ; // 测试出生日期的合法性
} else {
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 }[ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | 1 [ 0 - 9 ] | 2 [ 0 - 8 ]))[ 0 - 9 ]{ 3 }$ / ; // 测试出生日期的合法性
}
if (ereg.test(idcard)) return 0 ;
else return 2 ;
break ;
case 18 :
// 18位身份号码检测
// 出生日期的合法性检查
// 闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))
// 平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))
if ( parseInt(idcard.substr( 6 , 4 )) % 4 == 0 || (parseInt(idcard.substr( 6 , 4 )) % 100 == 0 && parseInt(idcard.substr( 6 , 4 )) % 4 == 0 )){
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 } 19 [ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ]))[ 0 - 9 ]{ 3 }[ 0 - 9Xx]$ / ; // 闰年出生日期的合法性正则表达式
} else {
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 } 19 [ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | 1 [ 0 - 9 ] | 2 [ 0 - 8 ]))[ 0 - 9 ]{ 3 }[ 0 - 9Xx]$ / ; // 平年出生日期的合法性正则表达式
}
if (ereg.test(idcard)){ // 测试出生日期的合法性
// 计算校验位
S = (parseInt(idcard_array[ 0 ]) + parseInt(idcard_array[ 10 ])) * 7
+ (parseInt(idcard_array[ 1 ]) + parseInt(idcard_array[ 11 ])) * 9
+ (parseInt(idcard_array[ 2 ]) + parseInt(idcard_array[ 12 ])) * 10
+ (parseInt(idcard_array[ 3 ]) + parseInt(idcard_array[ 13 ])) * 5
+ (parseInt(idcard_array[ 4 ]) + parseInt(idcard_array[ 14 ])) * 8
+ (parseInt(idcard_array[ 5 ]) + parseInt(idcard_array[ 15 ])) * 4
+ (parseInt(idcard_array[ 6 ]) + parseInt(idcard_array[ 16 ])) * 2
+ parseInt(idcard_array[ 7 ]) * 1
+ parseInt(idcard_array[ 8 ]) * 6
+ parseInt(idcard_array[ 9 ]) * 3 ;
Y = S % 11 ;
if (idcard_array[ 17 ] == " x " )
{
idcard_array[ 17 ] = " X " ;
}
// alert(Y);
// M = "F";
JYM = " 10X98765432 " ;
M = JYM.substr(Y, 1 ); // 判断校验位
if (M == idcard_array[ 17 ] ) return 0 ; // 检测ID的校验位
else return 3 ;
}
else return 2 ;
break ;
default :
return 1 ;
break ;
}
}
{
var area = { 11 : " 北京 " , 12 : " 天津 " , 13 : " 河北 " , 14 : " 山西 " , 15 : " 内蒙古 " , 21 : " 辽宁 " , 22 : " 吉林 " , 23 : " 黑龙江 " , 31 : " 上海 " , 32 : " 江苏 " , 33 : " 浙江 " , 34 : " 安徽 " , 35 : " 福建 " , 36 : " 江西 " , 37 : " 山东 " , 41 : " 河南 " , 42 : " 湖北 " , 43 : " 湖南 " , 44 : " 广东 " , 45 : " 广西 " , 46 : " 海南 " , 50 : " 重庆 " , 51 : " 四川 " , 52 : " 贵州 " , 53 : " 云南 " , 54 : " 西藏 " , 61 : " 陕西 " , 62 : " 甘肃 " , 63 : " 青海 " , 64 : " 宁夏 " , 65 : " 新疆 " , 71 : " 台湾 " , 81 : " 香港 " , 82 : " 澳门 " , 91 : " 国外 " }
var idcard,Y,JYM;
var S,M;
var idcard_array = new Array();
idcard_array = idcard.split( "" );
// 地区检验
if (area[parseInt(idcard.substr( 0 , 2 ))] == null ) return 4 ;
// 身份号码位数及格式检验
switch (idcard.length){
case 15 :
if ( (parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 4 == 0 || ((parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 100 == 0 && (parseInt(idcard.substr( 6 , 2 )) + 1900 ) % 4 == 0 )){
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 }[ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ]))[ 0 - 9 ]{ 3 }$ / ; // 测试出生日期的合法性
} else {
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 }[ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | 1 [ 0 - 9 ] | 2 [ 0 - 8 ]))[ 0 - 9 ]{ 3 }$ / ; // 测试出生日期的合法性
}
if (ereg.test(idcard)) return 0 ;
else return 2 ;
break ;
case 18 :
// 18位身份号码检测
// 出生日期的合法性检查
// 闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))
// 平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))
if ( parseInt(idcard.substr( 6 , 4 )) % 4 == 0 || (parseInt(idcard.substr( 6 , 4 )) % 100 == 0 && parseInt(idcard.substr( 6 , 4 )) % 4 == 0 )){
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 } 19 [ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ]))[ 0 - 9 ]{ 3 }[ 0 - 9Xx]$ / ; // 闰年出生日期的合法性正则表达式
} else {
ereg =/^ [ 1 - 9 ][ 0 - 9 ]{ 5 } 19 [ 0 - 9 ]{ 2 }(( 01 | 03 | 05 | 07 | 08 | 10 | 12 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 3 [ 0 - 1 ]) | ( 04 | 06 | 09 | 11 )( 0 [ 1 - 9 ] | [ 1 - 2 ][ 0 - 9 ] | 30 ) | 02 ( 0 [ 1 - 9 ] | 1 [ 0 - 9 ] | 2 [ 0 - 8 ]))[ 0 - 9 ]{ 3 }[ 0 - 9Xx]$ / ; // 平年出生日期的合法性正则表达式
}
if (ereg.test(idcard)){ // 测试出生日期的合法性
// 计算校验位
S = (parseInt(idcard_array[ 0 ]) + parseInt(idcard_array[ 10 ])) * 7
+ (parseInt(idcard_array[ 1 ]) + parseInt(idcard_array[ 11 ])) * 9
+ (parseInt(idcard_array[ 2 ]) + parseInt(idcard_array[ 12 ])) * 10
+ (parseInt(idcard_array[ 3 ]) + parseInt(idcard_array[ 13 ])) * 5
+ (parseInt(idcard_array[ 4 ]) + parseInt(idcard_array[ 14 ])) * 8
+ (parseInt(idcard_array[ 5 ]) + parseInt(idcard_array[ 15 ])) * 4
+ (parseInt(idcard_array[ 6 ]) + parseInt(idcard_array[ 16 ])) * 2
+ parseInt(idcard_array[ 7 ]) * 1
+ parseInt(idcard_array[ 8 ]) * 6
+ parseInt(idcard_array[ 9 ]) * 3 ;
Y = S % 11 ;
if (idcard_array[ 17 ] == " x " )
{
idcard_array[ 17 ] = " X " ;
}
// alert(Y);
// M = "F";
JYM = " 10X98765432 " ;
M = JYM.substr(Y, 1 ); // 判断校验位
if (M == idcard_array[ 17 ] ) return 0 ; // 检测ID的校验位
else return 3 ;
}
else return 2 ;
break ;
default :
return 1 ;
break ;
}
}
2
var
Errors
=
new
Array(
" 验证通过! " ,
" 身份证号码位数不对! " ,
" 身份证号码出生日期超出范围或含有非法字符! " ,
" 身份证号码校验错误! " ,
" 身份证地区非法! "
);
var result = checkIdcard(IDCardNoValue);
if (result != 0 )
... {
//你的代码 here
}
" 验证通过! " ,
" 身份证号码位数不对! " ,
" 身份证号码出生日期超出范围或含有非法字符! " ,
" 身份证号码校验错误! " ,
" 身份证地区非法! "
);
var result = checkIdcard(IDCardNoValue);
if (result != 0 )
... {
//你的代码 here
}
3
'
'' -----------------------------------------------------------------------------
' '' <summary>
' '' 将15位的身份证号码升级到18位
' '' </summary>
' '' <param name="IDCard15">15位的身份证号码</param>
' '' <returns>18位的身份证号码</returns>
' '' <remarks>
' '' 根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
' '' 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码, 三位数字顺序码和一位数字校验码。
' '' 地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
' '' 生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
' '' 顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。
' '' 顺序码的奇数分给男性,偶数分给女性。
' '' 校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
' ''
' '' 注意:这里没有考虑1900年以及之前出生的人的情况
' ''
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function IDCard15to18( ByVal IDCard15 As String ) As String
Dim IDCard17 As String
' 将出生年扩展为4位,即在2位数的出生年前面加19 (这里没有考虑1900年以及之前出生的人的情况)
' IDCard18 = IDCard15.Substring(0, 6) + "19" + IDCard15.Substring(6)
IDCard17 = IDCard15.Insert( 6 , " 19 " )
' 计算校验码
Dim code As Char
code = GetCheckCode(IDCard17)
' 返回18位身份证号码
Return IDCard17 + code.ToString()
End Function
' '' -----------------------------------------------------------------------------
' '' <summary>
' '' 判断身份证号码的校验码是否正确
' '' </summary>
' '' <param name="IDCard18">18位身份证号码</param>
' '' <returns>true表示验证码正确,否则表示验证码错误</returns>
' '' <remarks>
' '' 注意:
' '' 此方法只是对验证码进行判断,不判断身份证号码其它部分的合法性.
' '' 比如出现666666198013320014这样的号码,显然是非法的身份证号码
' '' 666666的地区号目前是不存在的
' '' 1980年没有13月,也没有32日
' '' 但是它的校验码4却是正确的
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function ValidCheckcode( ByVal IDCard18 As String ) As Boolean
' 参数IDCard18中的校验码
Dim currentCode As Char
currentCode = IDCard18.Chars( 17 )
' 正确的验证码
Dim ValidCode As Char
ValidCode = GetCheckCode(IDCard18.Substring( 0 , 17 ))
Return ValidCode.Equals(currentCode)
End Function
' '' -----------------------------------------------------------------------------
' '' <summary>
' '' 根据身份证号码的前17位数字生成最后一位的校验码
' '' </summary>
' '' <param name="IDCard17">身份证号码的前17位数字</param>
' '' <returns>校验码(身份证号码的第18位)</returns>
' '' <remarks>
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function GetCheckCode( ByVal IDCard17 As String ) As Char
' 按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码
' 公式如下:
' ∑(ai×Wi)(mod 11)
' i----表示号码字符从右至左包括校验码在内的位置序号;
' ai----表示第i位置上的号码字符值;
' Wi----示第i位置上的加权因子,其数值依据公式Wi=2^(n-1)(mod 11)计算得出。
Dim num As Integer = 0
For i As Integer = 18 To 2 Step - 1
num += CInt (IDCard17.Substring( 18 - i, 1 )) * ( 2 ^ (i - 1 ) Mod 11 )
Next
num = num Mod 11
' 然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:
' ∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
' 校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
Dim checkcode As String
Select Case num
Case 0
checkcode = " 1 "
Case 1
checkcode = " 0 "
Case 2
' TODO: X是大写还是小写还未确定(刚好我的身份证的校验码是小写x,不知道大写X是否也可行)
checkcode = " x "
Case Else
checkcode = CStr ( 12 - num)
End Select
Return CChar (checkcode)
End Function
' '' <summary>
' '' 将15位的身份证号码升级到18位
' '' </summary>
' '' <param name="IDCard15">15位的身份证号码</param>
' '' <returns>18位的身份证号码</returns>
' '' <remarks>
' '' 根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
' '' 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码, 三位数字顺序码和一位数字校验码。
' '' 地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
' '' 生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
' '' 顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。
' '' 顺序码的奇数分给男性,偶数分给女性。
' '' 校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
' ''
' '' 注意:这里没有考虑1900年以及之前出生的人的情况
' ''
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function IDCard15to18( ByVal IDCard15 As String ) As String
Dim IDCard17 As String
' 将出生年扩展为4位,即在2位数的出生年前面加19 (这里没有考虑1900年以及之前出生的人的情况)
' IDCard18 = IDCard15.Substring(0, 6) + "19" + IDCard15.Substring(6)
IDCard17 = IDCard15.Insert( 6 , " 19 " )
' 计算校验码
Dim code As Char
code = GetCheckCode(IDCard17)
' 返回18位身份证号码
Return IDCard17 + code.ToString()
End Function
' '' -----------------------------------------------------------------------------
' '' <summary>
' '' 判断身份证号码的校验码是否正确
' '' </summary>
' '' <param name="IDCard18">18位身份证号码</param>
' '' <returns>true表示验证码正确,否则表示验证码错误</returns>
' '' <remarks>
' '' 注意:
' '' 此方法只是对验证码进行判断,不判断身份证号码其它部分的合法性.
' '' 比如出现666666198013320014这样的号码,显然是非法的身份证号码
' '' 666666的地区号目前是不存在的
' '' 1980年没有13月,也没有32日
' '' 但是它的校验码4却是正确的
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function ValidCheckcode( ByVal IDCard18 As String ) As Boolean
' 参数IDCard18中的校验码
Dim currentCode As Char
currentCode = IDCard18.Chars( 17 )
' 正确的验证码
Dim ValidCode As Char
ValidCode = GetCheckCode(IDCard18.Substring( 0 , 17 ))
Return ValidCode.Equals(currentCode)
End Function
' '' -----------------------------------------------------------------------------
' '' <summary>
' '' 根据身份证号码的前17位数字生成最后一位的校验码
' '' </summary>
' '' <param name="IDCard17">身份证号码的前17位数字</param>
' '' <returns>校验码(身份证号码的第18位)</returns>
' '' <remarks>
' '' </remarks>
' '' <history>
' '' [Hudan] 2005-8-8 Created
' '' </history>
' '' -----------------------------------------------------------------------------
Public Function GetCheckCode( ByVal IDCard17 As String ) As Char
' 按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码
' 公式如下:
' ∑(ai×Wi)(mod 11)
' i----表示号码字符从右至左包括校验码在内的位置序号;
' ai----表示第i位置上的号码字符值;
' Wi----示第i位置上的加权因子,其数值依据公式Wi=2^(n-1)(mod 11)计算得出。
Dim num As Integer = 0
For i As Integer = 18 To 2 Step - 1
num += CInt (IDCard17.Substring( 18 - i, 1 )) * ( 2 ^ (i - 1 ) Mod 11 )
Next
num = num Mod 11
' 然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:
' ∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
' 校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
Dim checkcode As String
Select Case num
Case 0
checkcode = " 1 "
Case 1
checkcode = " 0 "
Case 2
' TODO: X是大写还是小写还未确定(刚好我的身份证的校验码是小写x,不知道大写X是否也可行)
checkcode = " x "
Case Else
checkcode = CStr ( 12 - num)
End Select
Return CChar (checkcode)
End Function
4下面是写成数据库的函数形式(原著不名,我在网上搜索到的都没有标明作者),其实知道了算法,写成SQL语句也不困难:
Create
function
getCheckCode(
@SFZH
char
(
18
))
Returns char ( 1 )
As
Begin
declare @r char ( 1 )
declare @i int
if len ( @SFZH ) <> 18
set @r = ' ? '
else
set @i = cast ( substring ( @SFZH , 1 , 1 ) as int ) * 7
+ cast ( substring ( @SFZH , 2 , 1 ) as int ) * 9
+ cast ( substring ( @SFZH , 3 , 1 ) as int ) * 10
+ cast ( substring ( @SFZH , 4 , 1 ) as int ) * 5
+ cast ( substring ( @SFZH , 5 , 1 ) as int ) * 8
+ cast ( substring ( @SFZH , 6 , 1 ) as int ) * 4
+ cast ( substring ( @SFZH , 7 , 1 ) as int ) * 2
+ cast ( substring ( @SFZH , 8 , 1 ) as int ) * 1
+ cast ( substring ( @SFZH , 9 , 1 ) as int ) * 6
+ cast ( substring ( @SFZH , 10 , 1 ) as int ) * 3
+ cast ( substring ( @SFZH , 11 , 1 ) as int ) * 7
+ cast ( substring ( @SFZH , 12 , 1 ) as int ) * 9
+ cast ( substring ( @SFZH , 13 , 1 ) as int ) * 10
+ cast ( substring ( @SFZH , 14 , 1 ) as int ) * 5
+ cast ( substring ( @SFZH , 15 , 1 ) as int ) * 8
+ cast ( substring ( @SFZH , 16 , 1 ) as int ) * 4
+ cast ( substring ( @SFZH , 17 , 1 ) as int ) * 2
set @i = @i - @i / 11 * 11
set @r = ( case @i
when 0 then ' 1 ' when 1 then ' 0 ' when 2 then ' X ' when 3 then ' 9 '
when 4 then ' 8 ' when 5 then ' 7 ' when 6 then ' 6 ' when 7 then ' 5 '
when 8 then ' 4 ' when 9 then ' 3 ' when 10 then ' 2 ' else ' / ' end )
Return ( @r )
End
Returns char ( 1 )
As
Begin
declare @r char ( 1 )
declare @i int
if len ( @SFZH ) <> 18
set @r = ' ? '
else
set @i = cast ( substring ( @SFZH , 1 , 1 ) as int ) * 7
+ cast ( substring ( @SFZH , 2 , 1 ) as int ) * 9
+ cast ( substring ( @SFZH , 3 , 1 ) as int ) * 10
+ cast ( substring ( @SFZH , 4 , 1 ) as int ) * 5
+ cast ( substring ( @SFZH , 5 , 1 ) as int ) * 8
+ cast ( substring ( @SFZH , 6 , 1 ) as int ) * 4
+ cast ( substring ( @SFZH , 7 , 1 ) as int ) * 2
+ cast ( substring ( @SFZH , 8 , 1 ) as int ) * 1
+ cast ( substring ( @SFZH , 9 , 1 ) as int ) * 6
+ cast ( substring ( @SFZH , 10 , 1 ) as int ) * 3
+ cast ( substring ( @SFZH , 11 , 1 ) as int ) * 7
+ cast ( substring ( @SFZH , 12 , 1 ) as int ) * 9
+ cast ( substring ( @SFZH , 13 , 1 ) as int ) * 10
+ cast ( substring ( @SFZH , 14 , 1 ) as int ) * 5
+ cast ( substring ( @SFZH , 15 , 1 ) as int ) * 8
+ cast ( substring ( @SFZH , 16 , 1 ) as int ) * 4
+ cast ( substring ( @SFZH , 17 , 1 ) as int ) * 2
set @i = @i - @i / 11 * 11
set @r = ( case @i
when 0 then ' 1 ' when 1 then ' 0 ' when 2 then ' X ' when 3 then ' 9 '
when 4 then ' 8 ' when 5 then ' 7 ' when 6 then ' 6 ' when 7 then ' 5 '
when 8 then ' 4 ' when 9 then ' 3 ' when 10 then ' 2 ' else ' / ' end )
Return ( @r )
End