Class: ISO::IBAN::Specification
- Inherits:
-
Object
- Object
- ISO::IBAN::Specification
- Defined in:
- lib/iso/iban/specification.rb
Overview
Specification of the IBAN format for one country. Every country has its own specification of the IBAN format. SWIFT is the official authority where those formats are registered.
Constant Summary collapse
- StructureCodes =
A mapping from SWIFT structure specification to PCRE regex.
{ 'n' => '\d', 'a' => '[A-Z]', 'c' => '[A-Za-z0-9]', 'e' => ' ', }
Instance Attribute Summary collapse
-
#a2_country_code ⇒ Object
readonly
Returns the value of attribute a2_country_code.
-
#bank_position_from ⇒ Object
readonly
Returns the value of attribute bank_position_from.
-
#bank_position_to ⇒ Object
readonly
Returns the value of attribute bank_position_to.
-
#bban_length ⇒ Object
readonly
Returns the value of attribute bban_length.
-
#bban_structure ⇒ Object
readonly
Returns the value of attribute bban_structure.
-
#branch_position_from ⇒ Object
readonly
Returns the value of attribute branch_position_from.
-
#branch_position_to ⇒ Object
readonly
Returns the value of attribute branch_position_to.
-
#country_name ⇒ Object
readonly
Returns the value of attribute country_name.
-
#iban_length ⇒ Object
readonly
Returns the value of attribute iban_length.
-
#iban_structure ⇒ Object
readonly
Returns the value of attribute iban_structure.
Class Method Summary collapse
-
.load_yaml(path) ⇒ Hash<String => ISO::IBAN::Specification>
Load the specifications YAML.
-
.parse_file(path) ⇒ Array<ISO::IBAN::Specification>
Parse the SWIFT provided file (which sadly is a huge mess and not machine friendly at all).
-
.structure_regex(structure, anchored = true) ⇒ Object
*n: Digits (numeric characters 0 to 9 only) *a: Upper case letters (alphabetic characters A-Z only) *c: upper and lower case alphanumeric characters (A-Z, a-z and 0-9) *e: blank space *nn!: fixed length *nn: maximum length.
Instance Method Summary collapse
-
#account_code_length ⇒ Fixnum
The length of the account code in the IBAN.
-
#bank_code_length ⇒ Fixnum
The length of the bank code in the IBAN, 0 if the IBAN has no bank code.
-
#branch_code_length ⇒ Fixnum
The length of the bank code in the IBAN, 0 if the IBAN has no branch code.
-
#component_lengths ⇒ Array<Integer>
An array with the lengths of all components.
-
#iban_regex ⇒ Regexp
A regex to verify the structure of the IBAN.
-
#initialize(country_name, a2_country_code, iban_structure, iban_length, bban_structure, bban_length, bank_position_from, bank_position_to, branch_position_from, branch_position_to) ⇒ Specification
constructor
A new instance of Specification.
-
#to_a ⇒ Array
An array with the Specification properties.
-
#unanchored_iban_regex ⇒ Regexp
A regex to identify the structure of the IBAN, without anchors.
Constructor Details
#initialize(country_name, a2_country_code, iban_structure, iban_length, bban_structure, bban_length, bank_position_from, bank_position_to, branch_position_from, branch_position_to) ⇒ Specification
Returns a new instance of Specification.
87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/iso/iban/specification.rb', line 87 def initialize(country_name, a2_country_code, iban_structure, iban_length, bban_structure, bban_length, bank_position_from, bank_position_to, branch_position_from, branch_position_to) @country_name = country_name @a2_country_code = a2_country_code @iban_structure = iban_structure @iban_length = iban_length @bban_structure = bban_structure @bban_length = bban_length @bank_position_from = bank_position_from @bank_position_to = bank_position_to @branch_position_from = branch_position_from @branch_position_to = branch_position_to end |
Instance Attribute Details
#a2_country_code ⇒ Object (readonly)
Returns the value of attribute a2_country_code.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def a2_country_code @a2_country_code end |
#bank_position_from ⇒ Object (readonly)
Returns the value of attribute bank_position_from.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def bank_position_from @bank_position_from end |
#bank_position_to ⇒ Object (readonly)
Returns the value of attribute bank_position_to.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def bank_position_to @bank_position_to end |
#bban_length ⇒ Object (readonly)
Returns the value of attribute bban_length.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def bban_length @bban_length end |
#bban_structure ⇒ Object (readonly)
Returns the value of attribute bban_structure.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def bban_structure @bban_structure end |
#branch_position_from ⇒ Object (readonly)
Returns the value of attribute branch_position_from.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def branch_position_from @branch_position_from end |
#branch_position_to ⇒ Object (readonly)
Returns the value of attribute branch_position_to.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def branch_position_to @branch_position_to end |
#country_name ⇒ Object (readonly)
Returns the value of attribute country_name.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def country_name @country_name end |
#iban_length ⇒ Object (readonly)
Returns the value of attribute iban_length.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def iban_length @iban_length end |
#iban_structure ⇒ Object (readonly)
Returns the value of attribute iban_structure.
76 77 78 |
# File 'lib/iso/iban/specification.rb', line 76 def iban_structure @iban_structure end |
Class Method Details
.load_yaml(path) ⇒ Hash<String => ISO::IBAN::Specification>
Load the specifications YAML.
22 23 24 |
# File 'lib/iso/iban/specification.rb', line 22 def self.load_yaml(path) Hash[YAML.load_file(path).map { |country, spec| [country, new(*spec)] }] end |
.parse_file(path) ⇒ Array<ISO::IBAN::Specification>
Parse the SWIFT provided file (which sadly is a huge mess and not machine friendly at all).
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 |
# File 'lib/iso/iban/specification.rb', line 29 def self.parse_file(path) File.read(path, encoding: Encoding::Windows_1252).encode(Encoding::UTF_8).split("\r\n").tap(&:shift).flat_map { |line| country_name, country_codes, iban_structure_raw, iban_length, bban_structure, bban_length, bank_position = line.split(/\t/).values_at(0,1,11,12,4,5,6) codes = country_codes.size == 2 ? [country_codes] : country_codes.scan(/\b[A-Z]{2}\b/) primary_code = codes.first bank_position_from, bank_position_to, branch_position_from, branch_position_to = bank_position.match(/(?:[Pp]ositions?|) (\d+)-(\d+)(?:.*Branch identifier positions?: (\d+)-(\d+))?/).captures.map { |pos| pos && pos.to_i+3 } codes.map { |a2_country_code| iban_structure = iban_structure_raw[/#{a2_country_code}[acen\!\d]*/] || iban_structure_raw[/#{primary_code}[acen\!\d]*/] bban_structure = bban_structure[/[acen\!\d]*/] new( country_name.strip, a2_country_code, iban_structure, iban_length.to_i, bban_structure.strip, bban_length.to_i, bank_position_from, bank_position_to, branch_position_from, branch_position_to ) } } end |
.structure_regex(structure, anchored = true) ⇒ Object
*n: Digits (numeric characters 0 to 9 only) *a: Upper case letters (alphabetic characters A-Z only) *c: upper and lower case alphanumeric characters (A-Z, a-z and 0-9) *e: blank space *nn!: fixed length *nn: maximum length
Example: "AL2!n8!n16!c"
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/iso/iban/specification.rb', line 64 def self.structure_regex(structure, anchored=true) source = structure.scan(/([A-Z]+)|(\d+)(!?)([nac])/).map { |exact, length, fixed, code| if exact Regexp.escape(exact) else StructureCodes[code]+(fixed ? "{#{length}}" : "{,#{length}}") end }.join(')(') anchored ? /\A(#{source})\z/ : /(#{source})/n end |
Instance Method Details
#account_code_length ⇒ Fixnum
Returns The length of the account code in the IBAN.
129 130 131 |
# File 'lib/iso/iban/specification.rb', line 129 def account_code_length bban_length-bank_code_length-branch_code_length end |
#bank_code_length ⇒ Fixnum
Returns The length of the bank code in the IBAN, 0 if the IBAN has no bank code.
117 118 119 |
# File 'lib/iso/iban/specification.rb', line 117 def bank_code_length @bank_position_from && @bank_position_to ? @bank_position_to-@bank_position_from+1 : 0 end |
#branch_code_length ⇒ Fixnum
Returns The length of the bank code in the IBAN, 0 if the IBAN has no branch code.
123 124 125 |
# File 'lib/iso/iban/specification.rb', line 123 def branch_code_length @branch_position_from && @branch_position_to ? @branch_position_to-@branch_position_from+1 : 0 end |
#component_lengths ⇒ Array<Integer>
Returns An array with the lengths of all components.
111 112 113 |
# File 'lib/iso/iban/specification.rb', line 111 def component_lengths [bank_code_length, branch_code_length, account_code_length].tap { |lengths| lengths.delete(0) } end |
#iban_regex ⇒ Regexp
Returns A regex to verify the structure of the IBAN.
101 102 103 |
# File 'lib/iso/iban/specification.rb', line 101 def iban_regex @_iban_regex ||= self.class.structure_regex(@iban_structure) end |
#to_a ⇒ Array
Returns An array with the Specification properties. Used for serialization.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/iso/iban/specification.rb', line 134 def to_a [ @country_name, @a2_country_code, @iban_structure, @iban_length, @bban_structure, @bban_length, @bank_position_from, @bank_position_to, @branch_position_from, @branch_position_to, ] end |
#unanchored_iban_regex ⇒ Regexp
Returns A regex to identify the structure of the IBAN, without anchors.
106 107 108 |
# File 'lib/iso/iban/specification.rb', line 106 def unanchored_iban_regex self.class.structure_regex(@iban_structure, false) end |