我正试图在一个银行账户创建示例的函数中生成一个16位随机卡号。我尝试了下面的代码,但没有成功。
void generate_card_number() {
srand(time(0));
long long int cardnumber = 0;
int i, randctrl;
for (i = 0; i < 15; i++) {
do {
randctrl = rand() % 9;
} while (randctrl == 0);
cardnumber += ((10^i) * randctrl);
}
printf("nThe Card Number : %lld", cardnumber);
}
你能帮我吗?
您的程序有几个不同的问题:
-
最引人注目的是这条线:
cardnumber+= ( (10^i) * randd ) ;
它并不像你想象的那样。
^
运算符执行两个操作数的逐位异或,它不计算幂。 -
您使用循环将
0
从数字中排除,这是不必要的(可以在没有循环的情况下完成(,而且似乎也是错误的,因为0
是一个完全有效的数字。如果你想强制你的数字有16位,那么你只希望最有效的一位不同于0
,而不是所有。 -
循环从
i=0
运行到14
,因此生成的是15位数字,而不是16位。 -
每次调用此函数时,都会调用
srand(time(0))
。如果在同一秒内调用,这将使函数生成相同的数字(time(0)
以秒为单位返回当前时间戳(。您可能不希望这样,并且应该在main()
中只调用srand()
一次。 -
没有理由对您的号码进行签名,这只会导致潜在的问题,请使用
unsigned
。
这里有一个相当简单的代码版本,可以实现您想要的。如果你正在寻找一个更快/更优化的版本,你可能想通过chqrlie查看另一个答案。
void generate_card_number()
{
unsigned long long cardnumber;
unsigned i;
// Ensure most significant digit is not 0
cardnumber = rand() % 9 + 1;
// Add 15 more digits (which can also be 0)
for (i = 0; i < 15; i++)
{
cardnumber *= 10;
cardnumber += rand() % 10;
}
printf("nThe Card Number : %llu", cardnumber);
}
您的代码中存在以下几个问题:
srand(time(0));
用于对伪随机数生成器进行种子。在main()
函数中只使用一次,否则在同一秒内生成的所有数字都将相同- 要生成一个16位的随机数,唯一不能为零的数字是第一个,其他所有数字都可以为零,这与代码不同
10^i
不计算C中10
的第i次幂,它评估10
或i
- 你没有计算出足够的数字
randd
未定义
计算从最高有效位到最低有效位的数字更容易。这是一个修改版本:
#include <stdlib.h>
void generate_card_number() {
// start with a digit between 1 and 9
long long cardnumber = 1 + rand() % 9;
// add the remaining 15 digits
for (int i = 1; i < 16; i++)
cardnumber = cardnumber * 10 + rand() % 10;
printf("The Card Number: %lldn", cardnumber);
}
由于RAND_MAX
保证大于10000
,因此一次可以计算4位数字:
#include <stdlib.h>
void generate_card_number() {
// start with a number between 1000 and 9999
long long cardnumber = 1000 + rand() % 9000;
cardnumber = cardnumber * 10000 + rand() % 10000; // add 4 digits
cardnumber = cardnumber * 10000 + rand() % 10000; // add 4 digits
cardnumber = cardnumber * 10000 + rand() % 10000; // add the last 4 digits
printf("The Card Number: %lldn", cardnumber);
}
在大多数平台上,RAND_MAX
要大得多,所以这里有一个替代方案可以利用这一点,并使用更少的调用来生成号码:
#include <stdlib.h>
void generate_card_number() {
#if RAND_MAX >= 100000000
// start with a number between 10000000 and 99999999
long long cardnumber = 10000000 + rand() % 90000000;
cardnumber = cardnumber * 100000000 + rand() % 100000000; // add 8 digits
#else
// start with a number between 1000 and 9999
long long cardnumber = 1000 + rand() % 9000;
cardnumber = cardnumber * 10000 + rand() % 10000; // add 4 digits
cardnumber = cardnumber * 10000 + rand() % 10000; // add 4 digits
cardnumber = cardnumber * 10000 + rand() % 10000; // add the last 4 digits
#endif
printf("The Card Number: %lldn", cardnumber);
}
但是请注意,卡号有额外的限制,例如限制值范围,并且必须有有效的Luhn校验和。
正如评论中所指出的,如果你不必对卡号进行任何算术运算,如加法、减法等。最好将卡号存储为字符串:
int getRandomDigit() {
return rand() % 10;
}
void generateCardNumber(char cardNumber[], int size) {
for (int i = 0; i < size; i++) {
cardNumber[i] = '0' + getRandomDigit();
}
cardNumber[size] = ' ';
}
int main() {
srand(time(NULL));
const int size = 16;
char card1[size + 1], card2[size + 1];
generateCardNumber(card1, size);
generateCardNumber(card2, size);
printf("%sn", card1);
printf("%sn", card2);
}
上面的代码生成一个16位的卡片数字,如下所示:
0216624478324435
8815844216687237