uk_account_validator 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/lib/uk_account_validator.rb +14 -0
- data/lib/uk_account_validator/exceptions/base_exception.rb +65 -0
- data/lib/uk_account_validator/exceptions/exception_1.rb +10 -0
- data/lib/uk_account_validator/exceptions/exception_10.rb +18 -0
- data/lib/uk_account_validator/exceptions/exception_12.rb +9 -0
- data/lib/uk_account_validator/exceptions/exception_14.rb +30 -0
- data/lib/uk_account_validator/exceptions/exception_2_9.rb +68 -0
- data/lib/uk_account_validator/exceptions/exception_3.rb +10 -0
- data/lib/uk_account_validator/exceptions/exception_4.rb +16 -0
- data/lib/uk_account_validator/exceptions/exception_5.rb +48 -0
- data/lib/uk_account_validator/exceptions/exception_6.rb +16 -0
- data/lib/uk_account_validator/exceptions/exception_7.rb +9 -0
- data/lib/uk_account_validator/exceptions/exception_8.rb +7 -0
- data/lib/uk_account_validator/modulus_weight.rb +2 -2
- data/lib/uk_account_validator/number_indices.rb +18 -0
- data/lib/uk_account_validator/validator.rb +36 -21
- data/lib/uk_account_validator/validators/base_validator.rb +8 -134
- data/lib/uk_account_validator/validators/double_alternate.rb +2 -5
- data/lib/uk_account_validator/validators/standard_modulus.rb +4 -7
- data/lib/uk_account_validator/version.rb +1 -1
- data/uk_account_validator.gemspec +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c637157bc170af3a8dfffc98dc8eb077c8399a53
|
4
|
+
data.tar.gz: 306471bc50f263137a9345d71bdbb01030dfedd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d4c22ba1364efd73e909e109f99875f281ec87dbbd90e27042cd50223f3a899e7efe803da9aeac4d7f4c634fdfb256413f51ee6f9255f47958ad0ff5f69cdc2
|
7
|
+
data.tar.gz: 8455a102924d27c735870f1fe061c6200105a8a766a6fe36bf14e761b0e78aad6dc8a4f64b1258a718174d41ee2ca3cb2b0e0d8287de0fdcfe957821584adad3
|
data/.travis.yml
CHANGED
data/lib/uk_account_validator.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'uk_account_validator/number_indices.rb'
|
1
2
|
require 'uk_account_validator/validator.rb'
|
2
3
|
require 'uk_account_validator/modulus_weight.rb'
|
3
4
|
require 'uk_account_validator/modulus_weights_table.rb'
|
@@ -8,6 +9,19 @@ require 'uk_account_validator/validators/modulus10.rb'
|
|
8
9
|
require 'uk_account_validator/validators/modulus11.rb'
|
9
10
|
require 'uk_account_validator/validators/double_alternate.rb'
|
10
11
|
|
12
|
+
require 'uk_account_validator/exceptions/base_exception.rb'
|
13
|
+
require 'uk_account_validator/exceptions/exception_1.rb'
|
14
|
+
require 'uk_account_validator/exceptions/exception_2_9.rb'
|
15
|
+
require 'uk_account_validator/exceptions/exception_3.rb'
|
16
|
+
require 'uk_account_validator/exceptions/exception_4.rb'
|
17
|
+
require 'uk_account_validator/exceptions/exception_5.rb'
|
18
|
+
require 'uk_account_validator/exceptions/exception_6.rb'
|
19
|
+
require 'uk_account_validator/exceptions/exception_7.rb'
|
20
|
+
require 'uk_account_validator/exceptions/exception_8.rb'
|
21
|
+
require 'uk_account_validator/exceptions/exception_10.rb'
|
22
|
+
require 'uk_account_validator/exceptions/exception_12.rb'
|
23
|
+
require 'uk_account_validator/exceptions/exception_14.rb'
|
24
|
+
|
11
25
|
module UkAccountValidator
|
12
26
|
def self.modulus_weights_table
|
13
27
|
@modulus_weights_table ||= read_modulus_weights_table
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class BaseException
|
2
|
+
include NumberIndices
|
3
|
+
|
4
|
+
attr_reader :modulus_weight, :account_number, :sort_code, :check_number
|
5
|
+
|
6
|
+
def initialize(modulus_weight, account_number, sort_code, check_number)
|
7
|
+
@modulus_weight = modulus_weight
|
8
|
+
@account_number = account_number
|
9
|
+
@sort_code = sort_code
|
10
|
+
@check_number = check_number
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.allow_any?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def override_test?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the new modulus weight after applying the exception.
|
22
|
+
def replace_weight(_test_digits)
|
23
|
+
return modulus_weight
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the new total after any adjustments
|
27
|
+
def after_calculate_total(total, _test_digits)
|
28
|
+
return total
|
29
|
+
end
|
30
|
+
|
31
|
+
def apply_account_number_substitutions
|
32
|
+
return account_number
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the new sort code after substitutions
|
36
|
+
def apply_sort_code_substitutions
|
37
|
+
return sort_code
|
38
|
+
end
|
39
|
+
|
40
|
+
# Useful functions
|
41
|
+
|
42
|
+
# Zero all weights
|
43
|
+
def zero_all
|
44
|
+
UkAccountValidator::ModulusWeight.new(
|
45
|
+
modulus_weight.sort_code_start,
|
46
|
+
modulus_weight.sort_code_end,
|
47
|
+
modulus_weight.modulus,
|
48
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
49
|
+
modulus_weight.exception
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Zero weights for u to b
|
54
|
+
def zero_u_b
|
55
|
+
UkAccountValidator::ModulusWeight.new(
|
56
|
+
modulus_weight.sort_code_start,
|
57
|
+
modulus_weight.sort_code_end,
|
58
|
+
modulus_weight.modulus,
|
59
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
60
|
+
modulus_weight.c, modulus_weight.d, modulus_weight.e,
|
61
|
+
modulus_weight.f, modulus_weight.g, modulus_weight.h,
|
62
|
+
modulus_weight.exception
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Perform the double alternate check except:
|
2
|
+
# Add 27 to the total (ie before you divide by 10)
|
3
|
+
# This effectively places a financial institution number (580149) before the
|
4
|
+
# sorting code and account number which is subject to the alternate doubling as
|
5
|
+
# well.
|
6
|
+
class Exception1 < BaseException
|
7
|
+
def after_calculate_total(total, _test_digits)
|
8
|
+
return total + 27
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# For the exception 10 check, if ab = 09 or ab = 99 and g = 9, zeroise weighting
|
2
|
+
# positions u-b.
|
3
|
+
class Exception10 < BaseException
|
4
|
+
def self.allow_any?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
def replace_weight(test_digits)
|
9
|
+
# if ab = 09 or 99 and g=9, zeroise weighting positions u-b.
|
10
|
+
a = test_digits[NUMBER_INDEX[:a]]
|
11
|
+
b = test_digits[NUMBER_INDEX[:b]]
|
12
|
+
|
13
|
+
return zero_u_b if (a == 0 && b == 9) ||
|
14
|
+
(a == 9 && b == 9 && test_digits[NUMBER_INDEX[:g]] == 9)
|
15
|
+
|
16
|
+
return modulus_weight
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# These are for Nationwide Flex accounts. Where there is a 12 in the exception
|
2
|
+
# column for the first check for a sorting code and a 13 in the exception column
|
3
|
+
# for the second check for the same sorting code, if either check is successful
|
4
|
+
# the account number is deemed valid.
|
5
|
+
class Exception12 < BaseException
|
6
|
+
def self.allow_any?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Perform the modulus 11 check as normal:
|
2
|
+
# * If the check passes (that is, there is no remainder), then the account
|
3
|
+
# number should be considered valid. Do not perform the second check.
|
4
|
+
# * If the first check fails, then the second check must be performed as
|
5
|
+
# specified below.
|
6
|
+
#
|
7
|
+
# Second check:
|
8
|
+
# * If the 8th digit of the account number (reading from left to right) is not
|
9
|
+
# 0, 1 or 9 then the account number fails the second check and is not a valid
|
10
|
+
# Coutts account number
|
11
|
+
# * If the 8th digit is 0, 1 or 9, then remove the digit from the account
|
12
|
+
# number and insert a 0 as the 1st digit for check purposes only
|
13
|
+
# * Perform the modulus 11 check on the modified account number using the same
|
14
|
+
# weightings as specified in the table (that is, 0 0 0 0 0 0 8 7 6 5 4 3 2 1):
|
15
|
+
# - If there is no remainder, then the account number should be considered
|
16
|
+
# valid
|
17
|
+
# - If there is a remainder, then the account number fails the second check
|
18
|
+
# and is not a valid Coutts account number
|
19
|
+
class Exception14 < BaseException
|
20
|
+
def self.allow_any?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def apply_account_number_substitutions
|
25
|
+
return account_number unless %w(0 1 9).include?(account_number[7])
|
26
|
+
|
27
|
+
account_number.slice!(7)
|
28
|
+
return '0' + account_number
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Only occurs for some standard modulus 11 checks, when there is a 2 in the
|
2
|
+
# exception column for the first check for a sorting code and a 9 in the
|
3
|
+
# exception column for the second check for the same sorting code. This is used
|
4
|
+
# specifically for Lloyds euro accounts.
|
5
|
+
#
|
6
|
+
# Perform the standard check, except:
|
7
|
+
# * If a <> 0 and g <> 9, substitute the weight specified in the modulus weight
|
8
|
+
# table with:
|
9
|
+
# u v w x y z a b c d e f g h
|
10
|
+
# 0 0 1 2 5 3 6 4 8 7 10 9 3 1
|
11
|
+
#
|
12
|
+
# * If a <> 0 and g = 9, substitute the weight specified in the modulus weight
|
13
|
+
# table with:
|
14
|
+
# u v w x y z a b c d e f g h
|
15
|
+
# 0 0 0 0 0 0 0 0 8 7 10 9 3 1
|
16
|
+
#
|
17
|
+
# If the first row with exception 2 passes the standard modulus 11 check, you do
|
18
|
+
# not need to carry out the second check (ie it is deemed to be a valid sterling
|
19
|
+
# account).
|
20
|
+
#
|
21
|
+
# All Lloyds euro accounts are held at sorting code 30-96-34, however customers
|
22
|
+
# may perceive that their euro account is held at the branch where sterling
|
23
|
+
# accounts are held and thus quote a sorting code other than 30-96-34. The
|
24
|
+
# combination of the "sterling" sorting code and "euro" account number will
|
25
|
+
# cause the first standard modulus 11 check to fail. In such cases, carry out
|
26
|
+
# the second modulus 11 check, substituting the sorting code with 309634 and the
|
27
|
+
# appropriate weighting. If this check passes it is deemed to be a valid euro
|
28
|
+
# account.
|
29
|
+
|
30
|
+
class Exception29 < BaseException
|
31
|
+
def self.allow_any?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def apply_sort_code_substitutions
|
36
|
+
return '309634' if check_number == 2
|
37
|
+
|
38
|
+
return sort_code
|
39
|
+
end
|
40
|
+
|
41
|
+
def replace_weight(test_digits)
|
42
|
+
return modulus_weight if test_digits[NUMBER_INDEX[:a]] == 0
|
43
|
+
return substitute_modulus_weight if check_number == 2
|
44
|
+
|
45
|
+
if test_digits[NUMBER_INDEX[:g]] != 9
|
46
|
+
return UkAccountValidator::ModulusWeight.new(
|
47
|
+
modulus_weight.sort_code_start,
|
48
|
+
modulus_weight.sort_code_end,
|
49
|
+
modulus_weight.modulus,
|
50
|
+
0, 0, 1, 2, 5, 3, 6, 4, 8, 7, 10, 9, 3, 1,
|
51
|
+
modulus_weight.exception
|
52
|
+
)
|
53
|
+
else
|
54
|
+
return UkAccountValidator::ModulusWeight.new(
|
55
|
+
modulus_weight.sort_code_start,
|
56
|
+
modulus_weight.sort_code_end,
|
57
|
+
modulus_weight.modulus,
|
58
|
+
0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 10, 9, 3, 1,
|
59
|
+
modulus_weight.exception
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the modulus weight for 309634
|
65
|
+
def substitute_modulus_weight
|
66
|
+
UkAccountValidator.modulus_weights_table.find('309634').first
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Perform the standard modulus 11 check.
|
2
|
+
# After you have finished the check, ensure that the remainder is the same as
|
3
|
+
# the two-digit checkdigit;
|
4
|
+
# the checkdigit for exception 4 is gh from the original account number.
|
5
|
+
class Exception4 < BaseException
|
6
|
+
def override_test?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def test(modulus, total, test_digits, _test)
|
11
|
+
check_sum = [test_digits[NUMBER_INDEX[:g]], test_digits[NUMBER_INDEX[:h]]].join
|
12
|
+
check_sum = check_sum.to_i
|
13
|
+
|
14
|
+
total % modulus == check_sum
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Perform the first check (standard modulus check) except:
|
2
|
+
# * If the sorting code appears in SCSUBTAB.txt, substitute it for the
|
3
|
+
# "substitute with" column (for check purposes only).
|
4
|
+
# If the sorting code is not found, use the original sorting code.
|
5
|
+
#
|
6
|
+
# For the standard check with exception 5 the checkdigit is g from the original
|
7
|
+
# account number.
|
8
|
+
# * After dividing the result by 11:
|
9
|
+
# - if the remainder = 0 and g = 0 the account number is valid
|
10
|
+
# - if the remainder = 1 the account number is invalid
|
11
|
+
# - for all other remainders, take the remainder away from 11. If the number
|
12
|
+
# you get is the same as g then the account number is valid.
|
13
|
+
#
|
14
|
+
# Perform the second double alternate check, and for the double alternate check
|
15
|
+
# with exception 5 the checkdigit is h from the original account number, except:
|
16
|
+
# * After dividing the result by 10:
|
17
|
+
# - if the remainder = 0 and h = 0 the account number is valid
|
18
|
+
# - for all other remainders, take the remainder away from 10. If the number
|
19
|
+
# you get is the same as h then the account number is valid.
|
20
|
+
class Exception5 < BaseException
|
21
|
+
def apply_sort_code_substitutions
|
22
|
+
substitutions = UkAccountValidator.read_sort_code_substitution
|
23
|
+
|
24
|
+
return substitutions[sort_code] if substitutions.keys.include?(sort_code)
|
25
|
+
|
26
|
+
return sort_code
|
27
|
+
end
|
28
|
+
|
29
|
+
def override_test?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def test(modulus, total, test_digits, test)
|
34
|
+
if test == :double_alternate
|
35
|
+
check_digit = :h
|
36
|
+
else
|
37
|
+
check_digit = :g
|
38
|
+
end
|
39
|
+
|
40
|
+
check_sum = total % modulus
|
41
|
+
expected_sum = test_digits[NUMBER_INDEX[check_digit]].to_i
|
42
|
+
|
43
|
+
return false if check_sum == 1 && check_digit == :g
|
44
|
+
return true if check_sum == 0 && expected_sum == 0
|
45
|
+
|
46
|
+
return (modulus - check_sum) == expected_sum
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Indicates that these sorting codes may contain foreign currency accounts which
|
2
|
+
# cannot be checked.
|
3
|
+
# Perform the first and second checks, except:
|
4
|
+
# If a = 4, 5, 6, 7 or 8, and g and h are the same, the accounts are for a
|
5
|
+
# foreign currency and the checks cannot be used.
|
6
|
+
class Exception6 < BaseException
|
7
|
+
def replace_weight(test_digits)
|
8
|
+
a = test_digits[NUMBER_INDEX[:a]]
|
9
|
+
g = test_digits[NUMBER_INDEX[:g]]
|
10
|
+
h = test_digits[NUMBER_INDEX[:h]]
|
11
|
+
|
12
|
+
return zero_all if (a == 4 || a == 5 || a == 6 || a == 7 || a == 8) && g == h
|
13
|
+
|
14
|
+
return modulus_weight
|
15
|
+
end
|
16
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module UkAccountValidator
|
2
2
|
class ModulusWeight
|
3
|
-
|
3
|
+
attr_reader :sort_code_start, :sort_code_end, :modulus, :u, :v, :w, :x,
|
4
4
|
:y, :z, :a, :b, :c, :d, :e, :f, :g, :h, :exception
|
5
5
|
|
6
6
|
# the size of each column
|
@@ -11,7 +11,7 @@ module UkAccountValidator
|
|
11
11
|
# See https://www.ruby-forum.com/topic/184294#805359
|
12
12
|
data = definition_line.unpack("A#{COLUMN_SIZES.join('A')}")
|
13
13
|
|
14
|
-
data.map!
|
14
|
+
data.map!(&:strip)
|
15
15
|
|
16
16
|
@sort_code_start, @sort_code_end, @modulus, @u, @v, @w, @x,
|
17
17
|
@y, @z, @a, @b, @c, @d, @e, @f, @g, @h, @exception = data
|
@@ -11,7 +11,7 @@ module UkAccountValidator
|
|
11
11
|
@modulus_weights ||= UkAccountValidator.modulus_weights_table.find(sort_code)
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def modulus_validator(modulus)
|
15
15
|
case modulus
|
16
16
|
when 'MOD10'
|
17
17
|
Validators::Modulus10
|
@@ -26,35 +26,50 @@ module UkAccountValidator
|
|
26
26
|
|
27
27
|
def valid?
|
28
28
|
exceptions = modulus_weights.map(&:exception)
|
29
|
+
exception_class = self.exception_class(exceptions)
|
29
30
|
|
30
31
|
results = modulus_weights.each_with_index.map do |modulus_weight, i|
|
31
|
-
|
32
|
-
next Validator.new(account_number, '309634').valid?
|
33
|
-
end
|
32
|
+
exception = exception_class.new(modulus_weight, account_number, sort_code, i + 1)
|
34
33
|
|
35
|
-
|
34
|
+
@account_number = exception.apply_account_number_substitutions
|
35
|
+
|
36
|
+
modulus_validator(modulus_weight.modulus).new(
|
37
|
+
account_number, sort_code, modulus_weight, exception
|
38
|
+
).valid?
|
36
39
|
end
|
37
40
|
|
38
|
-
return results.any? if
|
39
|
-
return results.any? if exceptions.include?('10') && exceptions.include?('11')
|
40
|
-
return results.any? if exceptions.include?('12') && exceptions.include?('13')
|
41
|
-
return apply_exception_14 if !results.any? && exceptions.include?('14')
|
41
|
+
return results.any? if exception_class.allow_any?
|
42
42
|
|
43
43
|
results.all?
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
46
|
+
def exception_class(exception_strings)
|
47
|
+
case
|
48
|
+
when exception_strings.include?('1')
|
49
|
+
Exception1
|
50
|
+
when exception_strings.include?('2') && exception_strings.include?('9')
|
51
|
+
Exception29
|
52
|
+
when exception_strings.include?('3')
|
53
|
+
Exception3
|
54
|
+
when exception_strings.include?('4')
|
55
|
+
Exception4
|
56
|
+
when exception_strings.include?('5')
|
57
|
+
Exception5
|
58
|
+
when exception_strings.include?('6')
|
59
|
+
Exception6
|
60
|
+
when exception_strings.include?('7')
|
61
|
+
Exception7
|
62
|
+
when exception_strings.include?('8')
|
63
|
+
Exception8
|
64
|
+
when exception_strings.include?('10') && exception_strings.include?('11')
|
65
|
+
Exception10
|
66
|
+
when exception_strings.include?('12') && exception_strings.include?('13')
|
67
|
+
Exception12
|
68
|
+
when exception_strings.include?('14')
|
69
|
+
Exception14
|
70
|
+
else
|
71
|
+
BaseException
|
72
|
+
end
|
58
73
|
end
|
59
74
|
end
|
60
75
|
end
|
@@ -1,154 +1,28 @@
|
|
1
1
|
module UkAccountValidator
|
2
2
|
module Validators
|
3
3
|
class BaseValidator
|
4
|
-
|
5
|
-
u: 0,
|
6
|
-
v: 1,
|
7
|
-
w: 2,
|
8
|
-
x: 3,
|
9
|
-
y: 4,
|
10
|
-
z: 5,
|
11
|
-
a: 6,
|
12
|
-
b: 7,
|
13
|
-
c: 8,
|
14
|
-
d: 9,
|
15
|
-
e: 10,
|
16
|
-
f: 11,
|
17
|
-
g: 12,
|
18
|
-
h: 13
|
19
|
-
}
|
4
|
+
include NumberIndices
|
20
5
|
|
21
|
-
|
6
|
+
attr_reader :account_number, :sort_code, :modulus_weight, :exception
|
7
|
+
|
8
|
+
def initialize(account_number, sort_code, modulus_weight, exception)
|
22
9
|
@account_number = account_number
|
23
10
|
@sort_code = sort_code
|
24
11
|
@modulus_weight = modulus_weight
|
25
|
-
@
|
12
|
+
@exception = exception
|
26
13
|
|
27
|
-
@sort_code =
|
14
|
+
@sort_code = exception.apply_sort_code_substitutions
|
28
15
|
end
|
29
16
|
|
30
17
|
def applying_exceptions(test_digits)
|
31
|
-
|
32
|
-
apply_exception_3(test_digits) if @modulus_weight.exception == '3'
|
33
|
-
apply_exception_6(test_digits) if @modulus_weight.exception == '6'
|
34
|
-
apply_exception_7(test_digits) if @modulus_weight.exception == '7'
|
35
|
-
apply_exception_8(test_digits) if @modulus_weight.exception == '8'
|
36
|
-
apply_exception_10(test_digits) if @modulus_weight.exception == '10'
|
18
|
+
@modulus_weight = exception.replace_weight(test_digits)
|
37
19
|
|
38
20
|
total = yield
|
39
21
|
|
40
|
-
total
|
22
|
+
total = exception.after_calculate_total(total, test_digits)
|
41
23
|
|
42
24
|
total
|
43
25
|
end
|
44
|
-
|
45
|
-
def zero_all
|
46
|
-
@modulus_weight = ModulusWeight.new(
|
47
|
-
@modulus_weight.sort_code_start,
|
48
|
-
@modulus_weight.sort_code_end,
|
49
|
-
@modulus_weight.modulus,
|
50
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
51
|
-
@modulus_weight.exception
|
52
|
-
)
|
53
|
-
end
|
54
|
-
|
55
|
-
def zero_u_b
|
56
|
-
@modulus_weight = ModulusWeight.new(
|
57
|
-
@modulus_weight.sort_code_start,
|
58
|
-
@modulus_weight.sort_code_end,
|
59
|
-
@modulus_weight.modulus,
|
60
|
-
0, 0, 0, 0, 0, 0, 0, 0,
|
61
|
-
@modulus_weight.c, @modulus_weight.d, @modulus_weight.e,
|
62
|
-
@modulus_weight.f, @modulus_weight.g, @modulus_weight.h,
|
63
|
-
@modulus_weight.exception
|
64
|
-
)
|
65
|
-
end
|
66
|
-
|
67
|
-
def apply_exception_2_9(test_digits)
|
68
|
-
return if test_digits[NUMBER_INDEX[:a]] == 0
|
69
|
-
|
70
|
-
if test_digits[NUMBER_INDEX[:g]] != 9
|
71
|
-
@modulus_weight = ModulusWeight.new(
|
72
|
-
@modulus_weight.sort_code_start,
|
73
|
-
@modulus_weight.sort_code_end,
|
74
|
-
@modulus_weight.modulus,
|
75
|
-
0, 0, 1, 2, 5, 3, 6, 4, 8, 7, 10, 9, 3, 1,
|
76
|
-
@modulus_weight.exception
|
77
|
-
)
|
78
|
-
else
|
79
|
-
@modulus_weight = ModulusWeight.new(
|
80
|
-
@modulus_weight.sort_code_start,
|
81
|
-
@modulus_weight.sort_code_end,
|
82
|
-
@modulus_weight.modulus,
|
83
|
-
0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 10, 9, 3, 1,
|
84
|
-
@modulus_weight.exception
|
85
|
-
)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def apply_exception_3(test_digits)
|
90
|
-
c = test_digits[NUMBER_INDEX[:c]]
|
91
|
-
zero_all if c == 6 || c == 9
|
92
|
-
end
|
93
|
-
|
94
|
-
def apply_exception_4(total, test_digits)
|
95
|
-
check_sum = [test_digits[NUMBER_INDEX[:g]], test_digits[NUMBER_INDEX[:h]]].join
|
96
|
-
check_sum = check_sum.to_i
|
97
|
-
|
98
|
-
total % modulus == check_sum
|
99
|
-
end
|
100
|
-
|
101
|
-
def apply_exception_5_substitutions(sort_code)
|
102
|
-
substitutions = UkAccountValidator.read_sort_code_substitution
|
103
|
-
|
104
|
-
if substitutions.keys.include?(sort_code)
|
105
|
-
sort_code = substitutions[sort_code]
|
106
|
-
end
|
107
|
-
|
108
|
-
return sort_code
|
109
|
-
end
|
110
|
-
|
111
|
-
def apply_exception_5(total, test_digits, check_digit)
|
112
|
-
check_sum = total % modulus
|
113
|
-
expected_sum = test_digits[NUMBER_INDEX[check_digit]].to_i
|
114
|
-
|
115
|
-
return false if check_sum == 1 && check_digit == :g
|
116
|
-
return true if check_sum == 0 && expected_sum == 0
|
117
|
-
|
118
|
-
return (modulus - check_sum) == expected_sum
|
119
|
-
end
|
120
|
-
|
121
|
-
# If a = 4, 5, 6, 7 or 8, and g and h are the same
|
122
|
-
def apply_exception_6(test_digits)
|
123
|
-
a = test_digits[NUMBER_INDEX[:a]]
|
124
|
-
g = test_digits[NUMBER_INDEX[:g]]
|
125
|
-
h = test_digits[NUMBER_INDEX[:h]]
|
126
|
-
|
127
|
-
zero_all if (a == 4 || a == 5 || a == 6 || a == 7 || a == 8) && g == h
|
128
|
-
end
|
129
|
-
|
130
|
-
def apply_exception_7(test_digits)
|
131
|
-
return unless test_digits[NUMBER_INDEX[:g]] == 9
|
132
|
-
|
133
|
-
zero_u_b
|
134
|
-
end
|
135
|
-
|
136
|
-
def apply_exception_8(test_digits)
|
137
|
-
test_string = '090126' + @account_number
|
138
|
-
|
139
|
-
test_digits.replace(test_string.split(//).map(&:to_i))
|
140
|
-
end
|
141
|
-
|
142
|
-
def apply_exception_10(test_digits)
|
143
|
-
# if ab = 09 or 99 and g=9, zeroise weighting positions u-b.
|
144
|
-
a = test_digits[NUMBER_INDEX[:a]]
|
145
|
-
b = test_digits[NUMBER_INDEX[:b]]
|
146
|
-
|
147
|
-
return unless (a == 0 && b == 9) ||
|
148
|
-
(a == 9 && b == 9 && test_digits[NUMBER_INDEX[:g]] == 9)
|
149
|
-
|
150
|
-
zero_u_b
|
151
|
-
end
|
152
26
|
end
|
153
27
|
end
|
154
28
|
end
|
@@ -24,11 +24,8 @@ module UkAccountValidator
|
|
24
24
|
weighted_test_digits.inject(:+)
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
return apply_exception_4(total, test_digits)
|
30
|
-
when '5'
|
31
|
-
return apply_exception_5(total, test_digits, :h)
|
27
|
+
if exception.override_test?
|
28
|
+
return exception.test(modulus, total, test_digits, :double_alternate)
|
32
29
|
end
|
33
30
|
|
34
31
|
total % modulus == 0
|
@@ -7,7 +7,7 @@ module UkAccountValidator
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def valid?
|
10
|
-
test_string =
|
10
|
+
test_string = sort_code + account_number
|
11
11
|
|
12
12
|
test_digits = test_string.split(//).map(&:to_i)
|
13
13
|
|
@@ -15,15 +15,12 @@ module UkAccountValidator
|
|
15
15
|
NUMBER_INDEX.each_pair.reduce(0) do |t, pair|
|
16
16
|
weight, index = pair
|
17
17
|
|
18
|
-
t +
|
18
|
+
t + modulus_weight.send(weight) * test_digits[index]
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
return apply_exception_4(total, test_digits)
|
25
|
-
when '5'
|
26
|
-
return apply_exception_5(total, test_digits, :g)
|
22
|
+
if exception.override_test?
|
23
|
+
return exception.test(modulus, total, test_digits, :standard_modulus)
|
27
24
|
end
|
28
25
|
|
29
26
|
total % modulus == 0
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ['hayden@haydenball.me.uk']
|
11
11
|
spec.summary = 'Validate UK Account Numbers and Sort Codes'
|
12
12
|
spec.description = spec.summary
|
13
|
-
spec.homepage = ''
|
13
|
+
spec.homepage = 'https://github.com/ball-hayden/uk_account_validator'
|
14
14
|
spec.license = '2 Clause BSD'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uk_account_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hayden Ball
|
@@ -37,8 +37,21 @@ files:
|
|
37
37
|
- features/support/env.rb
|
38
38
|
- features/two_modulus_check.feature
|
39
39
|
- lib/uk_account_validator.rb
|
40
|
+
- lib/uk_account_validator/exceptions/base_exception.rb
|
41
|
+
- lib/uk_account_validator/exceptions/exception_1.rb
|
42
|
+
- lib/uk_account_validator/exceptions/exception_10.rb
|
43
|
+
- lib/uk_account_validator/exceptions/exception_12.rb
|
44
|
+
- lib/uk_account_validator/exceptions/exception_14.rb
|
45
|
+
- lib/uk_account_validator/exceptions/exception_2_9.rb
|
46
|
+
- lib/uk_account_validator/exceptions/exception_3.rb
|
47
|
+
- lib/uk_account_validator/exceptions/exception_4.rb
|
48
|
+
- lib/uk_account_validator/exceptions/exception_5.rb
|
49
|
+
- lib/uk_account_validator/exceptions/exception_6.rb
|
50
|
+
- lib/uk_account_validator/exceptions/exception_7.rb
|
51
|
+
- lib/uk_account_validator/exceptions/exception_8.rb
|
40
52
|
- lib/uk_account_validator/modulus_weight.rb
|
41
53
|
- lib/uk_account_validator/modulus_weights_table.rb
|
54
|
+
- lib/uk_account_validator/number_indices.rb
|
42
55
|
- lib/uk_account_validator/validator.rb
|
43
56
|
- lib/uk_account_validator/validators/base_validator.rb
|
44
57
|
- lib/uk_account_validator/validators/double_alternate.rb
|
@@ -47,7 +60,7 @@ files:
|
|
47
60
|
- lib/uk_account_validator/validators/standard_modulus.rb
|
48
61
|
- lib/uk_account_validator/version.rb
|
49
62
|
- uk_account_validator.gemspec
|
50
|
-
homepage:
|
63
|
+
homepage: https://github.com/ball-hayden/uk_account_validator
|
51
64
|
licenses:
|
52
65
|
- 2 Clause BSD
|
53
66
|
metadata: {}
|
@@ -82,3 +95,4 @@ test_files:
|
|
82
95
|
- features/step_definitions/modulus_weights_table.rb
|
83
96
|
- features/support/env.rb
|
84
97
|
- features/two_modulus_check.feature
|
98
|
+
has_rdoc:
|