使用luhn算法验证信用卡号

时间:2013-12-22 02:49:09

标签: java arrays validation credit-card luhn

我对以下编程任务有疑问。

信用卡号码遵循某些模式。信用卡必须在13到16位之间。它必须以:

开头

•4张Visa卡

•5张万事达卡

•美国运通卡37张

1954年,IBM的Hans Luhn提出了一种验证信用卡号码的算法。该算法可用于确定是否正确输入了卡号或扫描仪是否正确扫描了信用卡。几乎所有信用卡号都是在此有效性检查后生成的,通常称为Luhn检查或模数10检查,可以描述如下。例如,请考虑卡号4388576018402625。

  1. 从右到左加倍每秒。如果数字加倍会产生2位数字,请将两位数相加得到一位数字。
  2. 2 x 2 = 4

    2 x 2 = 4

    4 x 2 = 8

    1 x 2 = 2

    6 x 2 = 12(1 + 2 = 3)

    5 x 2 = 10(1 + 0 = 1)

    8 x 2 = 16(1 + 6 = 7)

    4 x 2 = 8

    1. 添加步骤1中的所有单个数字 4 + 4 + 8 + 2 + 3 + 1 + 7 + 8 = 37

    2. 在卡号

    3. 中添加从右到左奇数位的所有数字

      5 + 6 + 0 + 8 + 0 + 7 + 8 + 3 = 37

      1. 总结步骤2和步骤3的结果 37 + 37 = 74

      2. 如果步骤的结果可被10整除,则卡号有效;否则,它无效。例如,号码4388576018402625无效,但号码4388576018410707是有效的Visa卡;号码6011000593748745无效,但号码6011000593748746是一张有效的Discover卡。

      3. 我尝试解决它,如下面的代码所示:

        import java.util.Scanner;
        
        public class CreditCardValidation {
        
            public static boolean isValid(long number) {
        
                int total = sumOfDoubleEvenPlace(number) + sumOfOddPlace(number);
        
        
                if ((total % 10 == 0) && (prefixMatched(number, 1) == true) && (getSize(number)>=13 ) && (getSize(number)<=16 )) {
                    return true;
                } else {
                    return false;
                }
            }
        
            public static int getDigit(int number) {
        
                if (number <= 9) {
                    return number;
                } else {
                    int firstDigit = number % 10;
                    int secondDigit = (int) (number / 10);
        
                    return firstDigit + secondDigit;
                }
            }
            public static int sumOfOddPlace(long number) {
                int result = 0;
        
                while (number > 0) {
                    result += (int) (number % 10);
                    number = number / 100;
                }
        
                return result;
            }
        
            public static int sumOfDoubleEvenPlace(long number) {
        
                int result = 0;
                long temp = 0;
        
                while (number > 0) {
                    temp = number % 100;
                    result += getDigit((int) (temp / 10) * 2);
                    number = number / 100;
                }
        
                return result;
            }
        
            public static boolean prefixMatched(long number, int d) {
        
                if ((getPrefix(number, d) == 4)
                        || (getPrefix(number, d) == 5)
                        || (getPrefix(number, d) == 3)) {
        
                    if (getPrefix(number, d) == 3) {
                        System.out.println("\nVisa Card ");
                    } else if (getPrefix(number, d) == 5) {
                        System.out.println("\nMaster Card ");
                    } else if (getPrefix(number, d) == 3) {
                        System.out.println("\nAmerican Express Card ");
                    }
        
                    return true;
        
                } else {
        
                    return false;
        
                }
            }
        
            public static int getSize(long d) {
        
                int count = 0;
        
                while (d > 0) {
                    d = d / 10;
        
                    count++;
                }
        
                return count;
        
            }
        
            public static long getPrefix(long number, int k) {
        
                if (getSize(number) < k) {
                    return number;
                } else {
        
                    int size = (int) getSize(number);
        
                    for (int i = 0; i < (size - k); i++) {
                        number = number / 10;
                    }
        
                    return number;
        
                }
        
            }
        
            public static void main(String[] args) {
        
                Scanner sc = new Scanner(System.in);
        
                System.out.print("Enter a credit card number as a long integer: ");
        
                long input = sc.nextLong();
        
        
                if (isValid(input) == true) {
                    System.out.println("\n" + input + " is Valid. ");
                } else {
                    System.out.println("\n" + input + " is Invalid. ");
                }
        
            }
        } 
        

        我的问题是如何使用数组来存储信用卡号而不是使用长号码。

4 个答案:

答案 0 :(得分:1)

int分割为List<Integer>

有两种方法
  1. 在使用时使用%10并将其存储到List
  2. 转换为String,然后取数值
  3. 以下是几个简单的例子

    public static void main(String[] args) throws Exception {
        final int num = 12345;
        final List<Integer> nums1 = splitInt(num);
        final List<Integer> nums2 = splitString(num);
        System.out.println(nums1);
        System.out.println(nums2);
    }
    
    private static List<Integer> splitInt(int num) {
        final List<Integer> ints = new ArrayList<>();
        while (num > 0) {
            ints.add(0, num % 10);
            num /= 10;
        }
        return ints;
    }
    
    private static List<Integer> splitString(int num) {
        final List<Integer> ints = new ArrayList<>();
        for (final char c : Integer.toString(num).toCharArray()) {
            ints.add(Character.getNumericValue(c));
        }
        return ints;
    }
    

答案 1 :(得分:1)

这是luhn算法实现,我只使用16位信用卡号

if(ccnum.length()==16){
    char[] c = ccnum.toCharArray();
    int[] cint = new int[16];
    for(int i=0;i<16;i++){
        if(i%2==1){
            cint[i] = Integer.parseInt(String.valueOf(c[i]))*2;
            if(cint[i] >9)
                cint[i]=1+cint[i]%10;
        }
        else
            cint[i] = Integer.parseInt(String.valueOf(c[i]));
    }
    int sum=0;
    for(int i=0;i<16;i++){
        sum+=cint[i];
    }
    if(sum%10==0)
        result.setText("Card is Valid");
    else
        result.setText("Card is Invalid");
}else
    result.setText("Card is Invalid");

如果你想在任何数字上使用它,请用你的输入数字长度替换所有16个。

它适用于问题中给出的签证号码。(我测试过)

答案 2 :(得分:1)

好的,这可以通过字符串转换和一些Java 8来解决 东西。不要忘记数字,代表数字的字符也不一样。 '1'!= 1

<html>
<head lang="en">
<meta charset="UTF-8">
<title>DnB Timesheet Management</title>
<!-- Style sheets -->
<link href="Content/bootstrap.css" rel="stylesheet" />
</head>
<body ng-app="timesheetManagement">
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <div class="navbar-header">
            <div class="navbar-brand">DnB Timesheet Management</div>
        </div>
    </div>
</nav>
<div class="container">
    <div ui-view></div>
    <!--<div ng-include="'app/timesheets/timesheetListView.html'"></div>-->
</div>
<!-- Library Scripts -->
<script src="scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script src="Scripts/angular-ui-router.js"></script>
<!-- Application Script -->
<script src="app/app.js"></script>
<!-- Services -->
<script src="common/common.services.js"></script>
<script src="common/timesheetResource.js"></script>
<!-- Product Controllers -->
<script src="app/timesheets/timesheetListCtrl.js"></script>
<script src="app/timesheets/timesheetEditCtrl.js"></script>
</body>
</html>

您现在可以使用此方法执行luhn算法:

public static int[] longToIntArray(long cardNumber){

return Long.toString(cardNumber).chars()
    .map(x -> x - '0') //converts char to int 
    .toArray();  //converts to int array
}

答案 3 :(得分:0)

public class Creditcard {

    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        String cardno = sc.nextLine();

        if(checkType(cardno).equals("U")) //checking for unknown type
          System.out.println("UNKNOWN");
        else
          checkValid(cardno); //validation 
}

private static String checkType(String S)
{
    int AM=Integer.parseInt(S.substring(0,2));
    int D=Integer.parseInt(S.substring(0,4)),d=0;
    for(int i=S.length()-1;i>=0;i--)
    {
        if(S.charAt(i)==' ')
            continue;
        else
            d++;
    }
    if((AM==34 || AM==37) && d==15)
        System.out.println("AMEX");
    else if(D==6011 && d==16)
        System.out.println("Discover");
    else if(AM>=51 && AM<=55 && d==16)
        System.out.println("MasterCard");
    else if(((S.charAt(0)-'0')==4)&&(d==13 || d==16)) 
        System.out.println("Visa");
    else
        return "U";
    return "";
}

private static void checkValid(String S) // S--> cardno
{
    int i,d=0,sum=0,card[]=new int[S.length()];

    for(i=S.length()-1;i>=0;i--)
    {
        if(S.charAt(i)==' ')
            continue;
        else
            card[d++]=S.charAt(i)-'0';
    }

    for(i=0;i<d;i++)
    {
        if(i%2!=0)
        {
            card[i]=card[i]*2;
            if(card[i]>9)
                sum+=digSum(card[i]);
            else
                sum+=card[i];
        }
        else
            sum+=card[i];
    }
    if(sum%10==0)
        System.out.println("Valid");
    else    
        System.out.println("Invalid");

}

public static int digSum(int n)
{
    int sum=0;
    while(n>0)
    {
        sum+=n%10;
        n/=10;
    }
    return sum;
}
}