Class: ISO::IBAN
- Inherits:
-
Object
- Object
- ISO::IBAN
- Includes:
- Comparable
- Defined in:
- lib/iso/iban/no_autoload.rb,
lib/iso/iban/version.rb,
lib/iso/iban/invalid.rb,
lib/iso/iban/specification.rb
Overview
IBAN - ISO 13616-1
Usage
require 'iso/iban'
ISO::IBAN.valid?('CH35 1234 5987 6543 2109 A') # => true
ISO::IBAN.validate('CH37 1234 5987 6543 2109 A') # => [:invalid_checksum]
ISO::IBAN.generate('CH', '12345', '987') # => #<ISO::IBAN CH76 1234 5000 0000 0098 7>
iban = ISO::IBAN.parse('CH35 1234 5987 6543 2109 A') # => #<ISO::IBAN CH35 1234 5987 6543 2109 A>
iban = ISO::IBAN.new('CH351234598765432109A') # => #<ISO::IBAN CH35 1234 5987 6543 2109 A>
iban.formatted # => "CH35 1234 5987 6543 2109 A"
iban.compact # => "CH351234598765432109A"
iban.country # => "CH"
iban.checksum_digits # => "35"
iban.bank_code # => "12345"
iban.account_code # => "98765432109A"
iban.valid? # => true
iban.validate # => []
General IBAN Information
-
What is an IBAN?
IBAN stands for International Bank Account Number. It is the ISO 13616 international standard for numbering bank accounts. In 2006, the International Organization for Standardization (ISO) designated SWIFT as the Registration Authority for ISO 13616. -
Use
The IBAN facilitates the communication and processing of cross-border transactions. It allows exchanging account identification details in a machine-readable form.
The ISO 13616 IBAN Standard
-
Structure
The IBAN structure is defined in ISO 13616-1 and consists of a two-letter ISO 3166-1 country code, followed by two check digits and up to thirty alphanumeric characters for a BBAN (Basic Bank Account Number) which has a fixed length per country and, included within it, a bank identifier with a fixed position and a fixed length per country. The check digits are calculated based on the scheme defined in ISO/IEC 7064 (MOD97-10). -
Terms and definitions
-
Bank identifier: The identifier that uniquely identifies the financial institution and, when appropriate, the branch of that financial institution servicing an account.
-
BBAN: basic bank account number: The identifier that uniquely identifies an individual account, at a specific financial institution, in a particular country. The BBAN includes a bank identifier of the financial institution servicing that account.
-
IBAN: international bank account number: The expanded version of the basic bank account number (BBAN), intended for use internationally. The IBAN uniquely identifies an individual account, at a specific financial institution, in a particular country.
-
-
Submitters
Nationally-agreed, ISO13616-compliant IBAN formats are submitted to the registration authority exclusively by the National Standards Body or the National Central Bank of the country.
Defined Under Namespace
Classes: Invalid, Specification
Constant Summary
- Version =
Note:
require 'iso/iban' loads the version.
The version of the sorting gem.
Gem::Version.new("0.1.0")
- CharacterCodes =
Character code translation used to convert an IBAN into its numeric (digits-only) form
Hash[('0'..'9').zip('0'..'9')+('a'..'z').zip(10..35)+('A'..'Z').zip(10..35)]
- UpperAlpha =
All uppercase letters
[*'A'..'Z']
- LowerAlpha =
All lowercase letters
[*'a'..'z']
- Digits =
All digits
[*'0'..'9']
- AlphaNumeric =
All uppercase letters, lowercase letters and digits
[*'A'..'Z', *'a'..'z', *'0'..'9']
Instance Attribute Summary (collapse)
-
- (String) compact
readonly
The standard form of the IBAN for machine communication, without spaces, encoded in Encoding::BINARY.
-
- (String) country
readonly
The ISO-3166 2-letter country code (first and second character).
-
- (ISO::IBAN::Specification) specification
readonly
The specification for this IBAN (determined by its country).
Class Method Summary (collapse)
-
+ (Object) generate(country, *components)
Generate an IBAN from country code and components, automatically filling in the checksum.
-
+ (self) load_specifications(spec_file = nil)
Load the IBAN specifications file, which determines how the IBAN for any given country looks.
-
+ (String) numerify(string)
Converts a String into its digits-only form, i.e.
-
+ (ISO::IBAN) parse(iban_number)
An IBAN instance representing the passed IBAN number.
-
+ (ISO::IBAN) parse!(iban_number)
Like ISO::IBAN.parse, but raises an ISO::IBAN::Invalid exception if the IBAN is invalid.
-
+ (ISO::IBAN) random(*countries)
A random, valid IBAN.
-
+ (ISO::IBAN::Specification) specification(a2_country_code, *default, &default_block)
The specification for the given country.
-
+ (Hash<String => ISO::IBAN::Specification>) specifications
A hash with the country (ISO3166 2-letter) as key and the specification for that country as value.
-
+ (String) strip(iban)
The IBAN in compact form, all whitespace and dashes stripped.
-
+ (true, false) valid?(iban)
Whether the IBAN is valid.
-
+ (Array<Symbol>) validate(iban)
An array with a code of all validation errors, empty if valid.
Instance Method Summary (collapse)
-
- (-1, ...) <=>(other)
See Object#.
-
- (String) account_code
The account code part of the IBAN.
-
- (String?) bank_code
The bank code part of the IBAN, nil if not applicable.
-
- (String) bban
The BBAN of the IBAN (everything except the country code and check digits).
-
- (String?) branch_code
The branch code part of the IBAN, nil if not applicable.
-
- (String) calculated_check_digits
The check-digits as calculated from the IBAN.
-
- (String) checksum_digits
The checksum digits in the IBAN (character 3 & 4).
-
- (true, false) eql?(other)
Whether two ISO::IBANs are equal.
-
- (String) formatted
The IBAN in its formatted form, which is more human readable than the compact form.
-
- (Integer) hash
A hash value, see Object#hash.
-
- (IBAN) initialize(iban)
constructor
A new instance of IBAN.
-
- (Object) inspect
See Object#inspect.
-
- (Array) invalid_characters(input_encoding = nil)
An Array with all invalid characters.
-
- (Integer?) numeric
IBAN in its numeric form, i.e.
-
- (Array) to_a
The individual IBAN components as defined by the SWIFT specification.
-
- (String) to_s
The compact form of the IBAN as a String.
-
- (self) update_checksum!
Requires that the checksum digits were left as '??', replaces them with the proper checksum.
-
- (true, false) valid?
Whether the IBAN is valid.
-
- (true, false) valid_characters?
Whether IBAN consists only of valid characters.
-
- (true, false) valid_checksum?
Whether the checksum of the IBAN is valid.
-
- (true, false) valid_country?
Whether the country of the IBAN is valid.
-
- (true, false) valid_format?
Whether the format of the IBAN is valid.
-
- (true, false) valid_length?
Whether the length of the IBAN is valid.
-
- (Array<Symbol>) validate
Error codes:.
Constructor Details
- (IBAN) initialize(iban)
Returns a new instance of IBAN
280 281 282 283 284 285 286 |
# File 'lib/iso/iban/no_autoload.rb', line 280 def initialize(iban) raise ArgumentError, "String expected for iban, but got #{iban.class}" unless iban.is_a?(String) @compact = iban.b @country = iban[0,2] @specification = self.class.specification(@country, nil) end |
Instance Attribute Details
- (String) compact (readonly)
Returns The standard form of the IBAN for machine communication, without spaces, encoded in Encoding::BINARY.
270 271 272 |
# File 'lib/iso/iban/no_autoload.rb', line 270 def compact @compact end |
- (String) country (readonly)
Returns The ISO-3166 2-letter country code (first and second character).
273 274 275 |
# File 'lib/iso/iban/no_autoload.rb', line 273 def country @country end |
- (ISO::IBAN::Specification) specification (readonly)
Returns The specification for this IBAN (determined by its country).
276 277 278 |
# File 'lib/iso/iban/no_autoload.rb', line 276 def specification @specification end |
Class Method Details
+ (Object) generate(country, *components)
generate
will pad all segments with zeros, which means it will
generate invalid IBANs if you provide too short segments which are
alphabetic only.
For example, ISO::IBAN.generate('BG',
'A', '2', 'C')
generates an invalid IBAN.
Generate an IBAN from country code and components, automatically filling in the checksum.
218 219 220 221 222 223 224 225 |
# File 'lib/iso/iban/no_autoload.rb', line 218 def self.generate(country, *components) spec = specification(country) justified = spec.component_lengths.zip(components).map { |length, component| component.rjust(length, "0") } iban = new(country+'??'+justified.join('')) iban.update_checksum! iban end |
+ (self) load_specifications(spec_file = nil)
Using require 'iso/iban'
will automatically invoke
this method. If you do not wish this behavior, require
'iso/iban/no_autoload'
instead.
Load the IBAN specifications file, which determines how the IBAN for any given country looks.
It will use the following sources in this order (first one which exists wins)
-
Path passed as
spec_file
parameter -
Path provided by the env variable
IBAN_SPECIFICATIONS
-
The file
../data/iso-iban/specs.yaml
relative to the lib dir -
The Gem datadir path
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/iso/iban/no_autoload.rb', line 115 def self.load_specifications(spec_file=nil) if spec_file then # do nothing elsif ENV['IBAN_SPECIFICATIONS'] then spec_file = ENV['IBAN_SPECIFICATIONS'] else spec_file = File.('../../../../data/iso-iban/specs.yaml', __FILE__) if !File.file?(spec_file) && defined?(Gem) && Gem.datadir('iso-iban') spec_file = Gem.datadir('iso-iban')+'/specs.yaml' end end if spec_file && File.file?(spec_file) @specifications = ISO::IBAN::Specification.load_yaml(spec_file) elsif spec_file raise "Could not load IBAN specifications, specs file #{spec_file.inspect} does not exist or can't be read." else raise "Could not load IBAN specifications, no specs file found." end self end |
+ (String) numerify(string)
Converts a String into its digits-only form, i.e. all characters a-z are replaced with their corresponding digit sequences, according to the IBAN specification.
261 262 263 264 265 266 267 |
# File 'lib/iso/iban/no_autoload.rb', line 261 def self.numerify(string) string.downcase.gsub(/\D/) { |char| CharacterCodes.fetch(char) { raise ArgumentError, "The string contains an invalid character #{char.inspect}" } }.to_i end |
+ (ISO::IBAN) parse(iban_number)
Returns An IBAN instance representing the passed IBAN number.
201 202 203 |
# File 'lib/iso/iban/no_autoload.rb', line 201 def self.parse(iban_number) new(strip(iban_number)) end |
+ (ISO::IBAN) parse!(iban_number)
Like ISO::IBAN.parse, but raises an ISO::IBAN::Invalid exception if the IBAN is invalid.
189 190 191 192 193 194 |
# File 'lib/iso/iban/no_autoload.rb', line 189 def self.parse!(iban_number) iban = parse(iban_number) raise Invalid.new(iban) unless iban.valid? iban end |
+ (ISO::IBAN) random(*countries)
Returns A random, valid IBAN.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/iso/iban/no_autoload.rb', line 231 def self.random(*countries) countries = specifications.keys if countries.empty? country = countries.sample account = specification(country).iban_structure.scan(/([A-Z]+)|(\d+)(!?)([nac])/).map { |exact, length, fixed, code| if exact exact elsif code == 'a' Array.new(length.to_i) { UpperAlpha.sample }.join('') elsif code == 'c' Array.new(length.to_i) { AlphaNumeric.sample }.join('') elsif code == 'e' ' '*length.to_i elsif code == 'n' Array.new(length.to_i) { Digits.sample }.join('') end }.join('') account[2,2] = '??' iban = new(account) iban.update_checksum! iban end |
+ (ISO::IBAN::Specification) specification(a2_country_code, *default, &default_block)
Returns The specification for the given country.
149 150 151 |
# File 'lib/iso/iban/no_autoload.rb', line 149 def self.specification(a2_country_code, *default, &default_block) specifications.fetch(a2_country_code, *default, &default_block) end |
+ (Hash<String => ISO::IBAN::Specification>) specifications
Returns A hash with the country (ISO3166 2-letter) as key and the specification for that country as value.
140 141 142 |
# File 'lib/iso/iban/no_autoload.rb', line 140 def self.specifications @specifications || raise("No specifications have been loaded yet - Check the docs for ISO::IBAN::load_specifications.") end |
+ (String) strip(iban)
Returns The IBAN in compact form, all whitespace and dashes stripped.
178 179 180 |
# File 'lib/iso/iban/no_autoload.rb', line 178 def self.strip(iban) iban.delete("\n\r\t -") end |
+ (true, false) valid?(iban)
Returns Whether the IBAN is valid.
See #validate for details.
159 160 161 |
# File 'lib/iso/iban/no_autoload.rb', line 159 def self.valid?(iban) parse(iban).valid? end |
+ (Array<Symbol>) validate(iban)
Returns An array with a code of all validation errors, empty if valid.
See #validate for details.
169 170 171 |
# File 'lib/iso/iban/no_autoload.rb', line 169 def self.validate(iban) parse(iban).validate end |
Instance Method Details
- (-1, ...) <=>(other)
See Object#<=>
425 426 427 |
# File 'lib/iso/iban/no_autoload.rb', line 425 def <=>(other) other.respond_to?(:compact) ? @compact <=> other.compact : nil end |
- (String) account_code
Returns The account code part of the IBAN.
373 374 375 |
# File 'lib/iso/iban/no_autoload.rb', line 373 def account_code @compact[((@specification.branch_position_to || @specification.bank_position_to || 3)+1)..-1] end |
- (String?) bank_code
Returns The bank code part of the IBAN, nil if not applicable.
355 356 357 358 359 360 361 |
# File 'lib/iso/iban/no_autoload.rb', line 355 def bank_code if @specification && @specification.bank_position_from && @specification.bank_position_to @compact[@specification.bank_position_from..@specification.bank_position_to] else nil end end |
- (String) bban
Returns The BBAN of the IBAN (everything except the country code and check digits).
350 351 352 |
# File 'lib/iso/iban/no_autoload.rb', line 350 def bban @compact[4..-1] end |
- (String?) branch_code
Returns The branch code part of the IBAN, nil if not applicable.
364 365 366 367 368 369 370 |
# File 'lib/iso/iban/no_autoload.rb', line 364 def branch_code if @specification && @specification.branch_position_from && @specification.branch_position_to @compact[@specification.branch_position_from..@specification.branch_position_to] else nil end end |
- (String) calculated_check_digits
Returns The check-digits as calculated from the IBAN.
442 443 444 |
# File 'lib/iso/iban/no_autoload.rb', line 442 def calculated_check_digits "%02d" % (98-(self.class.numerify(bban+@country)*100)%97) end |
- (String) checksum_digits
Returns The checksum digits in the IBAN (character 3 & 4).
345 346 347 |
# File 'lib/iso/iban/no_autoload.rb', line 345 def checksum_digits @compact[2,2] end |
- (true, false) eql?(other)
Returns Whether two ISO::IBANs are equal. Comparison is based on class and IBAN number
449 450 451 |
# File 'lib/iso/iban/no_autoload.rb', line 449 def eql?(other) self.class.equal?(other.class) && self == other end |
- (String) formatted
Returns The IBAN in its formatted form, which is more human readable than the compact form.
293 294 295 |
# File 'lib/iso/iban/no_autoload.rb', line 293 def formatted @_formatted ||= @compact.gsub(/.{4}(?=.)/, '\0 ') end |
- (Integer) hash
Returns A hash value, see Object#hash
455 456 457 |
# File 'lib/iso/iban/no_autoload.rb', line 455 def hash [self.class, @compact].hash end |
- (Object) inspect
See Object#inspect
460 461 462 |
# File 'lib/iso/iban/no_autoload.rb', line 460 def inspect sprintf "#<%p %s>", self.class, formatted end |
- (Array) invalid_characters(input_encoding = nil)
Returns An Array with all invalid characters.
389 390 391 392 393 |
# File 'lib/iso/iban/no_autoload.rb', line 389 def invalid_characters(input_encoding=nil) iban = input_encoding ? @compact.dup.force_encoding(input_encoding) : @compact iban.gsub(/[A-Z0-9?]*/i, '').chars.uniq end |
- (Integer?) numeric
Returns IBAN in its numeric form, i.e. all characters a-z are replaced with
their corresponding digit sequences.
Will return nil if the IBAN is
shorter than 5 characters (which makes it invalid).
301 302 303 |
# File 'lib/iso/iban/no_autoload.rb', line 301 def numeric @compact.size < 5 ? nil : self.class.numerify(@compact[4..-1]+@compact[0,4]) end |
- (Array) to_a
This method is experimental. It might change or be removed in future versions!
Returns The individual IBAN components as defined by the SWIFT specification. An empty array if this IBAN does not have a specification.
475 476 477 478 479 |
# File 'lib/iso/iban/no_autoload.rb', line 475 def to_a @_components ||= @specification ? @compact.match(@specification.iban_regex).captures : [] @_components.dup end |
- (String) to_s
Returns The compact form of the IBAN as a String.
465 466 467 |
# File 'lib/iso/iban/no_autoload.rb', line 465 def to_s @compact.dup end |
- (self) update_checksum!
Requires that the checksum digits were left as '??', replaces them with the proper checksum.
433 434 435 436 437 438 439 |
# File 'lib/iso/iban/no_autoload.rb', line 433 def update_checksum! raise "Checksum digit placeholders missing" unless @compact[2,2] == '??' @compact[2,2] = calculated_check_digits self end |
- (true, false) valid?
Returns Whether the IBAN is valid. See #validate for details.
308 309 310 |
# File 'lib/iso/iban/no_autoload.rb', line 308 def valid? valid_country? && valid_checksum? && valid_length? && valid_format? end |
- (true, false) valid_characters?
Returns Whether IBAN consists only of valid characters.
396 397 398 |
# File 'lib/iso/iban/no_autoload.rb', line 396 def valid_characters? @compact =~ /\A[A-Z]{2}(?:\d\d|\?\?)[A-Z0-9]*\z/in ? true : false end |
- (true, false) valid_checksum?
Returns Whether the checksum of the IBAN is valid.
416 417 418 419 420 |
# File 'lib/iso/iban/no_autoload.rb', line 416 def valid_checksum? numerified = numeric() numerified && (numerified % 97 == 1) end |
- (true, false) valid_country?
Returns Whether the country of the IBAN is valid.
401 402 403 |
# File 'lib/iso/iban/no_autoload.rb', line 401 def valid_country? @specification ? true : false end |
- (true, false) valid_format?
Returns Whether the format of the IBAN is valid.
406 407 408 |
# File 'lib/iso/iban/no_autoload.rb', line 406 def valid_format? @specification && @specification.iban_regex =~ @compact ? true : false end |
- (true, false) valid_length?
Returns Whether the length of the IBAN is valid.
411 412 413 |
# File 'lib/iso/iban/no_autoload.rb', line 411 def valid_length? @specification && @compact.size == @specification.iban_length ? true : false end |
- (Array<Symbol>) validate
The class method validate uses parse, which means
it will strip whitespace and dashes from the IBAN.
#initialize on the other hand expects the IBAN in compact format
and will not strip those characters.
Error codes:
-
:invalid_characters
-
:invalid_country
-
:invalid_checksum
-
:invalid_length
-
:invalid_format
Invalid characters means that the IBAN contains characters which are not in
the set of A-Za-z0-9. See #invalid_characters.
Invalid country means
the country is unknown (character 1 & 2 in the IBAN).
Invalid
checksum means the two check digits (character 3 & 4 in the IBAN).
Invalid length means the IBAN does not comply with the length specified for
the country of that IBAN.
Invalid format means the IBAN does not comply
with the format specified for the country of that IBAN.
333 334 335 336 337 338 339 340 341 342 |
# File 'lib/iso/iban/no_autoload.rb', line 333 def validate errors = [] errors << :invalid_characters unless valid_characters? errors << :invalid_country unless valid_country? errors << :invalid_checksum unless valid_characters? && valid_checksum? errors << :invalid_length unless valid_length? errors << :invalid_format unless valid_format? errors end |