What's a good way to generate a random number for a valid credit card?
Asked Answered
C

3

8

I am developing a set of tools in Java for validating and working with credit cards. So far I have support for:

  • LUHN validation.

  • Date validation (simple expiration).

  • Card code length validation (CVV, CVC, CID) based on the brand (Visa, MasterCard, etc).

  • Credit card number length validation (based on the brand).

  • BIN/IIN validation (against a database of valid numbers).

  • Hiding the digits (425010 * * * * * * 1234)

To make the tool set a bit more complete, I would like to create a credit card random number generator based on the different card brands. This functionality will (hopefully) make my test cases a bit more reliable.

Basically, I would like to be able to generate numbers which are:

  • LUHN valid

  • Valid based on the brand prefixes

  • Valid based on the BIN/IIN prefix numbers

For BIN/IIN valid card numbers, I am thinking of looking up a random BIN/IIN number from the database (based on the brand of course) and then appending the remaining digits using Random. Obviously, that would not be valid most of the time and I will have to increment one of the digits until it passes the LUHN validation.

I can't seem to be able to think of a better way. Perhaps someone could suggest something a little smarter...?

Looking forward to your suggestions! Thanks in advance! :)

Coinage answered 20/7, 2012 at 13:13 Comment(7)
Am I missing something obvious? The way I'd do it is the following: 1) Get BIN/IIN number from dtb. 2) Append a random number without the check digit (which is the last digit - so you'll make it one digit short). 2) Compute the last check digit. Voila?Tannenberg
@Slanec That's a partial solution, but don't forget that the number isn't "random", e.g. a VISA card will only have a narrow range of initial digits.Basketwork
Does this help?Clostridium
@Slanec, that would be one way, I guess.Coinage
@oers, I'm afraid I don't find that answer or the links in it too useful. Maybe I'm missing your point...?Coinage
sry I forgot some of your requirements while looking at some links :) I just thought you needed a set of dummy numbers and forgot the creating-them-myself partClostridium
@Slanec, perhaps you would like to post an answer with the example?Coinage
C
2

This functionality will (hopefully) make my test cases a bit more reliable.

I'm not convinced. In my experience, it is not a good idea to use random data in unit tests, because you never know if you've covered all of the important cases ... and bugs.

I'd recommend creating your test credit card numbers by hand, and taking care that they cover all of the cases that need to be tested.

Calamondin answered 20/7, 2012 at 15:2 Comment(3)
Well, this is what I have done currently. However, if you have card number validators, this randomness should not be a concern, but rather -- a proof that they really work.Coinage
(Hmmm ... 8 months later you upvoted and accepted my answer. Does this mean that I was right about random data not giving you good test coverage? :-) )Calamondin
Haha! No, I agreed back then. You are right that test data should be easily predictable and guarantee reproducible results. I fully agree with this. I was actually checking the questions for which I hadn't accepted answers. Cheers! ;)Coinage
S
4

Not so long ago I've authored a library called MockNeat. One of the features is to allow the developer to generate different valid credit card numbers.

Check this method: creditCards().

A short example to write 1000 Credit Cards AMEX and Mastercard in a file for later use:

 MockNeat m = MockNeat.threadLocal();
    final Path path = Paths.get("cc.txt");

// Write in a file 1000 credit cards AMEX and Mastercard:
 m.creditCards()
            .types(MASTERCARD, AMERICAN_EXPRESS)
            .list(1000)
            .consume(list -> {
                try { Files.write(path, list, CREATE, WRITE); }
                catch (IOException e) { e.printStackTrace(); }
            });
Sleety answered 29/3, 2017 at 7:7 Comment(0)
C
2

This functionality will (hopefully) make my test cases a bit more reliable.

I'm not convinced. In my experience, it is not a good idea to use random data in unit tests, because you never know if you've covered all of the important cases ... and bugs.

I'd recommend creating your test credit card numbers by hand, and taking care that they cover all of the cases that need to be tested.

Calamondin answered 20/7, 2012 at 15:2 Comment(3)
Well, this is what I have done currently. However, if you have card number validators, this randomness should not be a concern, but rather -- a proof that they really work.Coinage
(Hmmm ... 8 months later you upvoted and accepted my answer. Does this mean that I was right about random data not giving you good test coverage? :-) )Calamondin
Haha! No, I agreed back then. You are right that test data should be easily predictable and guarantee reproducible results. I fully agree with this. I was actually checking the questions for which I hadn't accepted answers. Cheers! ;)Coinage
L
2

Here goes some Groovy to generate LUHN valid Credit Cards.. I'm sure you can re-write it in your own language:

cardPrepend = "400141"
cardLength = "16"

random = new Random()
myString = ""

    (cardLength.toInteger() - cardPrepend.length()).times{
        randomNumber = random.nextInt(9)
        myString = myString + randomNumber.toString()  
    }

    myString = cardPrepend + myString

    myStringMinusLastDigit = myString.substring(0, myString.length()-1)
    mod10Digit = getMod10Digit(myStringMinusLastDigit)
    myString = myStringMinusLastDigit + mod10Digit

    return  """${myString}"""  


//-------------------------------------------------------------------------
def getMod10Digit(String number) {
    int weight = 2;
    int sum    = 0;
    for (int i = number.length() - 1; i >= 0; i--) {
        int digit = weight * Integer.parseInt(number.substring(i,i+1));
        sum = sum + (digit / 10) + (digit % 10);
        weight = (weight == 2) ? 1: 2;
    }
 
    
    return ((10 - (sum % 10)) % 10);
    }
Lovel answered 24/5, 2021 at 21:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.