关于18位身份证的算法,长期疑惑
以下是C#的算法实现,有个疑问,最后那段代码
ai [17] = chTab [ sum % 11 ] ;
为什么一定要对11求余数,这样就导致最后一位有可能出现大于9的情况了,如果是对10求余数,这样余数就不会大于9了,身份证末尾就不必要出现一个 "X "的情况了,不是可以省很多事情吗,有人知道原因吗?
==================
//15位身份证号码转18位算法
class CIDCardNumber
{
// 最后的18位身份证号码
TCHAR szIdCard18 [MAX_PATH];
// 经过初次变换后的15位身份证号码
char ai[18];
public:
/*
功能:15位号码转换为18位
参数:chCodeNumber原15位身份证号码
*/
char * IDCard15To18 (const char * const chCodeNumber )
{
// 初次变换,把出生年由2位变为4位
// 最后一位a代表未知 。
ai[ 0] = chCodeNumber [0 ] ;
ai[ 1] = chCodeNumber [1 ] ;
ai[ 2] = chCodeNumber [2 ] ;
ai[ 3] = chCodeNumber [3 ] ;
ai[ 4] = chCodeNumber [4 ] ;
ai[ 5] = chCodeNumber [5 ] ;
ai[ 6] = '1 ' ;
ai[ 7] = '9 ' ;
ai[ 8] = chCodeNumber [6 ] ;
ai[ 9] = chCodeNumber [7 ] ;
ai[10] = chCodeNumber [8 ] ;
ai[11] = chCodeNumber [9 ] ;
ai[12] = chCodeNumber [10] ;
ai[13] = chCodeNumber [11] ;
ai[14] = chCodeNumber [12] ;
ai[15] = chCodeNumber [13] ;
ai[16] = chCodeNumber [14] ;
ai[17] = 'a ' ;
// 以下计算最后一位a
// 加权系数
const short shModulus[18] =
{ 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1} ;
int sum = 0 ;
// 初次变换后的身份证号码和加权系数对应位积的和
for ( int i =0 ; i < 17 ; i ++ )
{
TCHAR szTemp[MAX_PATH];
_stprintf ( szTemp , TEXT ( "%c " ) , ai ) ;
sum += ( atoi ( szTemp ) * shModulus );
}
// 查表,对应sum的值,查下表
const char chTab[11] =
{ '1 ', '0 ', 'X ', '9 ', '8 ', '7 ', '6 ', '5 ', '4 ', '3 ', '2 '};
// 把查表所得的值赋给ai的未知数a
ai [17] = chTab [ sum % 11 ] ;
_stprintf ( szIdCard18 , TEXT ( "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c " ) ,
ai[0] , ai[1 ], ai[2] , ai[3] , ai[4] , ai[5] , ai[6] , ai[7] ,
ai[8] , ai[9] , ai[10] , ai[11] , ai[12] , ai[13] , ai[14] ,
ai[15] , ai[16] ,ai[17] ) ;
// 计算完毕,返回18位身份证号码