teebo 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/data/en-us.yml +4 -4
- data/lib/teebo.rb +6 -3
- data/lib/teebo/credit_card.rb +49 -16
- data/lib/teebo/name.rb +11 -11
- data/lib/teebo/number.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f974479fae12561857d5bf06a7d8dca7ccdb9ec0
|
4
|
+
data.tar.gz: 625cc67d205696380258f0609b5bf9d629a0d815
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba28733ba9e1d07ce99788a6256dba6e963a82f2502f3b097f3471c3a7b0aa628fe15c7f7670cdafcf2748730ed29e76ab554b83814714a6080ca7d79fb0af3f
|
7
|
+
data.tar.gz: 27330412ec7063ebf78042caa44236bf57860ea4a2bac435ee42700406876bd52fcc5c897773b23d6a116fc63cbb1aad0560c0e40086064d92de08248f9b5882
|
data/lib/data/en-us.yml
CHANGED
@@ -9,7 +9,7 @@ credit-card-issuers:
|
|
9
9
|
- 15
|
10
10
|
validation: yes
|
11
11
|
probability: .092
|
12
|
-
|
12
|
+
cvv-length: 4
|
13
13
|
-
|
14
14
|
name: Discover Card
|
15
15
|
iin-prefixes: [ 6011, 622126, 622127, 622128, 622129, 622130, 622131, 622132, 622133, 622134, 622135, 622136, 622137, 622138, 622139, 622140, 622141, 622142, 622143, 622144, 622145, 622146, 622147, 622148, 622149, 622150, 622151, 622152, 622153, 622154, 622155, 622156, 622157, 622158, 622159, 622160, 622161, 622162, 622163, 622164, 622165, 622166, 622167, 622168, 622169, 622170, 622171, 622172, 622173, 622174, 622175, 622176, 622177, 622178, 622179, 622180, 622181, 622182, 622183, 622184, 622185, 622186, 622187, 622188, 622189, 622190, 622191, 622192, 622193, 622194, 622195, 622196, 622197, 622198, 622199, 622200, 6222, 6223, 6224, 6225, 6226, 6227, 6228, 622901, 622902, 622903, 622904, 622905, 622906, 622907, 622908, 622909, 622910, 622911, 622912, 622913, 622914, 622915, 622916, 622917, 622918, 622919, 622920, 622921, 622922, 622923, 622924, 622925, 644, 645, 646, 647, 648, 649, 65 ]
|
@@ -17,7 +17,7 @@ credit-card-issuers:
|
|
17
17
|
- 16
|
18
18
|
validation: yes
|
19
19
|
probability: .107
|
20
|
-
|
20
|
+
cvv-length: 3
|
21
21
|
-
|
22
22
|
name: MasterCard
|
23
23
|
iin-prefixes: [ 51, 52, 53, 54, 55 ]
|
@@ -25,7 +25,7 @@ credit-card-issuers:
|
|
25
25
|
- 16
|
26
26
|
validation: yes
|
27
27
|
probability: .313
|
28
|
-
|
28
|
+
cvv-length: 3
|
29
29
|
-
|
30
30
|
name: Visa
|
31
31
|
iin-prefixes:
|
@@ -35,4 +35,4 @@ credit-card-issuers:
|
|
35
35
|
- 16
|
36
36
|
validation: yes
|
37
37
|
probability: .488
|
38
|
-
|
38
|
+
cvv-length: 3
|
data/lib/teebo.rb
CHANGED
@@ -5,9 +5,12 @@ require 'randexp'
|
|
5
5
|
module Teebo
|
6
6
|
|
7
7
|
class TeeboGenerator
|
8
|
-
def
|
9
|
-
@db_connection
|
10
|
-
|
8
|
+
def self.db_connection
|
9
|
+
@db_connection ||= Teebo::DatabaseHandler.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.yaml_mapping
|
13
|
+
@yaml_mapping ||= YAML::load(File.open('lib/data/en-us.yml'))
|
11
14
|
end
|
12
15
|
end
|
13
16
|
end
|
data/lib/teebo/credit_card.rb
CHANGED
@@ -6,18 +6,29 @@ module Teebo
|
|
6
6
|
#
|
7
7
|
class CreditCard < TeeboGenerator
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
9
|
+
def self.issuers
|
10
|
+
@cc_issuers ||= yaml_mapping['credit-card-issuers']
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.generate_card(issuer=nil)
|
14
|
+
if issuer.nil?
|
15
|
+
issuer = generate_issuer
|
16
|
+
end
|
17
|
+
[
|
18
|
+
'issuer' => issuer['name'],
|
19
|
+
'number' => generate_number(issuer),
|
20
|
+
'cvv' => generate_cvv_code(issuer),
|
21
|
+
'expiration' => generate_expiration_date
|
22
|
+
]
|
12
23
|
end
|
13
24
|
|
14
25
|
#
|
15
26
|
# Returns a credit card issuer according to the likelihood that it would be seen in the wild.
|
16
27
|
#
|
17
|
-
def generate_issuer
|
28
|
+
def self.generate_issuer
|
18
29
|
random_choice = Random.rand
|
19
30
|
full_weight = 0
|
20
|
-
|
31
|
+
issuers.each do |issuer|
|
21
32
|
full_weight += issuer['probability']
|
22
33
|
if random_choice < full_weight
|
23
34
|
return issuer
|
@@ -28,23 +39,22 @@ module Teebo
|
|
28
39
|
#
|
29
40
|
# Generates a credit card number according to the pattern specified in the 'issuer' passed in.
|
30
41
|
#
|
31
|
-
def generate_number(issuer)
|
42
|
+
def self.generate_number(issuer)
|
32
43
|
# TODO: Sample according to realistic distribution - numbers w/long prefixes are prioritized too highly right now.
|
33
44
|
prefix = issuer['iin-prefixes'].sample.to_s
|
34
45
|
length = issuer['lengths'].sample
|
35
|
-
generated =
|
46
|
+
generated = number_with_length(length - prefix.length)
|
36
47
|
number = prefix + generated
|
37
48
|
if issuer['validation']
|
38
49
|
last_digit_validation(number)
|
39
50
|
end
|
40
|
-
|
41
51
|
end
|
42
52
|
|
43
53
|
#
|
44
|
-
# Gets the sum of the digits of the specified number
|
45
|
-
# check digit.
|
54
|
+
# Gets the sum of the digits of the specified number, with every other digit doubled. Necessary
|
55
|
+
# to calculate a credit card's check digit.
|
46
56
|
#
|
47
|
-
def luhn_sum(number)
|
57
|
+
def self.luhn_sum(number)
|
48
58
|
digits = number.to_s.chars.map(&:to_i)
|
49
59
|
digits.reverse.each_slice(2).map do |x, y|
|
50
60
|
[(x * 2).divmod(10), y || 0]
|
@@ -55,7 +65,7 @@ module Teebo
|
|
55
65
|
# A simple implementation of the [Luhn algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm),
|
56
66
|
# which all U.S.-based Credit Card issuers use for the validation check on credit card numbers.
|
57
67
|
#
|
58
|
-
def luhn_algorithm(number)
|
68
|
+
def self.luhn_algorithm(number)
|
59
69
|
digit_sum = luhn_sum(number)
|
60
70
|
((10 - digit_sum % 10) % 10).to_s
|
61
71
|
end
|
@@ -64,7 +74,7 @@ module Teebo
|
|
64
74
|
# Uses the Luhn algorithm to replace the last digit in the generated number with the correct
|
65
75
|
# check digit.
|
66
76
|
#
|
67
|
-
def last_digit_validation(number)
|
77
|
+
def self.last_digit_validation(number)
|
68
78
|
trimmed_number = number[0..-2]
|
69
79
|
check_digit = luhn_algorithm(trimmed_number)
|
70
80
|
trimmed_number + check_digit
|
@@ -74,9 +84,32 @@ module Teebo
|
|
74
84
|
# Generates a random number with the specified number of digits, padding the beginning with
|
75
85
|
# '0' characters, if necessary.
|
76
86
|
#
|
77
|
-
def
|
78
|
-
|
79
|
-
rand(10 **
|
87
|
+
def self.number_with_length(length)
|
88
|
+
length = length.to_i
|
89
|
+
rand(10 ** length).to_s.rjust(length,'0')
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Generates a Credit Card CVV code. This simply returns a random number of the length used by
|
94
|
+
# the specified 'issuer' object.
|
95
|
+
#
|
96
|
+
def self.generate_cvv_code(issuer)
|
97
|
+
number_with_length(issuer['cvv-length'])
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Generates an expiration date for a credit card. These dates are, somewhat arbitrarily, simply
|
102
|
+
# some time in the next 5 years.
|
103
|
+
#
|
104
|
+
def self.generate_expiration_date
|
105
|
+
current_year = Time.now.year - 2000
|
106
|
+
month = rand(1...13)
|
107
|
+
if month <= Time.now.month
|
108
|
+
current_year += 1
|
109
|
+
end
|
110
|
+
year = rand(current_year...(current_year + 5))
|
111
|
+
month = month.to_s.rjust(2,'0')
|
112
|
+
"#{month}/#{year}"
|
80
113
|
end
|
81
114
|
end
|
82
115
|
end
|
data/lib/teebo/name.rb
CHANGED
@@ -12,11 +12,11 @@ module Teebo
|
|
12
12
|
# Picks a random first & last name, selecting a random gender if it's not
|
13
13
|
# specified.
|
14
14
|
#
|
15
|
-
def
|
15
|
+
def self.generate_name (sex=nil)
|
16
16
|
if sex.nil?
|
17
17
|
sex = %w(M F).sample
|
18
18
|
end
|
19
|
-
|
19
|
+
generate_given_name(sex) + ' ' + generate_surname
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
@@ -26,38 +26,38 @@ module Teebo
|
|
26
26
|
# simply be another given name of the same gender is almost certainly less
|
27
27
|
# than 100%.
|
28
28
|
#
|
29
|
-
def
|
29
|
+
def self.generate_full_name(sex=nil)
|
30
30
|
# TODO: Take into account different probabilities of different types of middle names.
|
31
31
|
if sex.nil?
|
32
32
|
sex = %w(M F).sample
|
33
33
|
end
|
34
|
-
|
34
|
+
generate_given_name(sex) + ' ' + generate_given_name(sex) + ' ' + generate_surname
|
35
35
|
end
|
36
36
|
|
37
37
|
#
|
38
38
|
# Finds the total count for the number of names in the database.
|
39
39
|
#
|
40
|
-
def sum_count(sex)
|
41
|
-
|
40
|
+
def self.sum_count(sex)
|
41
|
+
db_connection.get_sum(GIVEN_NAMES_TABLE, 'count', {column: 'sex', condition: sex})
|
42
42
|
end
|
43
43
|
|
44
44
|
#
|
45
45
|
# Selects a random (weighted) given name from the database.
|
46
46
|
#
|
47
|
-
def
|
47
|
+
def self.generate_given_name(sex)
|
48
48
|
count = sum_count(sex)
|
49
49
|
selection = rand(count)
|
50
|
-
|
50
|
+
db_connection.get_row_for_count(GIVEN_NAMES_TABLE, 'count_to', selection,
|
51
51
|
{column: 'sex', condition: sex})['name']
|
52
52
|
end
|
53
53
|
|
54
54
|
#
|
55
55
|
# Selects a random (weighted) surname from the database.
|
56
56
|
#
|
57
|
-
def
|
58
|
-
count =
|
57
|
+
def self.generate_surname
|
58
|
+
count = db_connection.get_sum(SURNAMES_TABLE, 'count')
|
59
59
|
selection = rand(count)
|
60
|
-
|
60
|
+
db_connection.get_row_for_count(SURNAMES_TABLE, 'count_to', selection)['name']
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/teebo/number.rb
CHANGED
@@ -9,7 +9,7 @@ module Teebo
|
|
9
9
|
# A basic implementation of the Box-Muller transform. Adapted from an answer by antonakos on
|
10
10
|
# Stack Overflow here: http://stackoverflow.com/questions/5825680
|
11
11
|
#
|
12
|
-
def normal_dist(mean, std_deviation, rand = lambda { Kernel.rand })
|
12
|
+
def self.normal_dist(mean, std_deviation, rand = lambda { Kernel.rand })
|
13
13
|
theta = 2 * Math::PI * rand.call
|
14
14
|
rho = Math.sqrt(-2 * Math.log(1 - rand.call))
|
15
15
|
scale = std_deviation * rho
|
@@ -20,7 +20,7 @@ module Teebo
|
|
20
20
|
# Generates a number according to Benford's law, meaning that it is more indicative of numbers
|
21
21
|
# encountered in real life.
|
22
22
|
#
|
23
|
-
def benford_dist(upper_bound, decimals=0)
|
23
|
+
def self.benford_dist(upper_bound, decimals=0)
|
24
24
|
(upper_bound**Random.rand).round(decimals)
|
25
25
|
end
|
26
26
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teebo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Russ Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|