Created
August 15, 2016 19:32
-
-
Save joncardasis/910c565a7b877df2e5e1eff3d30a9e42 to your computer and use it in GitHub Desktop.
A Swift playground to generate valid credit card numbers for testing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
enum CreditCardType{ | |
case Visa | |
case Visa13Digit | |
case MasterCard | |
case Discover | |
case AmericanExpress | |
case DinersClubUSA | |
case DinersClubCanada | |
case DinersClubInternational | |
case DinersClubCarteBlanche | |
case JCB | |
} | |
func generateCreditCardNumber(for type: CreditCardType) -> String{ | |
/* Obtain proper card length */ | |
var cardLength = (type == .Visa13Digit) ? 13 : 16 | |
cardLength = (type == .AmericanExpress) ? 15 : cardLength | |
cardLength = (type == .DinersClubInternational || type == .DinersClubCarteBlanche) ? 14 : cardLength | |
var cardNumber = [Int](count: cardLength, repeatedValue: 0) | |
var startingIndex = 0 | |
/* Conform to rules for beginning card numbers */ | |
if type == .Visa || type == .Visa13Digit { | |
cardNumber[0] = 4 | |
startingIndex = 1 | |
} | |
else if type == .MasterCard { | |
cardNumber[0] = 5 | |
cardNumber[1] = Int(arc4random_uniform(5) + 1) | |
startingIndex = 2 | |
} | |
else if type == .Discover { | |
cardNumber.replaceRange(Range(0...3), with: [6,0,1,1]) | |
startingIndex = 4 | |
} | |
else if type == .AmericanExpress { | |
cardNumber.replaceRange(Range(0...1), with: [3,4]) | |
startingIndex = 2 | |
} | |
else if type == .DinersClubUSA || type == .DinersClubCanada { | |
//Will most often pass as a master card because of the 54 | |
cardNumber.replaceRange(Range(0...1), with: [5,4]) | |
startingIndex = 2 | |
} | |
else if type == .DinersClubInternational { | |
cardNumber.replaceRange(Range(0...1), with: [3,6]) | |
startingIndex = 2 | |
} | |
else if type == .DinersClubCarteBlanche { | |
cardNumber.replaceRange(Range(0...2), with: [3,0,0]) | |
startingIndex = 3 | |
} | |
else if type == .JCB { | |
cardNumber.replaceRange(Range(0...3), with: [3,5,2,8]) | |
startingIndex = 4 | |
} | |
/* Fill array with random numbers 0-9 */ | |
for i in startingIndex..<cardNumber.count{ | |
cardNumber[i] = Int(arc4random_uniform(10)) | |
} | |
/* Calculate the final digit using a custom variation of Luhn's formula | |
This way we dont have to spend time reversing the array | |
*/ | |
let offset = (cardNumber.count+1)%2 | |
var sum = 0 | |
for i in 0..<cardNumber.count-1 { | |
if ((i+offset) % 2) == 1 { | |
var temp = cardNumber[i] * 2 | |
if temp > 9{ | |
temp -= 9 | |
} | |
sum += temp | |
} | |
else{ | |
sum += cardNumber[i] | |
} | |
} | |
let finalDigit = (10 - (sum % 10)) % 10 | |
cardNumber[cardNumber.count-1] = finalDigit | |
//Convert cardnumber array to string | |
return cardNumber.map({ String($0) }).joinWithSeparator("") | |
} | |
//----------MAIN-----------// | |
let cardNumber = generateCreditCardNumber(for: .MasterCard) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated for Swift 5