132次浏览

C/C++ 生成随机银行卡号可过Luhn校验

如何随机生成一些能通过Lunhn算法校验的银行卡号数据 ? 要想生成真实卡号数据就必须要了解银行卡号的规则以及校验方式, 下面列出一些银行的卡号前六位规则 (以19位卡号为例)

	/*
	436745 中国建设银行VISA龙卡贷记zd卡
	622280 中国建设银行支付宝龙卡借记卡
	458123 交通银行VISA普通卡
	521899 交通银行MC信用卡普通卡
	622260 交通银行太平洋卡借记卡
	402674 上海银行VISA金卡
	622892 上海银行借记卡
	622188 中国回邮政储蓄绿卡借记卡
	602969 北京银行京卡借记卡
	622760 中国银行中银都市卡
	623668 中国建设银行龙卡
	*/

银行卡前六位是发卡银行识别号(BIN),这个号码可以提供的信息包括这张卡属于哪个信用卡组织,这张卡由哪个银行发行,这张卡是什么类型的卡片。 

银行卡的最后一位是校验位,用于卡号验证。 从第7位到倒数第2位是发卡银行使用的,包含的内容有开户行位置(发卡城市),卡号大序列等等,但是具体内容由发卡银行自己定义。

Luhn算法/公式

Luhn算法被用于最后一位为校验码的一串数字的校验,通过如下规则计算校验码的正确性:

  1. 按照从右往左的顺序,从这串数字的右边开始,包含校验码(最后一位是校验码),将偶数位的数字乘以2,如果得出的值大于9(如2 x 5 = 10)则计算这个值的个位数字和十位数字的和那么就是( 1 + 0 = 1);
  2. 第一步操作过后会得到新的一串数字,计算所有数字的和(包含校验码);
  3. 用第二步操作得到的和进行 “模10” 运算,其实就是判断得到的和能否被10整除,能则通过校验,反之不通过。

简单例子

了解完Luhn算法的公式后,开始实践, 例如一串数: 788123

最后一位 (3) 为校验位,通过公式转换后的数字为: 587143

再将所有数字相加 5+8+7+1+4+3=28, 所得和不能被10整除因此校验不通过。

银行卡随机生成思路

可知银行卡号前六位为发卡银行代码, 最后一位为校验位, 要生成建设银行龙卡类型的卡号 ( 通常卡号为19位 ) , 即: “623668” + 随机12位数字 + 校验位, 利用校验位数字来生成有效的银行卡号, 校验位之前的数字经过Luhn公式转换后所有数字相加得到一个和, 这个和 + 校验位数字要能被10整除, 因此弄个for循环用这个和去跟数字1到9进行尝试, 得到的和总有一次会成功被10整除, 此时得到的卡号就是有效的。

C/C++代码实现

int main()
{
	//银行类型的6位标识数字
	string card = "623668";
	srand((int)time(0));  // 产生随机种子  把0换成NULL也行
	//取12位随机数字
	for (int i = 0; i < 12; i++)
	{
		char buffer[10];
		itoa(1 + rand() % 9, buffer, 10);
		card += buffer;
	}


	int s = 0;
	int num = 0;
	int len = card.length() + 1;

	//校验位前一位是偶数位因此i初始化为2
	for (int i = 2; i <= len; i++)
	{
		//依次从右往左取出数字
		char buff = card[len - i];
		num = atoi(&buff);

		//判断当前在奇数位还是偶数位
		if (i % 2 == 0)
		{
			if ((num * 2) >= 10)
			{
				//偶数位*2大于10, 大于10则为两位数

				char buffer[3] = { 0 };
				itoa(num * 2, buffer, 10);
				//个位数与十位数相加
				s += (int(buffer[0]) - 48) + (int(buffer[1]) - 48);
			}
			else
				//偶数位*2小于10则不用十位各位相加直接取出
				s += num * 2;
		}
		else
			//奇数位直接取出
			s += num;
	}

	//判断s+几才能被10整除
	for (int i = 0; i < 10; i++)
	{
		if ((s + i) % 10 == 0)
		{
			char buffer[2] = { 0 };
			itoa(i, buffer, 10);
			card += buffer;
			break;
		}

	}

	//输出有效卡号
	cout << card << endl;

	return 0;
}

运行效果

校验银行卡 C/C++代码实现:

bool checkCard(string card)
{
	int length = card.length();

	if (!(length == 16 || length == 19)) {
		return false;
	}

	int s = 0;
	int num = 0;
	for (int i = 0; i < length; i++)
	{
		char buff = card[i];
		num = atoi(&buff);

		if ((i + 1) % 2 == 0)
		{
			if ((num * 2) >= 10)
			{
				char buffer[3] = { 0 };
				itoa(num * 2, buffer, 10);

				s += (int(buffer[0]) - 48) + (int(buffer[1]) - 48);
			}
			else
				s += num * 2;
		}
		else
			s += num;
	}

	if (s % 10 == 0)
	{
		return true;
	}
	else return false;

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注