【问题标题】:MOD10 Credit card validationMOD10 信用卡验证
【发布时间】:2012-08-14 19:54:03
【问题描述】:
  • 第 1 步:从右数第二位开始,将卡号交替数字的值加倍。
  • 第 2 步:将第 1 步中获得的单个数字与原始数字中的每个未受影响的数字相加。
  • 第三步:如果第二步得到的总数能被10整除,则卡号有效,否则无效。

例如使用 Mod 10 算法验证 VISA 卡 49977393716 的卡号:

第 1 步:

4 9 9 7 7 3 9 3 7 1 6
  x2  x2  x2  x2  x2

= 18 14 6 6 2

第二步:4 + (1+8) + 9 + (1+4) + 7 + (6) + 9 + (6) + 7 + (2) + 6 = 70

第三步:70能被10整除⇒卡号有效

这是问题的第二部分。所以我将卡号用户输入作为字符串。这是否意味着我必须 charAt(),需要的字符//替代值。

     int[] digits = new int[cardNo.length()/2];//Number of alternate values available
        char digit1;
        char digit2;
        int intDigit1;
        int intDigit2;
        int[] sumOfTwoDigits = new int[cardNo.length()/2];
        int totalSum;
        String digitsChar;

 for(int i=0; i<digits.length; i++){             
            digits[i]=(cardNo.charAt(i+1))*2; 
            digitsChar=Integer.toString(digits[i]);
            digit1= digitsChar.charAt(1);
            digit2= digitsChar.charAt(2);
            intDigit1= Character.getNumericValue(digit1);//Convert char to int to perform addition
            intDigit2= Character.getNumericValue(digit2);//Convert char to int to perform addition

            sumOfTwoDigits[i] = intDigit1+intDigit2;
            System.out.println("digits: " + intDigit1);

        }

【问题讨论】:

  • 它们运行但逻辑中的某个地方是错误的。我每次迭代都得到 0
  • 这是什么语言? @leppie 这不是 javascript。
  • @some: 糟糕,没有注意到System.out.println ;p 所以java!
  • 哦,我不知道这是算法,所以00000000000是一个有效的CC号码?
  • @dualed 从技术上讲,00000000000 是有效的,因为它具有正确的校验和。但是,如果它被排除在标准的某个地方,我不会感到惊讶。它通常用于表示没有输入数字。因此,永远不会有一个帐户附加到该卡号。请记住,Luhn 算法的目的是检测数字是否输入错误。要验证卡是否有效,您必须在线与发卡机构核实。

标签: java validation credit-card


【解决方案1】:

几点建议:

  • 您应该从数字序列的右侧结束开始,向左工作。信用卡号中的最后一位数字(如果是校验位)。有些信用卡的位数是奇数,有些信用卡的位数是偶数。从字符串的“右”端开始是确保将正确数字加倍的一种方法。
  • 有些信用卡使用奇数位数这一事实意味着您不能依赖在每个循环中处理两个字符(至少在没有对奇数剩余字符进行特殊情况处理的情况下)。
  • 当您将一位数字加倍时,如果您最终得到大于 10 的结果,您需要在将结果折叠到校验和之前从结果中减去 9(实际上是将两位数相加)。

【讨论】:

    【解决方案2】:

    我的 java 有点生锈了,但我们开始吧:

    public static boolean luhnVerify(String str) {
      int sum = 0;
      int value;
      int idx = str.length(); // Start from the end of string
      boolean alt = false;
    
      while(idx-- > 0) {
        // Get value. Throws error if it isn't a digit
        value = Integer.parseInt(str.substring(idx, idx + 1));
        if (alt) {
          value *= 2;
          if (value > 9) value -= 9;
        }
        sum += value;
        alt = !alt;  //Toggle alt-flag
      }
      return (sum % 10) == 0;
    }
    

    Luhn algorithm 从右端开始,然后每隔一个数字乘以 2 并相加。

    1. 在上面的代码中,我使用Integer.parseInt(str.substring(idx,idx+1)) 从字符串中获取每个数字。如果不是数字,则会引发错误。
    2. 在那里我检查alt-标志,如果是真的,我将值乘以2。如果结果大于9,我减去9。这与添加1+[0-8]的结果相同。
    3. 我将值添加到总和并切换alt-flag。
    4. 如果总和能被 10 整除,则结果为真。

    【讨论】:

      【解决方案3】:

      我已经尝试编写代码来实现我猜你的意图:

      String cardNo = "49977393716";
      int[] digits = new int[cardNo.length()/2]; //Number of alternate values available
      int[] sumOfTwoDigits = new int[cardNo.length()/2];
      
      for(int i=0; i<digits.length; i++){ 
              //get the numeric value of the char, instead of the int representation            
              digits[i]=Character.getNumericValue(cardNo.charAt(2*i+1))*2;
      
              //using Michael Burr's trick
              sumOfTwoDigits[i] = digits[i] >= 10 ? digits[i] - 9 : digits[i]; 
      }
      

      您遇到了麻烦,因为您将char 分配给int[] 中的一个位置,因此使用了char 的int 表示。因此,对digitsChar[2] 的调用没有失败(它总是应该失败,因为任何数字的双精度数都不能超过两位数,其中一半只有一位数),因为双倍的int 表示数字chars 都有三位数。

      【讨论】:

        猜你喜欢
        • 2014-08-14
        • 2011-01-24
        • 2017-04-02
        • 2016-11-15
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 2014-08-03
        相关资源
        最近更新 更多