forgery 0.4.3 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|