uk_account_validator 0.0.1 → 0.0.2
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/.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:
|