forgery 0.4.3 → 0.8.1
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 +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +12 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +35 -0
- data/LICENSE +1 -1
- data/README.markdown +196 -60
- data/Rakefile +10 -54
- data/forgery.gemspec +23 -0
- data/lib/forgery.rb +0 -1
- data/lib/forgery/dictionaries/bics +7 -0
- data/lib/forgery/dictionaries/company_names +0 -1
- data/lib/forgery/dictionaries/currency_descriptions +2 -2
- data/lib/forgery/dictionaries/ibans +61 -0
- data/lib/forgery/dictionaries/job_titles +1 -1
- data/lib/forgery/dictionaries/zones +1 -2
- data/lib/forgery/extend.rb +0 -2
- data/lib/forgery/extensions/range.rb +1 -1
- data/lib/forgery/file_reader.rb +2 -1
- data/lib/forgery/forgery/bank_account.rb +25 -0
- data/lib/forgery/forgery/basic.rb +1 -1
- data/lib/forgery/forgery/credit_card.rb +71 -0
- data/lib/forgery/forgery/geo.rb +54 -0
- data/lib/forgery/forgery/internet.rb +7 -0
- data/lib/forgery/forgery/lorem_ipsum.rb +4 -4
- data/lib/forgery/forgery/russian_tax.rb +57 -0
- data/lib/forgery/forgery_railtie.rb +0 -29
- data/lib/forgery/formats/phone +1 -1
- data/lib/forgery/version.rb +3 -1
- data/spec/data/dictionaries/code_names +6 -0
- data/spec/data/dictionaries/female_first_names +1 -0
- data/spec/data/documents/mock_web_page.html +17 -0
- data/spec/data/documents/mock_xml_doc.xml +5 -0
- data/spec/dictionaries_spec.rb +35 -0
- data/spec/extensions/array_spec.rb +25 -0
- data/spec/extensions/range_spec.rb +33 -0
- data/spec/extensions/string_spec.rb +29 -0
- data/spec/file_reader_spec.rb +32 -0
- data/spec/forgery/address_spec.rb +84 -0
- data/spec/forgery/bank_account_spec.rb +16 -0
- data/spec/forgery/basic_spec.rb +179 -0
- data/spec/forgery/credit_card_spec.rb +68 -0
- data/spec/forgery/currency_spec.rb +15 -0
- data/spec/forgery/date_spec.rb +134 -0
- data/spec/forgery/internet_spec.rb +62 -0
- data/spec/forgery/lorem_ipsum_spec.rb +132 -0
- data/spec/forgery/monetary_spec.rb +14 -0
- data/spec/forgery/name_spec.rb +11 -0
- data/spec/forgery/personal_spec.rb +15 -0
- data/spec/forgery/russian_tax_spec.rb +81 -0
- data/spec/forgery/time_spec.rb +7 -0
- data/spec/forgery_spec.rb +63 -0
- data/spec/formats_spec.rb +35 -0
- data/spec/spec_helper.rb +39 -0
- metadata +89 -38
- data/lib/forgery/file_writer.rb +0 -54
data/forgery.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
require 'forgery/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'forgery'
|
8
|
+
spec.version = Forgery::VERSION
|
9
|
+
spec.authors = ['Nathan Sutton', 'Brandon Arbini', 'Kamil Kieliszczyk']
|
10
|
+
spec.email = ['nate@zencoder.com', 'b@arbini.dev', 'kamil@kieliszczyk.net']
|
11
|
+
spec.homepage = 'http://github.com/sevenwire/forgery'
|
12
|
+
spec.summary = 'Easy and customizable generation of forged data.'
|
13
|
+
spec.description = 'Easy and customizable generation of forged data. Can be used as a gem or a rails plugin. Includes rails generators for creating your own forgeries.'
|
14
|
+
|
15
|
+
spec.platform = Gem::Platform::RUBY
|
16
|
+
spec.required_rubygems_version = '>= 1.3.6'
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
19
|
+
spec.test_files = `git ls-files spec`.split($INPUT_RECORD_SEPARATOR)
|
20
|
+
spec.require_paths = %w[lib]
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 2.1.4'
|
23
|
+
end
|
data/lib/forgery.rb
CHANGED
@@ -73,7 +73,7 @@ Palladium Ounces
|
|
73
73
|
Peru Nuevos Soles
|
74
74
|
Philippines Pesos
|
75
75
|
Platinum Ounces
|
76
|
-
|
76
|
+
Polish Zloty
|
77
77
|
Portugal Escudos
|
78
78
|
Qatar Riyals
|
79
79
|
Romania New Lei
|
@@ -103,4 +103,4 @@ United States Dollars
|
|
103
103
|
Venezuela Bolivares
|
104
104
|
Venezuela Bolivares Fuertes
|
105
105
|
Vietnam Dong
|
106
|
-
Zambia Kwacha
|
106
|
+
Zambia Kwacha
|
@@ -0,0 +1,61 @@
|
|
1
|
+
AD1200012030200359100100
|
2
|
+
AE070331234567890123456
|
3
|
+
AL47212110090000000235698741
|
4
|
+
AT611904300234573201
|
5
|
+
AZ21NABZ00000000137010001944
|
6
|
+
BA391290079401028494
|
7
|
+
BE68539007547034
|
8
|
+
BG80BNBG96611020345678
|
9
|
+
BH67BMAG00001299123456
|
10
|
+
CH9300762011623852957
|
11
|
+
CY17002001280000001200527600
|
12
|
+
CZ6508000000192000145399
|
13
|
+
DE89370400440532013000
|
14
|
+
DK5000400440116243
|
15
|
+
DO28BAGR00000001212453611324
|
16
|
+
EE382200221020145685
|
17
|
+
ES9121000418450200051332
|
18
|
+
FI2112345600000785
|
19
|
+
FO7630004440960235
|
20
|
+
FR1420041010050500013M02606
|
21
|
+
GB29NWBK60161331926819
|
22
|
+
GE29NB0000000101904917
|
23
|
+
GI75NWBK000000007099453
|
24
|
+
GL4330003330229543
|
25
|
+
GR1601101250000000012300695
|
26
|
+
HR1210010051863000160
|
27
|
+
HU42117730161111101800000000
|
28
|
+
IE29AIBK93115212345678
|
29
|
+
IL620108000000099999999
|
30
|
+
IS140159260076545510730339
|
31
|
+
IT60X0542811101000000123456
|
32
|
+
JO94CBJO0010000000000131000302
|
33
|
+
KW81CBKU0000000000001234560101
|
34
|
+
KZ86125KZT5004100100
|
35
|
+
LB62099900000001001901229114
|
36
|
+
LI21088100002324013AA
|
37
|
+
LT121000011101001000
|
38
|
+
LU280019400644750000
|
39
|
+
LV80BANK0000435195001
|
40
|
+
MC1112739000700011111000h79
|
41
|
+
MD24AG000225100013104168
|
42
|
+
ME25505000012345678951
|
43
|
+
MK07300000000042425
|
44
|
+
MR1300020001010000123456753
|
45
|
+
MT84MALT011000012345MTLCAST001S
|
46
|
+
MU17BOMM0101101030300200000MUR
|
47
|
+
NL91ABNA0417164300
|
48
|
+
NO9386011117947
|
49
|
+
PL27114020040000300201355387
|
50
|
+
PK36SCBL0000001123456702
|
51
|
+
PT50000201231234567890154
|
52
|
+
QA58DOHB00001234567890ABCDEFG
|
53
|
+
RO49AAAA1B31007593840000
|
54
|
+
RS35260005601001611379
|
55
|
+
SA0380000000608010167519
|
56
|
+
SE3550000000054910000003
|
57
|
+
SI56191000000123438
|
58
|
+
SK3112000000198742637541
|
59
|
+
SM86U0322509800000000270100
|
60
|
+
TN5914207207100707129648
|
61
|
+
TR330006100519786457841326
|
data/lib/forgery/extend.rb
CHANGED
data/lib/forgery/file_reader.rb
CHANGED
@@ -29,8 +29,9 @@ class Forgery
|
|
29
29
|
def self.find_file(name, folder)
|
30
30
|
Forgery.load_paths.reverse.each do |path|
|
31
31
|
file = "#{path}/#{folder}/#{name}"
|
32
|
-
return file if File.
|
32
|
+
return file if File.exist?(file)
|
33
33
|
end
|
34
|
+
raise ArgumentError.new("File '#{name}' wasn't found in '#{folder}' folder. Searched paths: \n#{Forgery.load_paths.join('\n')}")
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Generates random bank account information
|
2
|
+
class Forgery::BankAccount < Forgery
|
3
|
+
|
4
|
+
# Gets a random iban out of the 'ibans' dictionary.
|
5
|
+
#
|
6
|
+
# Forgery(:bank_account).iban
|
7
|
+
# # => "BE68539007547034"
|
8
|
+
#
|
9
|
+
# Forgery(:bank_account).iban
|
10
|
+
# # => "FI2112345600000785"
|
11
|
+
def self.iban
|
12
|
+
dictionaries[:ibans].random.unextend
|
13
|
+
end
|
14
|
+
|
15
|
+
# Gets a random bic out of the 'bics' dictionary.
|
16
|
+
#
|
17
|
+
# Forgery(:bank_account).bic
|
18
|
+
# # => "AARBDE5W100"
|
19
|
+
#
|
20
|
+
# Forgery(:bank_account).bic
|
21
|
+
# # => "GENODEF1PA1"
|
22
|
+
def self.bic
|
23
|
+
dictionaries[:bics].random.unextend
|
24
|
+
end
|
25
|
+
end
|
@@ -50,7 +50,7 @@ class Forgery::Basic < Forgery
|
|
50
50
|
#
|
51
51
|
# Forgery(:basic).encrypt('your-password', Time.utc(2009))
|
52
52
|
# # => "4b157c2fbf430b962842d21926eaa887c3a12f81"
|
53
|
-
def self.encrypt(password="password", salt
|
53
|
+
def self.encrypt(password="password", salt=rand)
|
54
54
|
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
|
55
55
|
end
|
56
56
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Generates random credit card numbers.
|
2
|
+
class Forgery::CreditCard < Forgery
|
3
|
+
|
4
|
+
CARDS = Forgery::Extend([
|
5
|
+
{:type => 'Visa', :length => 16, :prefixes => %w"4539 4556 4916 4532 4929 40240071 4485 4716 4"},
|
6
|
+
{:type => 'MasterCard', :length => 16, :prefixes => %w"51 52 53 54 55"},
|
7
|
+
{:type => 'American Express', :length => 15, :prefixes => %w"34 37"},
|
8
|
+
{:type => 'Discover', :length => 16, :prefixes => ["6011"]}
|
9
|
+
])
|
10
|
+
|
11
|
+
# Gets a random credit card type
|
12
|
+
#
|
13
|
+
# Forgery(:credit_card).type
|
14
|
+
# # => "Visa"
|
15
|
+
def self.type
|
16
|
+
CARDS.random[:type]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Gets a random credit card number
|
20
|
+
#
|
21
|
+
# Forgery(:credit_card).number
|
22
|
+
# # => "4539750423451972"
|
23
|
+
#
|
24
|
+
# Forgery(:credit_card).number(:type => 'Visa', :length => 13)
|
25
|
+
# # => "4556180133982"
|
26
|
+
#
|
27
|
+
# Supported Options
|
28
|
+
# [:type]
|
29
|
+
# The credit card type. Defaults to a random selection.
|
30
|
+
# [:length]
|
31
|
+
# The length of the credit card number. Defaults to the length for the selected card type.
|
32
|
+
# [:prefixes]
|
33
|
+
# The allowed prefixes for the card number. Defaults to prefixes for the selected card type.
|
34
|
+
def self.number(options={})
|
35
|
+
# find a card by type specified, or select a card randomly
|
36
|
+
card = if options[:type]
|
37
|
+
CARDS.find { |ccard| ccard[:type] == options[:type] }.clone
|
38
|
+
else
|
39
|
+
CARDS.random.clone
|
40
|
+
end
|
41
|
+
# merge the remaining options
|
42
|
+
card.merge!(options)
|
43
|
+
# start the number with a prefix for this card
|
44
|
+
number = Forgery::Extend(card[:prefixes]).random
|
45
|
+
# fill in the rest of the number with random digits, leave one space for the check digit
|
46
|
+
number << Forgery::Extend("#" * (card[:length] - number.length - 1)).to_numbers
|
47
|
+
# add the check digit
|
48
|
+
number += check_digit(number)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def self.check_digit(number)
|
54
|
+
# for explanation, please see: http://www.darkcoding.net/credit-card/luhn-formula/
|
55
|
+
sum = 0
|
56
|
+
digits = number.reverse.chars.to_a.collect { |digit| digit.to_i }
|
57
|
+
digits.each_with_index do |digit, index|
|
58
|
+
if index.even?
|
59
|
+
sum += if digit * 2 > 9
|
60
|
+
digit * 2 - 9
|
61
|
+
else
|
62
|
+
digit * 2
|
63
|
+
end
|
64
|
+
else
|
65
|
+
sum += digit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
(((sum / 10 + 1) * 10 - sum) % 10).to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Generates random geographic information.
|
2
|
+
class Forgery::Geo < Forgery
|
3
|
+
|
4
|
+
# Return a latitude in the range -90.0 to +90.0 as a float.
|
5
|
+
def self.latitude
|
6
|
+
rand * 180.0 - 90.0
|
7
|
+
end
|
8
|
+
|
9
|
+
# Return a latitude's degrees component in the range -180 to +180 as an integer.
|
10
|
+
def self.latitude_degrees
|
11
|
+
rand(360)-180
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return a latitude's minutes component in the range 0 to 60 as an integer.
|
15
|
+
def self.latitude_minutes
|
16
|
+
rand(60)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return a latitude's seconds component in the range 0 to 60 as an integer.
|
20
|
+
def self.latitude_seconds
|
21
|
+
rand(60)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return a latitude's direction component, either "N" (north) or "S" (south)
|
25
|
+
def self.latitude_direction
|
26
|
+
['N','S'].sample
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return a longitude in the range -180.0 to +180.0 as a float.
|
30
|
+
def self.longitude
|
31
|
+
rand * 360.0 - 180.0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return a longitude's degrees component in the range -180 to +180 as an integer.
|
35
|
+
def self.longitude_degrees
|
36
|
+
rand(360)-180
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return a longitude's minutes component in the range 0 to 60 as an integer.
|
40
|
+
def self.longitude_minutes
|
41
|
+
rand(60)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return a longitude's seconds component in the range 0 to 60 as an integer.
|
45
|
+
def self.longitude_seconds
|
46
|
+
rand(60)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a longitude's direction component, either "E" (east) or "W" (west)
|
50
|
+
def self.longitude_direction
|
51
|
+
["E","W"].sample
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
1
3
|
class Forgery::Internet < Forgery
|
2
4
|
|
3
5
|
def self.user_name
|
@@ -28,4 +30,9 @@ class Forgery::Internet < Forgery
|
|
28
30
|
(1..4).map{rand(256)}.join('.')
|
29
31
|
end
|
30
32
|
|
33
|
+
# credit for this method from http://stackoverflow.com/a/2811349/793330
|
34
|
+
def self.ip_v6
|
35
|
+
IPAddr.new(rand(2**128),Socket::AF_INET6).to_s
|
36
|
+
end
|
37
|
+
|
31
38
|
end
|
@@ -28,7 +28,7 @@ class Forgery::LoremIpsum < Forgery
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.characters(quantity=10, options={})
|
31
|
-
options.merge!(:random_limit => lorem_ipsum_characters.length-quantity) if quantity.is_a?(
|
31
|
+
options.merge!(:random_limit => lorem_ipsum_characters.length-quantity) if quantity.is_a?(Integer)
|
32
32
|
|
33
33
|
lorem_ipsum_characters[range_from_quantity(quantity, options)]
|
34
34
|
end
|
@@ -38,7 +38,7 @@ class Forgery::LoremIpsum < Forgery
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.words(quantity=10, options={})
|
41
|
-
options.merge!(:random_limit => lorem_ipsum_words.length-quantity) if quantity.is_a?(
|
41
|
+
options.merge!(:random_limit => lorem_ipsum_words.length-quantity) if quantity.is_a?(Integer)
|
42
42
|
|
43
43
|
lorem_ipsum_words[range_from_quantity(quantity, options)].join(" ")
|
44
44
|
end
|
@@ -48,7 +48,7 @@ class Forgery::LoremIpsum < Forgery
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def self.sentences(quantity=2, options={})
|
51
|
-
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length-quantity)) if quantity.is_a?(
|
51
|
+
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length-quantity)) if quantity.is_a?(Integer)
|
52
52
|
|
53
53
|
dictionaries[:lorem_ipsum][range_from_quantity(quantity, options)].join(" ")
|
54
54
|
end
|
@@ -65,7 +65,7 @@ class Forgery::LoremIpsum < Forgery
|
|
65
65
|
:html => false,
|
66
66
|
:sentences => 3}
|
67
67
|
options = default_options.merge(options)
|
68
|
-
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length/options[:sentences])-quantity) if quantity.is_a?(
|
68
|
+
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length/options[:sentences])-quantity) if quantity.is_a?(Integer)
|
69
69
|
|
70
70
|
if options[:html]
|
71
71
|
options[:wrap] = { :start => "<p>",
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Generates various special numbers for Russian taxation system
|
2
|
+
# They have numbers for identification, for banks, for companies and entrepreneurs
|
3
|
+
class Forgery::RussianTax < Forgery
|
4
|
+
|
5
|
+
TYPES = Forgery::Extend([:person, :legal])
|
6
|
+
|
7
|
+
#bank identification
|
8
|
+
def self.bik
|
9
|
+
"04#{5.times.map { rand(9) + 1 }.join}#{rand(50) + 50}"
|
10
|
+
end
|
11
|
+
|
12
|
+
#bank account format pretty simple
|
13
|
+
def self.account_number
|
14
|
+
20.times.map { rand(9) + 1 }.join
|
15
|
+
end
|
16
|
+
|
17
|
+
#taxation id
|
18
|
+
def self.inn(options = {})
|
19
|
+
type = TYPES.include?(options[:type]) ? options[:type] : TYPES.random
|
20
|
+
send [type, :inn].join('_')
|
21
|
+
end
|
22
|
+
|
23
|
+
#government registration id
|
24
|
+
def self.ogrn(options = {})
|
25
|
+
type = TYPES.include?(options[:type]) ? options[:type] : TYPES.random
|
26
|
+
send [type, :ogrn].join('_')
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def self.person_inn
|
31
|
+
mask = [[7, 2, 4, 10, 3, 5, 9, 4, 6, 8], [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8]]
|
32
|
+
inn = 12.times.map { rand(9) + 1 }.join
|
33
|
+
inn[10] = ((0..(inn.length-3)).inject(0) {|crc, i| crc + inn[i].to_i*mask[0][i].to_i} % 11 % 10).to_s
|
34
|
+
inn[11] = ((0..(inn.length-2)).inject(0) {|crc, i| crc + inn[i].to_i*mask[1][i].to_i} % 11 % 10).to_s
|
35
|
+
inn
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.legal_inn
|
39
|
+
mask = [2, 4, 10, 3, 5, 9, 4, 6, 8]
|
40
|
+
inn = 10.times.map { rand(9) + 1 }.join
|
41
|
+
inn[9] = ((0..(inn.length-2)).inject(0) {|crc, i| crc + inn[i].to_i*mask[i].to_i} % 11 % 10).to_s
|
42
|
+
inn
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.person_ogrn
|
46
|
+
ogrn = 14.times.map { rand(9) + 1 }.join
|
47
|
+
ogrn += (ogrn.to_i%13%10).to_s
|
48
|
+
ogrn
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.legal_ogrn
|
52
|
+
ogrn = 12.times.map { rand(9) + 1 }.join
|
53
|
+
ogrn += (ogrn.to_i%11%10).to_s
|
54
|
+
ogrn
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|