3

クレジットカード番号を検証するプログラムを書いていますが、Luhn のアルゴリズムを使用する必要があります。前もって言っておきますが、私はプログラミングを学び始めたばかりなので (先週のようにループについて説明しました)、慣れていないことがたくさんあります。算術をチェックする関数の 1 つに問題があります。基本的に、右から左に 1 桁ごとに 2 倍にして、すべてを足し合わせる必要があります。しかし、5 のように数を 2 倍して 10 になる場合、合計に 10 ではなく 1+0=1 を追加する必要があります。どうすればそれをプログラムに入れることができますか?

これまでのサンプルコード:

int 
doubleEvenSum(string creditCardNumber) {
  int evenSum; 
  int countPosition; 
  int doublePosition; 
  int length;

  length = creditCardNumber.length (); 
  countPosition = creditCardNumber.at(length - 2); 
  evenSum = 0; 
  while(countPosition>0) { 
    if ((2 * countPosition) < 10) { 
      doublePosition = 2 * countPosition; 
    } 
    else if ((2 * countPosition) > 9) { 
      ??? 
    } 
    evenSum = evenSum + doublePosition; 
  }
4

4 に答える 4

1
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
    return the Luhn (MOD10) checksum for a sequence of digits.

    -1 is returned on error (a non-digit was in the sequence 

 */

int mod10( char const* s)
{
    int len = strlen(s);
    int sum = 0;

    int dbl = 0;

    while (len) {
        char digit;
        int val;

        --len;
        digit = s[len];

        if (!isdigit( (unsigned char) digit)) return -1;    // non digit in the sequence

        val = digit - '0';  // convert character to numeric value

        if (dbl) {
            // double the value
            val *= 2;

            // if the result is double-digits, add the digits together
            if (val > 9) {
                val = val - 10;
                val = val + 1;
            }
        }

        dbl = !dbl; // only double value every other time

        sum += val;
    }

    return sum % 10;
}
于 2012-10-20T05:38:23.790 に答える
1

ここに別のアルゴリズムがあります。C# の例から切り取って貼り付けました。2 番目のリンクでは、Luhn のさまざまな最適化について説明しています。

この例を調べて、デバッガーで実行して、実行中のコードの動作を調べてください。コードが実際にどのように実行されるか (コードを書いたときにどのように実行されると考えるかではなく) を理解することは、不可欠なスキルです。私見では....

/*
 * Validate credit card with Luhn Algorithm
 *
 * REFERENCES:
 * - http://jlcoady.net/c-sharp/credit-card-validation-in-c-sharp
 * - http://orb-of-knowledge.blogspot.com/2009/08/extremely-fast-luhn-function-for-c.html
 */
#include <stdio.h>   // printf(), scanf(), etc
#include <string.h>  // strlen (), etc
#include <ctype.h>   // isdigit(), etc
#if !defined(FALSE)
  #define FALSE 0
  #define TRUE ~FALSE
#endif

/*
 * type definitions (should go in separate header)
 */
enum CardType {
  MASTERCARD=1, BANKCARD=2, VISA=3, AMEX=4, DISCOVER=5, DINERS=6, JCB=7
};

/*
 * function prototypes (should also go in header)
 */
int luhn (int number[], int len);
bool validate (CardType cardType, char *cardNumber);

/*
 * program main
 */
int
main (int argc, char *argv[])
{
  char cc_number[80];
  int cc_type;
  for ( ;; ) {
    printf ("Enter a credit card number and type (1, 2, 3, 4, 5. 6 or 7):\n");
    printf ("  MASTERCARD=1, BANKCARD=2, VISA=3, AMEX=4, DISCOVER=5, DINERS=6, JCB=7\n");
    int iret = scanf ("%s %d", cc_number, &cc_type);
    if (iret == 2)
      break;
    else
      printf ("Incorrect input: please enter a valid CC# and CC type\n");
  }
  if (validate ((CardType)cc_type, cc_number))
    printf ("Valid\n");
  else
    printf ("Invalid card type/number\n");
  return 0;
}


/*
 * validate card#
 */
bool
validate (CardType cardType, char *cardNumber)
{
  // 16 or fewer digits?
  int len = strlen(cardNumber);
  if (strlen (cardNumber) > 16)
    return false;

  // number to validate
  int number[16]; 
  for(int i = 0; i < (int)strlen (cardNumber); i++) {
    if(!isdigit(cardNumber[i]))
      return FALSE;
    number[i] = cardNumber[i] - '0';
  }

  // Validate based on card type, first if tests length, second tests prefix
  switch(cardType)  {
    case MASTERCARD:
      if(len != 16)
        return FALSE;
      if(number[0] != 5 || number[1] == 0 || number[1] > 5)
        return FALSE;
      break;

    case BANKCARD:
      if(len != 16)
        return FALSE;
      if(number[0] != 5 || number[1] != 6 || number[2] > 1)
        return FALSE;
      break;

    case VISA:
      if(len != 16 && len != 13)
        return FALSE;
      if(number[0] != 4)
        return FALSE;
      break;

    case AMEX:
      if(len != 15)
        return FALSE;
      if(number[0] != 3 || (number[1] != 4 && number[1] != 7))
        return FALSE;
      break;

    case DISCOVER:
      if(len != 16)
        return FALSE;
      if(number[0] != 6 || number[1] != 0 || number[2] != 1 || number[3] != 1)
        return FALSE;
      break;

    case DINERS:
      if(len != 14)
        return FALSE;
      if(number[0] != 3 || (number[1] != 0 && number[1] != 6 && number[1] != 8) || number[1] == 0 && number[2] > 5)
        return FALSE;
      break;

    case JCB:
      if(len != 16 && len != 15)
        return FALSE;
      if(number[0] != 3 || number[1] != 5)
        return FALSE;
      break;
    default:
      return FALSE;
  }

  int sum = luhn (number, len);
  return (sum % 10 == 0);
}


// Use Luhn Algorithm to validate
int luhn (int number[], int len)
{
  int sum = 0;
  for(int i = len - 1; i >= 0; i--)
  {
    if(i % 2 == len % 2)
    {
      int n = number[i] * 2;
      sum += (n / 10) + (n % 10);
    }
    else
      sum += number[i];
  }
  return sum;
}
于 2012-10-20T19:54:54.427 に答える
0
int luhnCardValidator(char cardNumbers[]) {
    int sum = 0, nxtDigit, i;
    for (i = 0; cardNumbers[i] != NULL_TERMINATOR ; i++) {
         nxtDigit = cardNumbers[i] - START_OF_ASCII_NUMERIC;
        if (i % 2 == 0) 
          nxtDigit  = (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2;
        sum += nxtDigit;
    }
    return (sum % 10);
}

これ:

... (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : ...

賢いビットです。数字が 4 より大きい場合、倍増は 10 以上になります。その場合、2 倍の数を取り、10 を引くと 1 の桁になり、1 を足します (10 の桁)。

于 2016-02-15T22:49:30.710 に答える