Luhn算法

来源:互联网 发布:oracle数据库设计文档 编辑:程序博客网 时间:2024/06/05 17:36
 LUHN是一个算法,它的就要作用是为了计算信用卡等证件号码的合法性。我们用一个例子来看一下这个算法的工作过程:

假设我们有一个数4992 73 9871,这个数是没有带校验码的,算法的计算分为三步:

  1. 由最低位起每隔一位取一个数字,将这个数字乘2;
    1*2=2 8*2=16 3*2=6 2*2=4 9*2=18
  2. 将数字中余下的数字和上面结果中的数字直接相加,得到结果B;
    4 + 1+8 + 9 + 4 + 7 + 6 + 9 + 1+6 + 7 + 2 = 64
  3. 生成校验码C=A-B,其中A是比B大的10倍数中最小的数字,如B=86,则A=90;如B=34,A=40;
    6 = 70-64
  4. 将校验码加在原来数字的后面生成合法的帐户密码;
    4992 73 9871

现已Master Card为例:

  1.   <script>
  2.    function isValidMasterCard(sText){
  3.     var reMasterCard=/^(5[1-5]/d{2})[/s/-]?(/d{4})[/s/-]?(/d{4})[/s/-](/d{4})$/;
  4.     
  5.     if(reMasterCard.test(sText)){
  6.      var sCardNum=RegExp.$1+RegExp.$2+RegExp.$3+RegExp.$4;   
  7.       alert(sCardNum);   
  8.      //Luhn algorithm here
  9.      return luhnCheckSum(sCardNum);
  10.     }else{
  11.      return
  12.     }
  13.    }
  14.    
  15.    function luhnCheckSum(sCardNum){
  16.     var iOddSum=0;
  17.     var iEvenSum=0;
  18.     var bIsOdd=true;
  19.     
  20.     for(var i=sCardNum.length-1;i>=0;i--){
  21.     //alert("length="+sCardNum.length);
  22.     //alert("sCardNum.char("+i+")="+sCardNum.charAt(i));
  23.      var iNum=parseInt(sCardNum.charAt(i));
  24.      
  25.      if(bIsOdd){
  26.      //反向奇數求和
  27.       iOddSum+=iNum;   
  28.       
  29.      }else{
  30.       //偶數  
  31.       if(iNum>9){
  32.        iNum=eval(iNum.toString().split("").join("+"));
  33.       }
  34.       iEvenSum+=iNum;
  35.      
  36.      }
  37.      bIsOdd=!bIsOdd;
  38.     }
  39.      return ((iEvenSum+iOddSum)%10==0);
  40.    }
  41.    
  42.    alert(isValidMasterCard("5432 1234 5678 9012"));
  43.    alert(isValidMasterCard("5432-1234-5678-9012"));
  44.    
  45.   </script>

C++例子:

LLUHN.cpp

  1. //////////////////////////////////////////////////////////////////////
  2. //
  3. // Designed by Liutao, Xi'an Jitotong University
  4. // 2001-04-23
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7. //
  8. // LLUHN.cpp: implementation of the LLUHN class.
  9. //
  10. //////////////////////////////////////////////////////////////////////
  11. #include "LLUHN.h"
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[]=__FILE__;
  15. #define new DEBUG_NEW
  16. #endif
  17. //////////////////////////////////////////////////////////////////////
  18. // Construction/Destruction
  19. //////////////////////////////////////////////////////////////////////
  20. LLUHN::LLUHN()
  21. {
  22.     m_strCardNum = _T("");
  23. }
  24. LLUHN::LLUHN(CString strCardNum)
  25. {
  26.     for (int i=0; i<strCardNum.GetLength(); i++)
  27.         if (!isdigit(strCardNum[i])) 
  28.         {
  29.             LLUHN();
  30.             return;
  31.         }
  32.     m_strCardNum = strCardNum;
  33. }
  34. LLUHN::~LLUHN()
  35. {
  36.     m_strCardNum = _T("");  
  37. }
  38. #define CurrentDigit(i) (m_strCardNum[i]-'0')
  39. BOOL LLUHN::IsValid()
  40. {
  41.     int sum = 0;
  42.     if (m_strCardNum.IsEmpty()) return false;
  43.     for (int i=m_strCardNum.GetLength()-2; i>=0; )
  44.     {
  45.         sum += CurrentDigit(i)*2>10 ? 1+(CurrentDigit(i)*2)%10 : CurrentDigit(i)*2, i--;
  46.         if (i>=0) sum += CurrentDigit(i), i--;
  47.     }
  48.     return (10-sum%10)==(m_strCardNum[m_strCardNum.GetLength()-1]-'0');
  49. }
  50. char LLUHN::GetCheckSum()
  51. {
  52.     int sum = 0;
  53.     if (m_strCardNum.IsEmpty()) return false;
  54.     for (int i=m_strCardNum.GetLength()-1; i>=0; )
  55.     {
  56.         sum += CurrentDigit(i)*2>10 ? 1+(CurrentDigit(i)*2)%10 : CurrentDigit(i)*2, i--;
  57.         if (i>=0) sum += CurrentDigit(i), i--;
  58.     }
  59.     return (10-sum%10+'0');
  60. }
  61. #undef CurrentDigit
  62. BOOL LLUHN::SetCardNum(CString strCardNum)
  63. {
  64.     for (int i=0; i<strCardNum.GetLength(); i++)
  65.         if (!isdigit(strCardNum[i])) return false;
  66.     m_strCardNum = strCardNum;
  67.     return true;
  68. }
  69. const CString LLUHN::GetCardNum()
  70. {
  71.     return m_strCardNum;
  72. }

LLUHN.h

  1. //////////////////////////////////////////////////////////////////////
  2. //
  3. // Designed by Liutao, Xi'an Jitotong University
  4. // 2001-04-23
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7. //
  8. // LLUHN.h: interface for the LLUHN class.
  9. //
  10. //////////////////////////////////////////////////////////////////////
  11. #if !defined(AFX_LLUHN_H__6ACE3589_24B6_466C_921F_DCA4CA09AC97__INCLUDED_)
  12. #define AFX_LLUHN_H__6ACE3589_24B6_466C_921F_DCA4CA09AC97__INCLUDED_
  13. #if _MSC_VER > 1000
  14. #pragma once
  15. #endif // _MSC_VER > 1000
  16. class LLUHN  
  17. {
  18. public:
  19.     const CString GetCardNum();
  20.     char GetCheckSum();
  21.     BOOL IsValid();
  22.     BOOL SetCardNum(CString strCardNum);
  23.     LLUHN();
  24.     LLUHN(CString strCardNum);
  25.     virtual ~LLUHN();
  26. private:
  27.     CString m_strCardNum;
  28. };
  29. #endif // !defined(AFX_LLUHN_H__6ACE3589_24B6_466C_921F_DCA4CA09AC97__INCLUDED_)

参考资料:见 Luhn algorithm http://en.wikipedia.org/wiki/Luhn_algorithm