有人可以解释为什么我的 luhn 算法失败了吗?
Can someone explain why my luhn's algo fails?
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <cs50.h>
short unsigned int numlen(unsigned long long n);
bool isValidCC(unsigned long long int n);
unsigned short int first_n_nums(unsigned short int n, unsigned short int x);
int main(void)
{
unsigned long long num = 0;
num = get_long("Enter your card number ");
if(numlen(num) == 15 && (first_n_nums(num, 2) == 34 || first_n_nums(num, 2) == 37) && isValidCC(num) == true)
{
printf("AMEX\n");
}
else if((numlen(num) == 13 || numlen(num) == 16) && first_n_nums(num, 1) == 4 && isValidCC(num) == true)
{
printf("VISA\n");
}
else if(numlen(num) == 16 && (first_n_nums(num, 2) == 51 || first_n_nums(num, 2) == 52 || first_n_nums(num, 2) == 53 || first_n_nums(num, 2) == 54 || first_n_nums(num, 2) == 55) && isValidCC(num) == true)
{
printf("MASTERCARD\n");
}
else
{
printf("INVALID\n");
}
}
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
{
while(n > pow(10,x))
{
n /= 10;
}
return n;
}
short unsigned int numlen(unsigned long long n)
{
short unsigned int count = 0;
while (n !=0)
{
n /= 10; //removes last digit
count++; //counts the num of digits removed
}
return count;
}
bool isValidCC(unsigned long long int n)
{
// take user input and add elements to array in reverse
int arr1[(numlen(n))]; // declares but can't Initialize an array of n ;
for (int i = 0; i < (int)sizeof(arr1)/sizeof(int) ; i++)
{
arr1[i] = 0;
}
for (int i = 0 ; i <(int) (sizeof(arr1)/sizeof(int)) ; i++)
{
arr1[i] = n % 10; //Appends last digit to an array
n /= 10; // removes that last digit
}
// since arr1 = x digits long, arr2 is every second digit so its x/2 long
int arr2[((sizeof(arr1)/sizeof(int))*2)];
//initializing garbage data to 0
for (int i = 0; i < sizeof(arr2)/sizeof(int) ; i++)
{
arr2[i] = 0;
}
// multiplies, seperates, and sums arr2 elements
int sum_of_arr2 = 0;
for (int i = 1, a = 0, b = 0 ; i < (sizeof(arr1)/sizeof(int)) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
{
a = arr1[i] * 2;
if( a > 9)
{
b = a % 10;
a /= 10;
arr2[i] = b;
sum_of_arr2 += b;
}
arr2[i-1] = a; // cz i currenrly is one idex ahead
sum_of_arr2 += a;
}
// adds other elements of arr1 to sum_of_arr2
for (int i = 0 ; i < (sizeof(arr1)/4) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
{
sum_of_arr2 += arr1[i];
}
// returns true or false
if (sum_of_arr2 % 10 != 0)
{
return false;
}
else
{
return true;
}
}
有人可以解释为什么这对以下值失败:
371449635398431 - 应为“AMEX\n”,而不是“INVALID\n”
5555555555554444 - 应为“MASTERCARD\n”,而不是“INVALID\n”
5105105105105100- 应为“MASTERCARD\n”,而不是“VISA\n”
4111111111111111 - 应为“VISA\n”,而不是“INVALID\n”
4222222222222 - 应为“VISA\n”,而不是“INVALID\n”
你的问题出在你的函数上
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
您传递的是 unsigned short int
而不是 unsigned long long
,因此您可以只获取 unsigned short int
的最大值而不是实际值。
输出:
371449635398431 - "AMEX\n"
5555555555554444 - "MASTERCARD\n"
5105105105105100- "MASTERCARD\n"
4111111111111111 - "INVALID\n" - Note that the output you said you were expecting is incorrect because the input length is 14 instead of 13.
4222222222222 - "VISA\n"
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <cs50.h>
short unsigned int numlen(unsigned long long n);
bool isValidCC(unsigned long long int n);
unsigned short int first_n_nums(unsigned short int n, unsigned short int x);
int main(void)
{
unsigned long long num = 0;
num = get_long("Enter your card number ");
if(numlen(num) == 15 && (first_n_nums(num, 2) == 34 || first_n_nums(num, 2) == 37) && isValidCC(num) == true)
{
printf("AMEX\n");
}
else if((numlen(num) == 13 || numlen(num) == 16) && first_n_nums(num, 1) == 4 && isValidCC(num) == true)
{
printf("VISA\n");
}
else if(numlen(num) == 16 && (first_n_nums(num, 2) == 51 || first_n_nums(num, 2) == 52 || first_n_nums(num, 2) == 53 || first_n_nums(num, 2) == 54 || first_n_nums(num, 2) == 55) && isValidCC(num) == true)
{
printf("MASTERCARD\n");
}
else
{
printf("INVALID\n");
}
}
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
{
while(n > pow(10,x))
{
n /= 10;
}
return n;
}
short unsigned int numlen(unsigned long long n)
{
short unsigned int count = 0;
while (n !=0)
{
n /= 10; //removes last digit
count++; //counts the num of digits removed
}
return count;
}
bool isValidCC(unsigned long long int n)
{
// take user input and add elements to array in reverse
int arr1[(numlen(n))]; // declares but can't Initialize an array of n ;
for (int i = 0; i < (int)sizeof(arr1)/sizeof(int) ; i++)
{
arr1[i] = 0;
}
for (int i = 0 ; i <(int) (sizeof(arr1)/sizeof(int)) ; i++)
{
arr1[i] = n % 10; //Appends last digit to an array
n /= 10; // removes that last digit
}
// since arr1 = x digits long, arr2 is every second digit so its x/2 long
int arr2[((sizeof(arr1)/sizeof(int))*2)];
//initializing garbage data to 0
for (int i = 0; i < sizeof(arr2)/sizeof(int) ; i++)
{
arr2[i] = 0;
}
// multiplies, seperates, and sums arr2 elements
int sum_of_arr2 = 0;
for (int i = 1, a = 0, b = 0 ; i < (sizeof(arr1)/sizeof(int)) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
{
a = arr1[i] * 2;
if( a > 9)
{
b = a % 10;
a /= 10;
arr2[i] = b;
sum_of_arr2 += b;
}
arr2[i-1] = a; // cz i currenrly is one idex ahead
sum_of_arr2 += a;
}
// adds other elements of arr1 to sum_of_arr2
for (int i = 0 ; i < (sizeof(arr1)/4) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
{
sum_of_arr2 += arr1[i];
}
// returns true or false
if (sum_of_arr2 % 10 != 0)
{
return false;
}
else
{
return true;
}
}
有人可以解释为什么这对以下值失败:
371449635398431 - 应为“AMEX\n”,而不是“INVALID\n”
5555555555554444 - 应为“MASTERCARD\n”,而不是“INVALID\n”
5105105105105100- 应为“MASTERCARD\n”,而不是“VISA\n”
4111111111111111 - 应为“VISA\n”,而不是“INVALID\n”
4222222222222 - 应为“VISA\n”,而不是“INVALID\n”
你的问题出在你的函数上
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
您传递的是 unsigned short int
而不是 unsigned long long
,因此您可以只获取 unsigned short int
的最大值而不是实际值。
输出:
371449635398431 - "AMEX\n"
5555555555554444 - "MASTERCARD\n"
5105105105105100- "MASTERCARD\n"
4111111111111111 - "INVALID\n" - Note that the output you said you were expecting is incorrect because the input length is 14 instead of 13.
4222222222222 - "VISA\n"