想检查信用卡号是否有效

时间:2019-08-24 17:59:17

标签: c luhn

我想检查一个信用卡号是否有效,但是当我运行代码时,我输入的每个数字都无效。

下面给出的示例是我应该做的。

戴维斯签证的示例:4003600000000014。

为了便于讨论,让我们首先以其他数字加上下划线,从数字的倒数第二位开始:

4003600000000014

  1. 好的,让每个带下划线的数字乘以2:

1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2

这给了我们

2 + 0 + 0 + 0 + 0 + 12 + 0 + 8

  1. 现在,我们将这些产品的数字(即不是产品本身)加在一起:

2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13

  1. 现在,我们将该总和(13)加到未乘以2的数字总和中(从末尾开始):

13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20

  1. ,该总和(20)中的最后一位数字为0,因此David的卡是合法的!

#include <stdio.h>

int main()
{

    int no;
    printf("Visa number: ");`
    scanf("%d", &no);

    int d_1, d_2, d_3, d_4, d_5, d_6, d_7, d_8, d_9, d_10, d_11, d_12, d_13, d_14, d_15;

    d_15 = no%10;
    d_14 = ((no%100)/10)*2;
    d_13 = (no%1000)/100;
    d_12 = ((no%10000)/1000)*2;
    d_11 = (no%100000)/10000;
    d_10 = ((no%1000000)/100000)*2;
    d_9 = (no%10000000)/1000000;
    d_8 = ((no%100000000)/10000000)*2;
    d_7 = (no%1000000000)/100000000;
    d_6 = ((no%10000000000)/1000000000)*2;
    d_5 = (no%100000000000)/10000000000;
    d_4 = ((no%1000000000000)/100000000000)*2;
    d_3 = (no%10000000000000)/1000000000000;
    d_2 = ((no%100000000000000)/10000000000000)*2;
    d_1 = (no%1000000000000000)/100000000000000;

    int d[7] = {d_2, d_4, d_6, d_8, d_10, d_12, d_14};

    int n,add;

    for (n=1; n<=7; n++)
        if(d[n]>10)
        {
            d[n] = (d[n]%10);
            d[(15-n)+1] = ((d[n]%100)/10);
            int sum=0;
            for (int i=0; i<7; i++)
                sum += d[i];
        }
        else
        {
            add = d_14 + d_12 + d_10 + d_8 + d_6 + d_4 + d_2;
        }

    int sum = add + d_15 + d_13 + d_11 + d_9 + d_7 + d_5 + d_3 + d_1;

    if ((sum % 10) == 0)
    {
        printf("%s\n", "The card is valid");
    }
    else
    {
        printf("%s\n", "The card is invalid");
    }
}

2 个答案:

答案 0 :(得分:2)

  

我输入的每一个数字,输出都是无效的。

太大

OP的select * , sum(val) over (partition by user_id) as res , sum(val) over (partition by user_id order by ts) as res_order_by , sum(val) over ( partition by user_id order by ts rows between unbounded preceding and current row ) as res_order_by_unbounded_preceding , sum(val) over ( partition by user_id -- order by ts rows between unbounded preceding and current row ) as res_preceding , sum(val) over ( partition by user_id -- order by ts rows between current row and unbounded following ) as res_following , sum(val) over ( partition by user_id order by ts rows between unbounded preceding and unbounded following ) as res_orderby_preceding_following from example_table; 可能是32位。

读取试图在int范围之外形成int的文本输入是未定义行为。其余代码无关紧要。

int

请考虑先将用户输入内容读入 string ,然后再处理字符。 @Weather Vane

int no;
scanf("%d", &no);  // attempt to read "4003600000000014" leads to UB.

答案 1 :(得分:0)

#include <stdio.h>
#include <cs50.h>

long credit;

int getting_the_final_total_number (void);
void checking_which_kind (void);

int main(void)
{
   credit = get_long("Number: ");

   int i = 0;
   long number_count = credit;

   //finding how many numbers are there.
   while(number_count > 0)
   {
      number_count /= 10;
      i++;
   }

   //we use and because (using or make once true, the code block will work and always telling INVALID)

   if(i != 13 && i != 15 && i != 16)
   {
      printf("INVALID\n");
      return 0;
   }

   
   int total = getting_the_final_total_number(); //adding sum_1 and sum_2


   if(total % 10 != 0)
   {
      printf("INVALID\n");
      return 0;
   }

   checking_which_kind();

}

//assigning the credit to another variable for the loop
int getting_the_final_total_number (void)
{
   long credit_one = credit;

   int mod_1;
   int mod_2;

   int sum_1 = 0;

   int m;
   int d;
   int sum_2 = 0;

   do
   {
      //cutting the number into two pieces with all the last numbers and all the second-last-numbers

      //cutting the last numbers.
      mod_1 = credit_one % 10;
      credit_one = credit_one / 10;

      sum_1 += mod_1;

      //cutting the second-last-numbers.
      mod_2 = credit_one % 10;
      credit_one = credit_one / 10;

      //doubling the mod_2 (the second-last-numbers)
      mod_2 = mod_2 * 2;

      //making them into one number (if there is 16 or 18 in the product then make them 1 and 6 or 1 and 8. After that add them all together ).

      m = mod_2 % 10;  //This is for only one standing numer like 1 or 2 or 9 etc (but no 12 or 14 or 16)
      d = mod_2 / 10;    //This is for ten's digit to make sure to become ONE standing digit

      sum_2 = sum_2 + m + d;
   }
   while(credit_one > 0);

   return sum_1 + sum_2;
}

 //checking the first two number of credit
void checking_which_kind (void)
{
   long cc = credit;

   do
   {
    cc = cc / 10;
   }
   while(cc > 100);

   if(cc / 10 == 5 && (cc % 10 > 0 || cc % 10 < 6))
   {
      printf("MASTERCARD\n");
   }
   else if(cc / 10 == 3 && (cc % 10 == 4 || cc % 10 == 7))
   {
      printf("AMERICAN EXPRESS\n");
   }
   else if(cc / 10 == 4 && cc % 10 >= 0)
   {
      printf("VISA\n");
   }
   else
   {
      printf("ERROR");
   }
}