C002-CPP-Luhn公式

使用Luhn算法检验 键入的一串数字 是否合法


Luhn算法:

Luhn 是 模10算法:

符合Luhn算法的数字串包含2部分:具体数字(任意长度) + 校验数字(1个)
比如[1762483],符合Luhn算法,它的两部分是:[176248] + [3]
具体数字是任意的数字,它的校验数字是通过Luhn算法算出来的,计算后得到的整个数字串符合Luhn算法

Luhn算法的步骤:

假设数字串[176248]的校验数字是X,即整个数字串是[176248X],求出X的步骤如下:
1、从[176248X]的右边开始数,偶数位置的数字是[7,2,8],奇数位置的数字是[1,6,4,X]
2、将奇数位的数字相加:sum = 1 + 6 + 4 + X = 11 + X
3、将偶数位的数字都乘以2,得到数字串:[14,4,16]
4、将这个数字串中大于等于10的数字的十位和个位拆开,分别成为2个独立的数字:[1,4,4,1,6]
5、再将这个数字串的每一位加到sum中去:sum = 11 + X + 1 + 4 + 4 + 1 + 6 = 27 + X
6、Luhn算法要求sum必须可以被10整除,而X必须是1位数,所以X = 3,sum = 27 + 3 = 30,sum % 10 = 30 % 10 = 0
7、于是数字串[176248]加上的校验数字是3:1762483


上面是假设数字串已经符合Luhn算法,然后求出校验数字,这用来生成符合Luhn算法的数字串


下面的代码用来检验一个数字串是否符合Luhn算法,即在校验数字已知的情况下,检验数字串的sum是否可以被10整除


代码:

2_3_Luhn.cpp

// ==========================================================================================================
// 2-3节,Luhn算法:检验键入的一串数字是否合法
// 
// ==========================================================================================================
#include "2_3_Luhn.h"

#include <iostream>
// ----------------------------------------------------------------------------------------------------------
//      包含namespace std (@ iostream):
// (1). 换行符用"endl"指令,意为end of line
// (2). cin >> val 是函数调用,成功输入数据到val,返回TRUE,否则返回FALSE
// ----------------------------------------------------------------------------------------------------------
using namespace std;

#define DEBUG   1

// ==========================================================================================================
// 返回一个Luhn数的和
// 
// ==========================================================================================================
int Luhn_get_sum(int data)
{
    int temp;
    int sum;

    if(data > 9)
    {
        cout << "A Luhn number can not bigger than 9" << endl;
        return -1;
    }
    temp = data * 2;
    if(temp >= 10) { sum = 1 + temp % 10; }
    else           { sum = temp; }

    return sum;
}

// ==========================================================================================================
// Luhn公式:求键入的一串数字的Luhn和
// 
// 参数:sum     数字串的Luhn和
//       length  数字串的长度
// 
// (1). 输入的数字字符必须是ASCII码的字符、或是从0到9依次排列的数字字符
// 
// ==========================================================================================================
void Luhn_sum(int *sum, int *length)
{
    char number;    // 接收输入的数字串中的一个元素
    int  count = 0; // 记录数字串的长度
    int  sum_odd  = 0;
    int  sum_even = 0;

    cout << "Enter your number : ";
    while(1)
    {
        cin.get(number);
        if(('\n' == number) || ('\r' == number)) { break; }
        number -= '0';   // 减去序列中的第1个字符(不写成10,因为'0'字符在不同编码系统中的具体值可能不一样)
        count++;
        if(0 == (count % 2))                    // 从左到右数的偶数序列
        {                                       // 
            sum_odd  += Luhn_get_sum(number);   // 奇数长度的数字串:需要翻倍
            sum_even += number;                 // 偶数长度的数字串:不需要翻倍
        }
        else                                    // 从左到右数的奇数序列
        {
            sum_odd  += number;                 // 奇数长度的数字串:不需要翻倍
            sum_even += Luhn_get_sum(number);   // 偶数长度的数字串:需要翻倍
        }
#if DEBUG
        cout << '[' << '(' << count << ") " << (int)number << ',' << sum_odd  << ',' << sum_even  << ']' << endl;
#endif
    }
    *length = count;
    if(0 == (count % 2))
    { *sum = sum_even; }    // 长度为偶数
    else               
    { *sum = sum_odd;  }    // 长度为奇数
}

// ==========================================================================================================
// Luhn公式:检验键入的一串数字是否合法
// 
// ==========================================================================================================
void Luhn_check(void)
{
    int sum;
    int length;

    Luhn_sum(&sum, &length);
#if DEBUG
    cout << "The length of the input numbers = " << length << endl;
    cout << "and the Luhn-sum = " << sum << endl;
#endif
    cout << "The input numbers is " 
         << ((0 == (sum % 10)) ? "LEGAL" : "ILLEGAL" )
         << " (According to Luhn-Rule)" 
         << endl;
}
main.c

// ==========================================================================================================
// 主函数
// ==========================================================================================================


#include <malloc.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

#include "2_3_Luhn.h"

// ==========================================================================================================
// main函数
// 
// ==========================================================================================================
int main(void)
{
// ----------------------------------------------------------------------------------------------------------
//  使用Luhn公式对输入数字串进行检验
    while(1)
    { Luhn_check(); }

// ----------------------------------------------------------------------------------------------------------
    system("pause");
    return 0;
}

测试结果:

(1). 使用Luhn公式作为输入检查的号码:银行卡卡号。

       因而可以使用银行卡卡号来检验。

       这里测试了多个银行卡卡号,结果都OK。

(2). ISBN和身份证等数字串不是使用上面的Luhn算法得出的。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值