日期:2014-05-19  浏览次数:20694 次

关于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位身份证号码