forked from faker-ruby/faker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bank.rb
106 lines (84 loc) · 3.33 KB
/
bank.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# frozen_string_literal: true
module Faker
class Bank < Base
flexible :bank
class << self
def account_number(digits = 10)
output = ''
output += rand.to_s[2..-1] while output.length < digits
output[0...digits]
end
def iban(country_code = 'GB')
# Each country has it's own format for bank accounts
# Many of them use letters in certain parts of the account
# Using regex patterns we can create virtually any type of bank account
begin
pattern = fetch("bank.iban_details.#{country_code.downcase}.bban_pattern")
rescue I18n::MissingTranslationData
raise ArgumentError, "Could not find iban details for #{country_code}"
end
# Use Faker::Base.regexify for creating a sample from bank account format regex
account = Base.regexify(/#{pattern}/)
# Add country code and checksum to the generated account to form valid IBAN
country_code.upcase + iban_checksum(country_code, account) + account
end
def name
fetch('bank.name')
end
def routing_number
valid_routing_number
end
def routing_number_with_format
compile_fraction(valid_routing_number)
end
def swift_bic
fetch('bank.swift_bic')
end
private
def checksum(num_string)
num_array = num_string.split('').map(&:to_i)
(
7 * (num_array[0] + num_array[3] + num_array[6]) +
3 * (num_array[1] + num_array[4] + num_array[7]) +
9 * (num_array[2] + num_array[5])
) % 10
end
def compile_routing_number
digit_one_two = %w[00 01 02 03 04 05 06 07 08 09 10 11 12]
((21..32).to_a + (61..72).to_a + [80]).each { |x| digit_one_two << x.to_s }
routing_num = digit_one_two.sample + rand_numstring + rand_numstring + rand_numstring + rand_numstring + rand_numstring + rand_numstring + rand_numstring
routing_num
end
# Calculates the mandatory checksum in 3rd and 4th characters in IBAN format
# source: https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN
def iban_checksum(country_code, account)
# Converts letters to numbers according the iban rules, A=10..Z=35
account_to_number = "#{account}#{country_code}00".upcase.chars.map do |d|
d =~ /[A-Z]/ ? (d.ord - 55).to_s : d
end.join.to_i
# This is answer to (iban_to_num + checksum) % 97 == 1
checksum = (1 - account_to_number) % 97
# Use leftpad to make the size always to 2
checksum.to_s.rjust(2, '0')
end
def valid_routing_number
routing_number = compile_routing_number
checksum = checksum(routing_number)
return routing_number if valid_checksum?(routing_number, checksum)
routing_number[0..7] + checksum.to_s
end
def valid_checksum?(routing_number, checksum)
routing_number[8].to_i == checksum
end
def compile_fraction(routing_num)
prefix = (1..50).to_a.map(&:to_s).sample
numerator = routing_num.split('')[5..8].join.to_i.to_s
denominator = routing_num.split('')[0..4].join.to_i.to_s
prefix + '-' + numerator + '/' + denominator
end
def rand_numstring
(0..9).to_a.map(&:to_s).sample
end
end
end
end