IMEI第十五位校验码的计算方法

1、什么是IMEI?
IMEI为TAC + FAC + SNR + SP。IMEI(International Mobile Equipment Identity)是国际移动设备身份码的缩写,国际移动装备辨识码,是由15位数字组成的"电子串号",它与每台手机一一对应,而且该码是全世界唯一的。每一只手机在组装完成后都将被赋予一个全球唯一的一组号码,这个号码从生产到交付使用都将被制造生产的厂商所记录。


其组成为:
1、前6位数(TAC)是"型号核准号码",一般代表机型。
2、接着的2位数(FAC)是"最后装配号",一般代表产地。
3、之后的6位数(SNR)是"串号",一般代表生产顺序号。
4、最后1位数(SP)通常是"0",为检验码,目前暂备用。
IMEI码贴在手机背面的标志上,并且读写于手机内存中。它也是该手机在厂家的"档案"和"身份证号"。
 ------TAC------------     --FAC-     ------SNR-----------
 D14 D13 D12 D11 D10 D9    D8  D7    D6  D5  D4  D3  D2  D1  D0
  3   5   3   1   1   4     0  0      8   0   9  6   3    6  6
计算IMEI验证码的步骤:
1、把IMEI的奇数位数*2,如:D1,D3,D5,……D13
 D13  D11  D9  D7  D5   D3   D1
  10   2   8   0   0    12    12
2、将计算得到的7个奇数位数字分别以个位数相加(如果得到的是个两位数,则十位和个位分别当成个位数来相加),再加上7个偶数位数字,如:D2,D4,D6……D14
3+1+0+3+2+1+8+0+0+8+0+9+1+2+3+1+2=44
3、如果第2步计算得到的数字末位为0,则验证码数字为0。如果第2步计算结果末位数不是0,则以大于第2步计算结果的以0结尾的双位整数减去第2步的计算结果,所获得的个位数即为验证码。
D0 = 50 -44 =6

2、下面附上自己写的luhn算法

  1. /*********************************************************************************** 
  2. Function Name :CGIBASE_AutoChangeIMEI 
  3. Description   :传入14位IMEI值,计算出第15位校正码,并返回15位IMEI值 
  4. Author:zhou Ying 
  5. ***********************************************************************************/  
  6. unsigned long CGIBASE_AutoChangeIMEI(char *pcSource, char *pcDest)  
  7. {     
  8.     int i,j,k;    
  9.     int iTotal,iEvenTotal,iAddTotal,iTemp,iAuth;      
  10.     char acEven[10],acAdd[10], acTemp[3],acAuth[2];   
  11.   
  12.     if ( ( NULL == pcSource ) || ( NULL == pcDest ) )  
  13.     {  
  14.         return 1;  
  15.     }  
  16.       
  17.     memset(acEven, 0x0, sizeof(acEven));      
  18.     memset(acAdd, 0x0, sizeof(acAdd));        
  19.     j=0;      
  20.     k=0;      
  21.     iTemp=0;      
  22.     iEvenTotal=0;     
  23.     iAddTotal=0;      
  24.     iTotal=0;     
  25.     iAuth=0;     
  26.       
  27.     for(i=0; i<14; i++)   
  28.     {         
  29.         if( 0 == (i%2) )          
  30.         {             
  31.             acEven[j]=*(pcSource+i);              
  32.             memset(acTemp, 0x0, sizeof(acTemp));              
  33.             sprintf(acTemp, "%c", acEven[j]);             
  34.             iTemp = atoi(acTemp);             
  35.             iEvenTotal += iTemp;              
  36.             j += 1;       
  37.         }         
  38.         else          
  39.         {             
  40.             acAdd[k]=*(pcSource+i);           
  41.             memset(acTemp, 0x0, sizeof(acTemp));              
  42.             sprintf(acTemp, "%c", acAdd[k]);                  
  43.             iTemp = atoi(acTemp) * 2;                     
  44.             iAddTotal += (iTemp / 10) + (iTemp % 10);             
  45.             k += 1;       
  46.         }     
  47.     }     
  48.       
  49.     iTotal = iEvenTotal + iAddTotal;      
  50.     if( iTotal >= 100 )   
  51.     {         
  52.         iAuth = iTotal % 100 %10;         
  53.         if( iAuth != 0 )          
  54.         {             
  55.             iAuth = ((iTotal % 100) / 10 + 1)*10 - iTotal % 100;          
  56.         }     
  57.     }     
  58.     else    
  59.     {       
  60.         iAuth = iTotal % 10;      
  61.         if( iAuth != 0 )          
  62.         {             
  63.             iAuth = (iTotal / 10 + 1)*10 - iTotal;        
  64.         }    
  65.     }          
  66.     memset(acAuth, 0x0, sizeof(acAuth));      
  67.     sprintf(acAuth, "%d", iAuth);         
  68.     strcat(pcDest, pcSource);     
  69.     strcat(pcDest, acAuth);  
  70.   
  71.     return 0;  
  72. }  

本人算法:

/******************************************

  1. Author:SUN JIANG ZHENG

************************************************/

UpdateData(TRUE);
int count;
int TESTNUM=0;
int MEINUMSEND[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
count=GetCheckedRadioButton(IDC_RADIOMEI,IDC_RADIOTEST);
if(count == IDC_RADIOTEST)
{
CString command;
command="AT%PARA=FACTORYOUTPUT,1#\n"; //打开测试
m_Port.WriteToPort((LPCTSTR)command); //发送数据
TX_count+=command.GetLength();
CString strTemp;
strTemp.Format("TX:%d",TX_count);
m_ctrlTXCount.SetWindowText(strTemp);
//AfxMessageBox("TEST发送");
}
else if(count == IDC_RADIOMEI)
{
if(m_editMeiSend.GetLength() < 14)
{
AfxMessageBox("确认输入的MEI有14位");
return;
}

if(1)
{
UpdateData(TRUE);
for(int i=0;i<14;i++)
{
MEINUMSEND[i]=m_editMeiSend[i]-'0';
}
for(int j=0;j<7;j++)
{
MEINUMSEND[j*2+1]=MEINUMSEND[j*2+1]*2;
}
for(int k=0;k<14;k++)
{
if(MEINUMSEND[k]<10)
{
TESTNUM+=MEINUMSEND[k];
}
else
{
TESTNUM+=MEINUMSEND[k]/10;
TESTNUM+=MEINUMSEND[k]%10;
}
}
if(TESTNUM%10 == 0)
{
TESTNUM=0;
}
else
{
TESTNUM=(((TESTNUM/10)+1)*10)-TESTNUM;
}
}

CString command;
char point='"';
command="AT+EGMR=1,7,";
command+=point;
command+=m_editMeiSend;
command+=TESTNUM+'0';
command+=point;
command+='\n';
m_Port.WriteToPort((LPCTSTR)command); //发送数据

posted on 2015-01-14 16:11  塞北大漠  阅读(1977)  评论(0)    收藏  举报

导航