CS50 信用卡验证
CS50 Credit Card Validation
#include
#include
int main(void)
{
long cc = get_long("信用卡:"); // 获取输入
long len = 0; //intialized length
long x = cc; // set 2nd variable = to cc to prevent manipulation of cc
while (x != 0) // length count loop while x is divisable loop will continue will be stored as len
{
x = x / 10;
len++;
}
if ((len != 16) && (len != 15) && (len != 13)) //Checking for length to see if number matchs possible postive outcomes
{
printf("INVALID\n");
return 0;
}
//pull 2nd to last and then every other digit
long cc_num1 = ((cc % 100) / 10);
long cc_num2 = ((cc % 10000) / 1000);
long cc_num3 = ((cc % 1000000) / (100000));
long cc_num4 = ((cc % 100000000) / (10000000));
long cc_num5 = ((cc % 10000000000) / (1000000000));
long cc_num6 = ((cc % 1000000000000) / (100000000000));
long cc_num7 = ((cc % 100000000000000) / (10000000000000));
long cc_num8 = ((cc % 10000000000000000) / (1000000000000000));
cc_num1 = (cc_num1 * 2); //Multiply digits pulled above by 2
cc_num2 = (cc_num2 * 2);
cc_num3 = (cc_num3 * 2);
cc_num4 = (cc_num4 * 2);
cc_num5 = (cc_num5 * 2);
cc_num6 = (cc_num6 * 2);
cc_num7 = (cc_num7 * 2);
cc_num8 = (cc_num8 * 2);
cc_num1 = ((cc_num1 / 10) + (cc_num1 % 10)); //split double digits and add to signles
cc_num2 = ((cc_num2 / 10) + (cc_num2 % 10));
cc_num3 = ((cc_num3 / 10) + (cc_num3 % 10));
cc_num4 = ((cc_num4 / 10) + (cc_num4 % 10));
cc_num5 = ((cc_num5 / 10) + (cc_num5 % 10));
cc_num6 = ((cc_num6 / 10) + (cc_num6 % 10));
cc_num7 = ((cc_num7 / 10) + (cc_num7 % 10));
cc_num8 = ((cc_num8 / 10) + (cc_num8 % 10));
long cc_sum = cc_num1 + cc_num2 + cc_num3 + cc_num4 + cc_num5 + cc_num6 + cc_num7 + cc_num8; // add sum of number above
long cc_num1x = ((cc % 10) / 1); //pulls last digit from card then everyother digit
long cc_num2x = ((cc % 1000) / 100);
long cc_num3x = ((cc % 100000) / 10000);
long cc_num4x = ((cc % 10000000) / 1000000);
long cc_num5x = ((cc % 1000000000) / 100000000);
long cc_num6x = ((cc % 100000000000) / 10000000000);
long cc_num7x = ((cc % 10000000000000) / 1000000000000);
long cc_num8x = ((cc % 1000000000000000) / 100000000000000);
long cc_sumx = cc_num1x + cc_num2x + cc_num3x + cc_num4x + cc_num5x + cc_num6x + cc_num7x +
cc_num8x; //adds last and everyother digit together
long sumofsums = cc_sum + cc_sumx; // adds sums of both sums created
if ((sumofsums % 10) != 0) // Luhn’s Algorithm results will close if not met
{
printf("INVALID\n");
return 0;
}
{
if (len == 15) // checks for AMEX by using length then first 2 digits
{
long ax = cc / 10000000000000;
if ((ax == 34 || ax == 37))
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
long mc = cc / 100000000000000;
long v = cc / 1000000000000000;
long v2 = cc / 1000000000000;
if (len == 16) // Checks for MC and Via (16 digits) by length then first 2 digits MC or 1 visa
{
if ((mc == 51 || mc == 52 || mc == 53 || mc == 54 || mc == 55))
{
printf("MASTERCARD\n");
}
else if (v == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
if (len == 13) //Checks 2nd Visa length 13 digits then 1st digit
{
if (v2 == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
必须有比我计划执行此操作更好的方法。长度计数循环在 10 位数字之前都很好,但随后会提取随机数。
每隔一个数字公式似乎可以通过递归完成,但我对此一无所知。由于数量最多限制为 16,因此我使用的公式似乎有效。
- 判断卡是否为15 || 16 || IF Else loop
if not mark In valid in valid in if Else loop 13位数字
- 使用CC校验和公式If else循环(不满足Criteria则有效)
- 查看 2 个起始号码以确定 AX、MC 或 Visa
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
long cc = get_long("Credit Card: " ); // gets input
int len = 0; //intialized length
int x = cc; // set 2nd variable = to cc to prevent manipulation of cc
while(x != 0) // length count loop while x is divisable loop will continue will be stored as len
{
x = x/10;
len++;
}
printf("%i\n", len); // REMOVE !!!!!!!!!!! BUG TEST
//pull 2nd to last and then every other digit
int cc_num1 = ((cc % 100)/10);
int cc_num2 = ((cc % 10000)/1000);
int cc_num3 = ((cc % 1000000)/(100000));
int cc_num4 = ((cc % 100000000)/(10000000));
int cc_num5 = ((cc % 10000000000)/(1000000000));
int cc_num6 = ((cc % 1000000000000)/(100000000000));
int cc_num7 = ((cc % 100000000000000)/(10000000000000));
int cc_num8 = ((cc % 10000000000000000)/(1000000000000000));
printf("%i %i %i %i %i %i %i %i", cc_num1, cc_num2, cc_num3, cc_num4 , cc_num5, cc_num6 , cc_num7 , cc_num8 );
}
让我们先感谢房间里的大象。
long cc = get_long("Credit Card: " );
...
int x = cc;
C 标准指定 long
至少为 32 位,而 int
必须至少为 16 位。当然,实际值取决于您的系统和您的库实现。但通常情况下,long
将 能够存储比 int
更多的位。就像这里的情况一样。这意味着“超过 10 位的数字”,本质上是太大而无法存储到 int
中的数字将导致 undefined behavior。要确切知道 system/environment 中 int
的上限是哪个数字,您可以打印 limits.h
.
中定义的 INT_MAX
的值
解决方案当然是将 long
变量存储在 另一个 long
变量中,而不是 int
。或者,只需将值传递给执行必要工作的函数。现在将所有内容都放在 main 中不是很有条理是吗。
我们如何制作一个函数,根据卡号打印一张卡的所有详细信息?
签名看起来像-
void print_card_details(long num)
现在我们需要一个函数来通过 luhn 的算法来放置卡片。我们还可以为此创建一个函数-
int is_valid(long num)
{
int curr_digit, add_digit, prod_sum = 0, sum = 0;
for (int digit_count = 0; num != 0; num /= 10, digit_count++)
{
// Strip each digit from number, starting from the end
curr_digit = num % 10;
if (digit_count % 2 != 0)
{
// Every 2nd digit from the right goes through this
// The current digit gets doubled
// The digits of that result are added to the sum
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
}
else
{
// The remaining digits go through this
// They are all summed up
sum += curr_digit;
}
}
if ((prod_sum + sum) % 10 != 0)
{
// If the sum of prod_sum + sum doesn't end in 0
// It is invalid
return 0;
}
else
{
// The card is valid
return 1;
}
}
迭代一个数的数字的传统方法不是暴力地手动除10
的任意幂,而是迭代它并除以模数10。例如,这个片段-
while (x != 0)
{
printf("Current digit: %d\n", x % 10);
x /= 10;
}
将打印存储在 x
中的号码的所有数字。这基本上就是我们在 luhn 算法循环中使用的内容。除了我们还对总位数进行计数,因为我们只想要从末尾开始的每一秒数字。我们如何知道当前数字符合此标准?我们检查当前 digit_count
是否为偶数(通过除以 2 并检查剩余为 0)。
后面的公式-
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
基本上就是这个-
的实现
Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
确保仅添加结果 add_digit
的 位 。因此,如果 add_digit
最终为 12。我们需要添加 1 + 2。这正是 add_digit % 10 + add_digit / 10
所做的。 12 % 10 当然是 2。而 12 / 10 是 1。
这个函数return如果卡片有效则返回 1,否则返回 0。你可以把它放在你的主要功能中,并检查 return 值以了解该卡是否有效。
如果有效,请继续下一步检查卡片的位数以及开头的数字。
我们可以做一个循环来计算数字的个数,以及存储数字的第一位和第二位。
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
这将为您提供卡号的长度。注意,在最后一次迭代中,prev_digit
的值是第二个数字,curr_digit
是第一个数字。因此 curr_digit * 10 + prev_digit
将产生信用卡号开头的前 2 个数字(一起)。
最后,你只需要一堆简单的if/else
子句来验证它是哪张卡。您也只被要求检查一个非常小的子集。所以这里是-
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && begins_with / 10 == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && begins_with == 34 ||)
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (curr_digit == 5)
{
// MASTERCARD number begins with 5
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
把这些放在一起,你应该有希望得到
void print_card_details(long num)
{
if (!is_valid(num))
{
// Card did not pass luhn's algo
printf("INVALID\n");
return;
}
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && curr_digit == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && (begins_with == 34 || begins_with == 37))
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (begins_with >= 51 && begins_with <= 55)
{
// MASTERCARD number begins with 51, 52, 53, 54, or 55
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
return;
}
#include
int main(void) { long cc = get_long("信用卡:"); // 获取输入
long len = 0; //intialized length
long x = cc; // set 2nd variable = to cc to prevent manipulation of cc
while (x != 0) // length count loop while x is divisable loop will continue will be stored as len
{
x = x / 10;
len++;
}
if ((len != 16) && (len != 15) && (len != 13)) //Checking for length to see if number matchs possible postive outcomes
{
printf("INVALID\n");
return 0;
}
//pull 2nd to last and then every other digit
long cc_num1 = ((cc % 100) / 10);
long cc_num2 = ((cc % 10000) / 1000);
long cc_num3 = ((cc % 1000000) / (100000));
long cc_num4 = ((cc % 100000000) / (10000000));
long cc_num5 = ((cc % 10000000000) / (1000000000));
long cc_num6 = ((cc % 1000000000000) / (100000000000));
long cc_num7 = ((cc % 100000000000000) / (10000000000000));
long cc_num8 = ((cc % 10000000000000000) / (1000000000000000));
cc_num1 = (cc_num1 * 2); //Multiply digits pulled above by 2
cc_num2 = (cc_num2 * 2);
cc_num3 = (cc_num3 * 2);
cc_num4 = (cc_num4 * 2);
cc_num5 = (cc_num5 * 2);
cc_num6 = (cc_num6 * 2);
cc_num7 = (cc_num7 * 2);
cc_num8 = (cc_num8 * 2);
cc_num1 = ((cc_num1 / 10) + (cc_num1 % 10)); //split double digits and add to signles
cc_num2 = ((cc_num2 / 10) + (cc_num2 % 10));
cc_num3 = ((cc_num3 / 10) + (cc_num3 % 10));
cc_num4 = ((cc_num4 / 10) + (cc_num4 % 10));
cc_num5 = ((cc_num5 / 10) + (cc_num5 % 10));
cc_num6 = ((cc_num6 / 10) + (cc_num6 % 10));
cc_num7 = ((cc_num7 / 10) + (cc_num7 % 10));
cc_num8 = ((cc_num8 / 10) + (cc_num8 % 10));
long cc_sum = cc_num1 + cc_num2 + cc_num3 + cc_num4 + cc_num5 + cc_num6 + cc_num7 + cc_num8; // add sum of number above
long cc_num1x = ((cc % 10) / 1); //pulls last digit from card then everyother digit
long cc_num2x = ((cc % 1000) / 100);
long cc_num3x = ((cc % 100000) / 10000);
long cc_num4x = ((cc % 10000000) / 1000000);
long cc_num5x = ((cc % 1000000000) / 100000000);
long cc_num6x = ((cc % 100000000000) / 10000000000);
long cc_num7x = ((cc % 10000000000000) / 1000000000000);
long cc_num8x = ((cc % 1000000000000000) / 100000000000000);
long cc_sumx = cc_num1x + cc_num2x + cc_num3x + cc_num4x + cc_num5x + cc_num6x + cc_num7x +
cc_num8x; //adds last and everyother digit together
long sumofsums = cc_sum + cc_sumx; // adds sums of both sums created
if ((sumofsums % 10) != 0) // Luhn’s Algorithm results will close if not met
{
printf("INVALID\n");
return 0;
}
{
if (len == 15) // checks for AMEX by using length then first 2 digits
{
long ax = cc / 10000000000000;
if ((ax == 34 || ax == 37))
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
long mc = cc / 100000000000000;
long v = cc / 1000000000000000;
long v2 = cc / 1000000000000;
if (len == 16) // Checks for MC and Via (16 digits) by length then first 2 digits MC or 1 visa
{
if ((mc == 51 || mc == 52 || mc == 53 || mc == 54 || mc == 55))
{
printf("MASTERCARD\n");
}
else if (v == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
if (len == 13) //Checks 2nd Visa length 13 digits then 1st digit
{
if (v2 == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
必须有比我计划执行此操作更好的方法。长度计数循环在 10 位数字之前都很好,但随后会提取随机数。
每隔一个数字公式似乎可以通过递归完成,但我对此一无所知。由于数量最多限制为 16,因此我使用的公式似乎有效。
- 判断卡是否为15 || 16 || IF Else loop if not mark In valid in valid in if Else loop 13位数字
- 使用CC校验和公式If else循环(不满足Criteria则有效)
- 查看 2 个起始号码以确定 AX、MC 或 Visa
#include <stdio.h> #include <cs50.h> #include <string.h> int main(void) { long cc = get_long("Credit Card: " ); // gets input int len = 0; //intialized length int x = cc; // set 2nd variable = to cc to prevent manipulation of cc while(x != 0) // length count loop while x is divisable loop will continue will be stored as len { x = x/10; len++; } printf("%i\n", len); // REMOVE !!!!!!!!!!! BUG TEST //pull 2nd to last and then every other digit int cc_num1 = ((cc % 100)/10); int cc_num2 = ((cc % 10000)/1000); int cc_num3 = ((cc % 1000000)/(100000)); int cc_num4 = ((cc % 100000000)/(10000000)); int cc_num5 = ((cc % 10000000000)/(1000000000)); int cc_num6 = ((cc % 1000000000000)/(100000000000)); int cc_num7 = ((cc % 100000000000000)/(10000000000000)); int cc_num8 = ((cc % 10000000000000000)/(1000000000000000)); printf("%i %i %i %i %i %i %i %i", cc_num1, cc_num2, cc_num3, cc_num4 , cc_num5, cc_num6 , cc_num7 , cc_num8 ); }
让我们先感谢房间里的大象。
long cc = get_long("Credit Card: " );
...
int x = cc;
C 标准指定 long
至少为 32 位,而 int
必须至少为 16 位。当然,实际值取决于您的系统和您的库实现。但通常情况下,long
将 能够存储比 int
更多的位。就像这里的情况一样。这意味着“超过 10 位的数字”,本质上是太大而无法存储到 int
中的数字将导致 undefined behavior。要确切知道 system/environment 中 int
的上限是哪个数字,您可以打印 limits.h
.
INT_MAX
的值
解决方案当然是将 long
变量存储在 另一个 long
变量中,而不是 int
。或者,只需将值传递给执行必要工作的函数。现在将所有内容都放在 main 中不是很有条理是吗。
我们如何制作一个函数,根据卡号打印一张卡的所有详细信息?
签名看起来像-
void print_card_details(long num)
现在我们需要一个函数来通过 luhn 的算法来放置卡片。我们还可以为此创建一个函数-
int is_valid(long num)
{
int curr_digit, add_digit, prod_sum = 0, sum = 0;
for (int digit_count = 0; num != 0; num /= 10, digit_count++)
{
// Strip each digit from number, starting from the end
curr_digit = num % 10;
if (digit_count % 2 != 0)
{
// Every 2nd digit from the right goes through this
// The current digit gets doubled
// The digits of that result are added to the sum
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
}
else
{
// The remaining digits go through this
// They are all summed up
sum += curr_digit;
}
}
if ((prod_sum + sum) % 10 != 0)
{
// If the sum of prod_sum + sum doesn't end in 0
// It is invalid
return 0;
}
else
{
// The card is valid
return 1;
}
}
迭代一个数的数字的传统方法不是暴力地手动除10
的任意幂,而是迭代它并除以模数10。例如,这个片段-
while (x != 0)
{
printf("Current digit: %d\n", x % 10);
x /= 10;
}
将打印存储在 x
中的号码的所有数字。这基本上就是我们在 luhn 算法循环中使用的内容。除了我们还对总位数进行计数,因为我们只想要从末尾开始的每一秒数字。我们如何知道当前数字符合此标准?我们检查当前 digit_count
是否为偶数(通过除以 2 并检查剩余为 0)。
后面的公式-
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
基本上就是这个-
的实现Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
确保仅添加结果 add_digit
的 位 。因此,如果 add_digit
最终为 12。我们需要添加 1 + 2。这正是 add_digit % 10 + add_digit / 10
所做的。 12 % 10 当然是 2。而 12 / 10 是 1。
这个函数return如果卡片有效则返回 1,否则返回 0。你可以把它放在你的主要功能中,并检查 return 值以了解该卡是否有效。
如果有效,请继续下一步检查卡片的位数以及开头的数字。
我们可以做一个循环来计算数字的个数,以及存储数字的第一位和第二位。
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
这将为您提供卡号的长度。注意,在最后一次迭代中,prev_digit
的值是第二个数字,curr_digit
是第一个数字。因此 curr_digit * 10 + prev_digit
将产生信用卡号开头的前 2 个数字(一起)。
最后,你只需要一堆简单的if/else
子句来验证它是哪张卡。您也只被要求检查一个非常小的子集。所以这里是-
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && begins_with / 10 == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && begins_with == 34 ||)
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (curr_digit == 5)
{
// MASTERCARD number begins with 5
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
把这些放在一起,你应该有希望得到
void print_card_details(long num)
{
if (!is_valid(num))
{
// Card did not pass luhn's algo
printf("INVALID\n");
return;
}
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && curr_digit == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && (begins_with == 34 || begins_with == 37))
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (begins_with >= 51 && begins_with <= 55)
{
// MASTERCARD number begins with 51, 52, 53, 54, or 55
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
return;
}