__init__.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # coding=utf-8
  2. from __future__ import unicode_literals
  3. from collections import OrderedDict
  4. from .. import BaseProvider
  5. class CreditCard(object):
  6. def __init__(
  7. self,
  8. name,
  9. prefixes,
  10. length=16,
  11. security_code='CVC',
  12. security_code_length=3):
  13. self.name = name
  14. self.prefixes = prefixes
  15. self.length = length
  16. self.security_code = security_code
  17. self.security_code_length = security_code_length
  18. class Provider(BaseProvider):
  19. # Prefixes from:
  20. # * https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_.28IIN.29
  21. # * https://www.regular-expressions.info/creditcard.html
  22. # * https://creditcardjs.com/credit-card-type-detection
  23. prefix_maestro = ['5018', '5020', '5038', '56##', '57##', '58##',
  24. '6304', '6759', '6761', '6762', '6763', '0604', '6390']
  25. prefix_mastercard = ['51', '52', '53', '54', '55', '222%']
  26. prefix_visa = ['4']
  27. prefix_amex = ['34', '37']
  28. prefix_discover = ['6011', '65']
  29. prefix_diners = ['300', '301', '302', '303', '304', '305', '36', '38']
  30. prefix_jcb16 = ['35']
  31. prefix_jcb15 = ['2131', '1800']
  32. credit_card_types = OrderedDict((
  33. ('maestro', CreditCard('Maestro',
  34. prefix_maestro, 12, security_code='CVV')),
  35. ('mastercard', CreditCard('Mastercard',
  36. prefix_mastercard, 16, security_code='CVV')),
  37. ('visa16', CreditCard('VISA 16 digit', prefix_visa)),
  38. ('visa13', CreditCard('VISA 13 digit', prefix_visa, 13)),
  39. ('visa19', CreditCard('VISA 19 digit', prefix_visa, 19)),
  40. ('amex', CreditCard('American Express', prefix_amex,
  41. 15, security_code='CID', security_code_length=4)),
  42. ('discover', CreditCard('Discover', prefix_discover)),
  43. ('diners', CreditCard('Diners Club / Carte Blanche', prefix_diners, 14)),
  44. ('jcb15', CreditCard('JCB 15 digit', prefix_jcb15, 15)),
  45. ('jcb16', CreditCard('JCB 16 digit', prefix_jcb16)),
  46. ))
  47. credit_card_types['visa'] = credit_card_types['visa16']
  48. credit_card_types['jcb'] = credit_card_types['jcb16']
  49. luhn_lookup = {'0': 0, '1': 2, '2': 4, '3': 6, '4': 8,
  50. '5': 1, '6': 3, '7': 5, '8': 7, '9': 9}
  51. def credit_card_provider(self, card_type=None):
  52. """ Returns the provider's name of the credit card. """
  53. if card_type is None:
  54. card_type = self.random_element(self.credit_card_types.keys())
  55. return self._credit_card_type(card_type).name
  56. def credit_card_number(self, card_type=None):
  57. """ Returns a valid credit card number. """
  58. card = self._credit_card_type(card_type)
  59. prefix = self.random_element(card.prefixes)
  60. number = self._generate_number(self.numerify(prefix), card.length)
  61. return number
  62. def credit_card_expire(self, start='now', end='+10y', date_format='%m/%y'):
  63. expire_date = self.generator.date_time_between(start, end)
  64. return expire_date.strftime(date_format)
  65. def credit_card_full(self, card_type=None):
  66. card = self._credit_card_type(card_type)
  67. tpl = ('{provider}\n'
  68. '{owner}\n'
  69. '{number} {expire_date}\n'
  70. '{security}: {security_nb}\n')
  71. tpl = tpl.format(provider=card.name,
  72. owner=self.generator.parse(
  73. "{{first_name}} {{last_name}}"),
  74. number=self.credit_card_number(card),
  75. expire_date=self.credit_card_expire(),
  76. security=card.security_code,
  77. security_nb=self.credit_card_security_code(card))
  78. return self.generator.parse(tpl)
  79. def credit_card_security_code(self, card_type=None):
  80. """ Returns a security code string. """
  81. sec_len = self._credit_card_type(card_type).security_code_length
  82. return self.numerify('#' * sec_len)
  83. def _credit_card_type(self, card_type=None):
  84. """ Returns a random credit card type instance. """
  85. if card_type is None:
  86. card_type = self.random_element(self.credit_card_types.keys())
  87. elif isinstance(card_type, CreditCard):
  88. return card_type
  89. return self.credit_card_types[card_type]
  90. def _generate_number(self, prefix, length):
  91. """
  92. 'prefix' is the start of the CC number as a string, any number of digits.
  93. 'length' is the length of the CC number to generate. Typically 13 or 16
  94. """
  95. number = prefix
  96. # Generate random char digits
  97. number += '#' * (length - len(prefix) - 1)
  98. number = self.numerify(number)
  99. reverse = number[::-1]
  100. # Calculate sum
  101. tot = 0
  102. pos = 0
  103. while pos < length - 1:
  104. tot += Provider.luhn_lookup[reverse[pos]]
  105. if pos != (length - 2):
  106. tot += int(reverse[pos + 1])
  107. pos += 2
  108. # Calculate check digit
  109. check_digit = (10 - (tot % 10)) % 10
  110. number += str(check_digit)
  111. return number