credit_card_validations 1.5.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ # == CreditCardValidations Factory
2
+ # Generates card number that passes validation
3
+ #
4
+ # #random
5
+ # CreditCardValidations::Factory.random
6
+ # #or particular brand
7
+ # CreditCardValidations::Factory.random(:maestro) # "6010430241237266856"
8
+ #
9
+ #
10
+ #
11
+ module CreditCardValidations
12
+ class Factory
13
+ class << self
14
+ def random(brand = nil)
15
+ if brand.nil?
16
+ brand = Detector.brands.keys.sample
17
+ else
18
+ raise RuntimeError.new("Unsupported brand") if Detector.brands[brand].nil?
19
+ end
20
+ generate(Detector.brands[brand][:rules].sample)
21
+
22
+ end
23
+
24
+ def generate(rule)
25
+ number(rule[:prefixes].sample, rule[:length].sample, rule.fetch(:options, {})[:skip_luhn])
26
+ end
27
+
28
+ def number(prefix, length, skip_luhn = false)
29
+ number = prefix.dup
30
+ 1.upto(length - (prefix.length + 1)) do
31
+ number << "#{rand(9)}"
32
+ end
33
+ #if skip luhn
34
+ if skip_luhn
35
+ number += "#{rand(9)}"
36
+ else
37
+ number += last_digit(number).to_s
38
+ end
39
+ number
40
+ end
41
+
42
+ #extracted from darkcoding-credit-card
43
+
44
+ def last_digit(number)
45
+ # Calculate sum
46
+ sum, pos = 0, 0
47
+ length = number.length + 1
48
+
49
+ reversed_number = number.reverse
50
+ while pos < length do
51
+ odd = reversed_number[pos].to_i * 2
52
+ odd -= 9 if odd > 9
53
+
54
+ sum += odd
55
+
56
+ sum += reversed_number[pos + 1].to_i if pos != (length - 2)
57
+
58
+ pos += 2
59
+ end
60
+
61
+ (((sum / 10).floor + 1) * 10 - sum) % 10
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,8 @@
1
+ # == CreditCardValidations Luhn
2
+ # simple class to validate Luhn numbers.
3
+ #
4
+ # Luhn.valid? 4111111111111111
5
+ #
1
6
  module CreditCardValidations
2
7
  class Luhn
3
8
  def self.valid?(number)
@@ -1,17 +1,22 @@
1
- #Major Industry Identifier (MII)
1
+ # == CreditCardValidations Mmi
2
2
  #
3
- #The first digit of a credit card number is the Major Industry Identifier (MII), which represents the category of entity which issued the card. MII digits represent the following issuer categories:
4
- #0 – ISO/TC 68 and other future industry assignments
5
- #1 Airlines
6
- #2Airlines and other future industry assignments
7
- #3Travel and entertainment and banking/financial
8
- #4Banking and financial
9
- #5Banking and financial
10
- #6Merchandising and banking/financial
11
- #7Petroleum and other future industry assignments
12
- #8Healthcare, telecommunications and other future industry assignments
13
- #9National assignment
14
- #For example, American Express, Diner's Club, Carte Blanche, and JCB are in the travel and entertainment category; VISA, MasterCard, and Discover are in the banking and financial category (Discover being in the Merchandising and banking/financial category); and Sun Oil and Exxon are in the petroleum category.
3
+ # Implements Major Industry Identifier (MII) detection
4
+ #
5
+ # The first digit of a credit card number is the Major Industry Identifier (MII), which represents the category of entity which issued the card. MII digits represent the following issuer categories:
6
+ # 0 ISO/TC 68 and other future industry assignments
7
+ # 1 Airlines
8
+ # 2 Airlines and other future industry assignments
9
+ # 3 Travel and entertainment and banking/financial
10
+ # 4 Banking and financial
11
+ # 5 Banking and financial
12
+ # 6 Merchandising and banking/financial
13
+ # 7 Petroleum and other future industry assignments
14
+ # 8 Healthcare, telecommunications and other future industry assignments
15
+ # 9 – National assignment
16
+ # For example, American Express, Diner's Club, Carte Blanche,
17
+ # and JCB are in the travel and entertainment category;
18
+ # VISA, MasterCard, and Discover are in the banking and financial category (Discover being in the Merchandising and banking/financial category);
19
+ # and Sun Oil and Exxon are in the petroleum category.
15
20
 
16
21
 
17
22
  module CreditCardValidations
@@ -1,5 +1,10 @@
1
+ # String extension for brand detecting and number validation
1
2
  #
2
- #
3
+ # require 'credit_card_validations/string'
4
+ # '5274 5763 9425 9961'.credit_card_brand
5
+ # '5274 5763 9425 9961'.credit_card_brand_name
6
+ # '5274 5763 9425 9961'.valid_credit_card_brand?(:mastercard, :visa)
7
+ # '5274 5763 9425 9961'.valid_credit_card_brand?(:amex)
3
8
  #
4
9
  class String
5
10
  def credit_card_brand
@@ -9,4 +14,9 @@ class String
9
14
  def valid_credit_card_brand?(*brands)
10
15
  CreditCardValidations::Detector.new(self).valid?(*brands)
11
16
  end
17
+
18
+ def credit_card_brand_name
19
+ CreditCardValidations::Detector.new(self).brand_name
20
+ end
21
+
12
22
  end
@@ -1,3 +1,3 @@
1
1
  module CreditCardValidations
2
- VERSION = "1.5.1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,238 @@
1
+ ---
2
+ :visa:
3
+ :rules:
4
+ - :length:
5
+ - 13
6
+ - 16
7
+ :prefixes:
8
+ - '4'
9
+ :mastercard:
10
+ :rules:
11
+ - :length:
12
+ - 16
13
+ :prefixes:
14
+ - '51'
15
+ - '52'
16
+ - '53'
17
+ - '54'
18
+ - '55'
19
+ :options:
20
+ :brand_name: MasterCard
21
+ :amex:
22
+ :rules:
23
+ - :length:
24
+ - 15
25
+ :prefixes:
26
+ - '34'
27
+ - '37'
28
+ :options:
29
+ :brand_name: American Express
30
+ :diners:
31
+ :rules:
32
+ - :length:
33
+ - 14
34
+ :prefixes:
35
+ - '300'
36
+ - '301'
37
+ - '302'
38
+ - '303'
39
+ - '304'
40
+ - '305'
41
+ - '36'
42
+ - '38'
43
+ :options:
44
+ :brand_name: Diners Club
45
+ :diners_us:
46
+ :rules:
47
+ - :length:
48
+ - 16
49
+ :prefixes:
50
+ - '54'
51
+ - '55'
52
+ :options:
53
+ :brand_name: Diners Club US
54
+ :discover:
55
+ :rules:
56
+ - :length:
57
+ - 16
58
+ :prefixes:
59
+ - '6011'
60
+ - '644'
61
+ - '645'
62
+ - '646'
63
+ - '647'
64
+ - '648'
65
+ - '649'
66
+ - '65'
67
+ :jcb:
68
+ :rules:
69
+ - :length:
70
+ - 15
71
+ - 16
72
+ :prefixes:
73
+ - '3528'
74
+ - '3529'
75
+ - '353'
76
+ - '354'
77
+ - '355'
78
+ - '356'
79
+ - '357'
80
+ - '358'
81
+ - :length:
82
+ - 15
83
+ :prefixes:
84
+ - '1800'
85
+ - '2131'
86
+ - :length:
87
+ - 19
88
+ :prefixes:
89
+ - '357266'
90
+ :options:
91
+ :brand_name: JCB
92
+ :laser:
93
+ :rules:
94
+ - :length:
95
+ - 16
96
+ - 17
97
+ - 18
98
+ - 19
99
+ :prefixes:
100
+ - '6304'
101
+ - '6706'
102
+ - '6771'
103
+ :solo:
104
+ :rules:
105
+ - :length:
106
+ - 16
107
+ - 18
108
+ - 19
109
+ :prefixes:
110
+ - '6334'
111
+ - '6767'
112
+ :switch:
113
+ :rules:
114
+ - :length:
115
+ - 16
116
+ - 18
117
+ - 19
118
+ :prefixes:
119
+ - '633110'
120
+ - '633312'
121
+ - '633304'
122
+ - '633303'
123
+ - '633301'
124
+ - '633300'
125
+ :maestro:
126
+ :rules:
127
+ - :length:
128
+ - 12
129
+ - 13
130
+ - 14
131
+ - 15
132
+ - 16
133
+ - 17
134
+ - 18
135
+ - 19
136
+ :prefixes:
137
+ - '500'
138
+ - '5010'
139
+ - '5011'
140
+ - '5012'
141
+ - '5013'
142
+ - '5014'
143
+ - '5015'
144
+ - '5016'
145
+ - '5017'
146
+ - '5018'
147
+ - '502'
148
+ - '503'
149
+ - '504'
150
+ - '505'
151
+ - '506'
152
+ - '507'
153
+ - '508'
154
+ - '509'
155
+ - '56'
156
+ - '57'
157
+ - '58'
158
+ - '59'
159
+ - '6010'
160
+ - '6012'
161
+ - '6013'
162
+ - '6014'
163
+ - '6015'
164
+ - '6016'
165
+ - '6017'
166
+ - '6018'
167
+ - '6019'
168
+ - '602'
169
+ - '603'
170
+ - '604'
171
+ - '605'
172
+ - '6060'
173
+ - '621'
174
+ - '627'
175
+ - '629'
176
+ - '670'
177
+ - '671'
178
+ - '672'
179
+ - '673'
180
+ - '674'
181
+ - '675'
182
+ - '677'
183
+ - '6760'
184
+ - '6761'
185
+ - '6762'
186
+ - '6763'
187
+ - '6764'
188
+ - '6765'
189
+ - '6766'
190
+ - '6768'
191
+ - '6769'
192
+ - '679'
193
+ :unionpay:
194
+ :rules:
195
+ - :length:
196
+ - 16
197
+ - 17
198
+ - 18
199
+ - 19
200
+ :prefixes:
201
+ - '622'
202
+ - '624'
203
+ - '625'
204
+ - '626'
205
+ - '628'
206
+ :options:
207
+ :skip_luhn: true
208
+ :brand_name: China UnionPay
209
+ :dankrot:
210
+ :rules:
211
+ - :length:
212
+ - 16
213
+ :prefixes:
214
+ - '5019'
215
+ :rupay:
216
+ :rules:
217
+ - :length:
218
+ - 16
219
+ :prefixes:
220
+ - '6061'
221
+ - '6062'
222
+ - '6063'
223
+ - '6064'
224
+ - '6065'
225
+ - '6066'
226
+ - '6067'
227
+ - '6068'
228
+ - '6069'
229
+ - '607'
230
+ - '608'
231
+ :options:
232
+ :skip_luhn: true
233
+ :hipercard:
234
+ :rules:
235
+ - :length:
236
+ - 19
237
+ :prefixes:
238
+ - '384'
@@ -0,0 +1,69 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "ActiveModel Validator" do
4
+
5
+ let(:model) { CreditCard.new }
6
+
7
+ describe "Proc support" do
8
+ it "should be valid if brands from proc valid" do
9
+ card = model.dup
10
+ card.card_type = "Master Card"
11
+ card.number6 = CreditCardValidations::Factory.random(:visa)
12
+ card.valid?.must_equal false
13
+ card.number6 = CreditCardValidations::Factory.random(:mastercard)
14
+ card.valid?.must_equal true
15
+
16
+ end
17
+
18
+ end
19
+
20
+ describe "Any Brand" do
21
+ it "should be valid for all prepared valid numbers" do
22
+ VALID_NUMBERS.each do |_, numbers|
23
+
24
+ numbers.each do |number|
25
+ card = model
26
+ card.number4 = number
27
+ card.number5 = number
28
+ card.valid?.must_equal true
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ describe "Except Amex and Maestro brand" do
37
+ it "should reject all other valid numbers" do
38
+ VALID_NUMBERS.except(:amex, :maestro) do |_, numbers|
39
+ card = model
40
+ card.number = numbers.first
41
+ card.valid?.must_equal false
42
+ end
43
+ end
44
+
45
+ it "should accept using except options" do
46
+ VALID_NUMBERS.except(:amex, :maestro) do |_, numbers|
47
+ card = model
48
+ card.number3 = numbers.first
49
+ card.valid?.must_equal true
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ describe "Only Amex and Mestro brands" do
56
+
57
+
58
+ it "should accept amex and maestro brand if valid" do
59
+ VALID_NUMBERS.slice(:amex, :maestro) do |_, numbers|
60
+ card = model
61
+ card.number = numbers.first
62
+ card.number2 = numbers.first
63
+ card.valid?.must_equal true
64
+ end
65
+ end
66
+
67
+
68
+ end
69
+ end