iban-tools 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +50 -0
- data/lib/iban-tools.rb +26 -0
- data/lib/iban-tools/iban.rb +88 -0
- data/lib/iban-tools/iban_rules.rb +32 -0
- data/lib/iban-tools/rules.yml +242 -0
- metadata +60 -0
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# iban-tools
|
2
|
+
|
3
|
+
iban-tools is a Ruby library for manipulating and validating IBAN account numbers. You can [read more about IBAN](http://en.wikipedia.org/wiki/International_Bank_Account_Number) on Wikipedia
|
4
|
+
|
5
|
+
## Credit
|
6
|
+
|
7
|
+
[Iulianu](http://github.com/iulianu) wrote [iban-tools](http://github.com/iulianu/iban-tools). We just removed use of `String#ord` for compatibility with Ruby 1.8 and 1.9 and of course pushed the built gem to gemcutter.
|
8
|
+
|
9
|
+
You'll find the [source code](http://github.com/iulianu/iban-tools) on Github. [Our fork](http://github.com/alphasights/iban-tools) is also available on GitHub
|
10
|
+
|
11
|
+
The gem should be compatible with Ruby 1.8.6, 1.8.7 and 1.9.1.
|
12
|
+
|
13
|
+
## INSTALLATION
|
14
|
+
|
15
|
+
You'll need to add http://gems.rubyforge.com as a gem source if you don't already have it.
|
16
|
+
|
17
|
+
You can accomplish this with the gemcutter gem.
|
18
|
+
|
19
|
+
gem install gemcutter
|
20
|
+
gem tumble
|
21
|
+
|
22
|
+
Once you have the gemcutter source added you can install iban-tools with a simple gem install.
|
23
|
+
|
24
|
+
gem install iban-tools
|
25
|
+
|
26
|
+
## USAGE
|
27
|
+
|
28
|
+
require 'rubygems'
|
29
|
+
require 'iban-tools'
|
30
|
+
|
31
|
+
IBANTools::IBAN.valid?("GB82 WEST 1234 5698 7654 32")
|
32
|
+
=> true
|
33
|
+
|
34
|
+
Advanced usage, gives more detailed error messages
|
35
|
+
|
36
|
+
IBANTools::IBAN.new("XQ75 BADCODE 666").validation_errors
|
37
|
+
=> [:unknown_country_code, :bad_check_digits]
|
38
|
+
|
39
|
+
Pretty print, canonicalize, and extract fields from an IBAN code
|
40
|
+
|
41
|
+
iban = IBANTools::IBAN.new(" ro49 aaaa 1B31007593840000")
|
42
|
+
|
43
|
+
iban.code
|
44
|
+
=> "RO49AAAA1B31007593840000"
|
45
|
+
|
46
|
+
iban.country_code
|
47
|
+
=> "RO"
|
48
|
+
|
49
|
+
iban.prettify
|
50
|
+
=> "RO49 AAAA 1B31 0075 9384 0000"
|
data/lib/iban-tools.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim:ts=2:sw=2:et:
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009 Iulian Dogariu
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
#++
|
24
|
+
|
25
|
+
require 'iban-tools/iban.rb'
|
26
|
+
require 'iban-tools/iban_rules.rb'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# vim:ts=2:sw=2:et:
|
2
|
+
|
3
|
+
module IBANTools
|
4
|
+
class IBAN
|
5
|
+
|
6
|
+
def self.valid?( code, rules = nil )
|
7
|
+
new(code).validation_errors(rules).empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize( code )
|
11
|
+
@code = IBAN.canonicalize_code(code)
|
12
|
+
end
|
13
|
+
|
14
|
+
def validation_errors( rules = nil )
|
15
|
+
errors = []
|
16
|
+
return [:too_short] if @code.size < 5
|
17
|
+
return [:bad_chars] unless @code =~ /^[A-Z0-9]+$/
|
18
|
+
errors += validation_errors_against_rules( rules || IBAN.default_rules )
|
19
|
+
errors << :bad_check_digits unless valid_check_digits?
|
20
|
+
errors
|
21
|
+
end
|
22
|
+
|
23
|
+
def validation_errors_against_rules( rules )
|
24
|
+
errors = []
|
25
|
+
return [:unknown_country_code] if rules[country_code].nil?
|
26
|
+
errors << :bad_length if rules[country_code]["length"] != @code.size
|
27
|
+
errors << :bad_format unless bban =~ rules[country_code]["bban_pattern"]
|
28
|
+
errors
|
29
|
+
end
|
30
|
+
|
31
|
+
# The code in canonical form,
|
32
|
+
# suitable for storing in a database
|
33
|
+
# or sending over the wire
|
34
|
+
def code
|
35
|
+
@code
|
36
|
+
end
|
37
|
+
|
38
|
+
def country_code
|
39
|
+
@code[0..1]
|
40
|
+
end
|
41
|
+
|
42
|
+
def check_digits
|
43
|
+
@code[2..3]
|
44
|
+
end
|
45
|
+
|
46
|
+
def bban
|
47
|
+
@code[4..-1]
|
48
|
+
end
|
49
|
+
|
50
|
+
def valid_check_digits?
|
51
|
+
numerify.to_i % 97 == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def numerify
|
55
|
+
numerified = ""
|
56
|
+
(@code[4..-1] + @code[0..3]).each_byte do |byte|
|
57
|
+
numerified += case byte
|
58
|
+
# 0..9
|
59
|
+
when 48..57 then byte.chr
|
60
|
+
# 'A'..'Z'
|
61
|
+
when 65..90 then (byte - 55).to_s # 55 = 'A'.ord + 10
|
62
|
+
else
|
63
|
+
raise RuntimeError.new("Unexpected byte '#{byte}' in IBAN code '#{prettify}'")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
numerified
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
"#<#{self.class}: #{prettify}>"
|
71
|
+
end
|
72
|
+
|
73
|
+
# The IBAN code in a human-readable format
|
74
|
+
def prettify
|
75
|
+
@code.gsub(/(.{4})/, '\1 ').strip
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.canonicalize_code( code )
|
79
|
+
code.strip.gsub(/\s+/, '').upcase
|
80
|
+
end
|
81
|
+
|
82
|
+
# Load and cache the default rules from rules.yml
|
83
|
+
def self.default_rules
|
84
|
+
@default_rules ||= IBANRules.defaults
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# vim:ts=2:sw=2:et:
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module IBANTools
|
6
|
+
|
7
|
+
class IBANRules
|
8
|
+
|
9
|
+
def initialize( rules = {} )
|
10
|
+
@rules = rules
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@rules[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.defaults
|
18
|
+
load_from_string( File.read(File.dirname(__FILE__) + "/rules.yml") )
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_from_string( string )
|
22
|
+
rule_hash = YAML.load(string)
|
23
|
+
rule_hash.each do |country_code, specs|
|
24
|
+
specs["bban_pattern"] = Regexp.new(specs["bban_pattern"])
|
25
|
+
end
|
26
|
+
IBANRules.new(rule_hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# Data from http://www.tbg5-finance.org/?ibandocs.shtml/
|
2
|
+
|
3
|
+
"AD":
|
4
|
+
# Andorra
|
5
|
+
length: 24
|
6
|
+
bban_pattern: "\d{8}[A-Z0-9]{12}"
|
7
|
+
|
8
|
+
"AL":
|
9
|
+
# Albania
|
10
|
+
length: 28
|
11
|
+
bban_pattern: "\d{8}[A-Z0-9]{16}"
|
12
|
+
|
13
|
+
"AT":
|
14
|
+
# Austria
|
15
|
+
length: 20
|
16
|
+
bban_pattern: "\d{16}"
|
17
|
+
|
18
|
+
"BA":
|
19
|
+
# Bosnia
|
20
|
+
length: 20
|
21
|
+
bban_pattern: "\d{16}"
|
22
|
+
|
23
|
+
"BE":
|
24
|
+
# Belgium
|
25
|
+
length: 16
|
26
|
+
bban_pattern: "\d{12}"
|
27
|
+
|
28
|
+
"BG":
|
29
|
+
# Bulgaria
|
30
|
+
length: 22
|
31
|
+
bban_pattern: "[A-Z]{4}\d{6}[A-Z0-9]{8}"
|
32
|
+
|
33
|
+
"CH":
|
34
|
+
# Switzerland
|
35
|
+
length: 21
|
36
|
+
bban_pattern: "\d{5}[A-Z0-9]{12}"
|
37
|
+
|
38
|
+
"CY":
|
39
|
+
# Cyprus
|
40
|
+
length: 28
|
41
|
+
bban_pattern: "\d{8}[A-Z0-9]{16}"
|
42
|
+
|
43
|
+
"CZ":
|
44
|
+
# Czech Republic
|
45
|
+
length: 24
|
46
|
+
bban_pattern: "\d{20}"
|
47
|
+
|
48
|
+
"DE":
|
49
|
+
# Germany
|
50
|
+
length: 22
|
51
|
+
bban_pattern: "\d{18}"
|
52
|
+
|
53
|
+
"DK":
|
54
|
+
# Denmark
|
55
|
+
length: 18
|
56
|
+
bban_pattern: "\d{14}"
|
57
|
+
|
58
|
+
"EE":
|
59
|
+
# Estonia
|
60
|
+
length: 20
|
61
|
+
bban_pattern: "\d{16}"
|
62
|
+
|
63
|
+
"ES":
|
64
|
+
# Spain
|
65
|
+
length: 24
|
66
|
+
bban_pattern: "\d{20}"
|
67
|
+
|
68
|
+
"FI":
|
69
|
+
# Finland
|
70
|
+
length: 18
|
71
|
+
bban_pattern: "\d{14}"
|
72
|
+
|
73
|
+
"FO":
|
74
|
+
# Faroe Islands
|
75
|
+
length: 18
|
76
|
+
bban_pattern: "\d{14}"
|
77
|
+
|
78
|
+
"FR":
|
79
|
+
# France
|
80
|
+
length: 27
|
81
|
+
bban_pattern: "\d{10}[A-Z0-9]{11}\d{2}"
|
82
|
+
|
83
|
+
"GB":
|
84
|
+
# United Kingdom
|
85
|
+
length: 22
|
86
|
+
bban_pattern: "[A-Z]{4}\d{14}"
|
87
|
+
|
88
|
+
"GI":
|
89
|
+
# Gibraltar
|
90
|
+
length: 23
|
91
|
+
bban_pattern: "[A-Z]{4}[A-Z0-9]{15}"
|
92
|
+
|
93
|
+
"GL":
|
94
|
+
# Greenland
|
95
|
+
length: 18
|
96
|
+
bban_pattern: "\d{14}"
|
97
|
+
|
98
|
+
"GR":
|
99
|
+
# Greece
|
100
|
+
length: 27
|
101
|
+
bban_pattern: "\d{7}[A-Z0-9]{16}"
|
102
|
+
|
103
|
+
"HR":
|
104
|
+
# Croatia
|
105
|
+
length: 21
|
106
|
+
bban_pattern: "\d{17}"
|
107
|
+
|
108
|
+
"HU":
|
109
|
+
# Hungary
|
110
|
+
length: 28
|
111
|
+
bban_pattern: "\d{24}"
|
112
|
+
|
113
|
+
"IE":
|
114
|
+
# Ireland
|
115
|
+
length: 22
|
116
|
+
bban_pattern: "[A-Z]{4}\d{14}"
|
117
|
+
|
118
|
+
"IL":
|
119
|
+
# Israel
|
120
|
+
length: 23
|
121
|
+
bban_pattern: "\d{19}"
|
122
|
+
|
123
|
+
"IS":
|
124
|
+
# Iceland
|
125
|
+
length: 26
|
126
|
+
bban_pattern: "\d{22}"
|
127
|
+
|
128
|
+
"IT":
|
129
|
+
# Italy
|
130
|
+
length: 27
|
131
|
+
bban_pattern: "[A-Z]\d{10}[A-Z0-9]{12}"
|
132
|
+
|
133
|
+
"LI":
|
134
|
+
# Liechtenstein
|
135
|
+
length: 21
|
136
|
+
bban_pattern: "\d{5}[A-Z0-9]{12}"
|
137
|
+
|
138
|
+
"LT":
|
139
|
+
# Lithuania
|
140
|
+
length: 20
|
141
|
+
bban_pattern: "\d{16}"
|
142
|
+
|
143
|
+
"LU":
|
144
|
+
# Luxembourg
|
145
|
+
length: 20
|
146
|
+
bban_pattern: "\d{3}[A-Z0-9]{13}"
|
147
|
+
|
148
|
+
"LV":
|
149
|
+
# Latvia
|
150
|
+
length: 21
|
151
|
+
bban_pattern: "[A-Z]{4}[A-Z0-9]{13}"
|
152
|
+
|
153
|
+
"MC":
|
154
|
+
# Monaco
|
155
|
+
length: 27
|
156
|
+
bban_pattern: "\d{10}[A-Z0-9]{11}\d{2}"
|
157
|
+
|
158
|
+
"ME":
|
159
|
+
# Montenegro
|
160
|
+
length: 22
|
161
|
+
bban_pattern: "\d{18}"
|
162
|
+
|
163
|
+
"MK":
|
164
|
+
# Macedonia
|
165
|
+
length: 19
|
166
|
+
bban_pattern: "\d{3}[A-Z0-9]{10}\d{2}"
|
167
|
+
|
168
|
+
"MT":
|
169
|
+
# Malta
|
170
|
+
length: 31
|
171
|
+
bban_pattern: "[A-Z]{4}\d{5}[A-Z0-9]{18}"
|
172
|
+
|
173
|
+
"MU":
|
174
|
+
# Mauritius
|
175
|
+
length: 30
|
176
|
+
bban_pattern: "[A-Z]{4}\d{19}[A-Z]{3}"
|
177
|
+
|
178
|
+
"NL":
|
179
|
+
# Netherlands
|
180
|
+
length: 18
|
181
|
+
bban_pattern: "[A-Z]{4}\d{10}"
|
182
|
+
|
183
|
+
"NO":
|
184
|
+
# Norway
|
185
|
+
length: 15
|
186
|
+
bban_pattern: "\d{11}"
|
187
|
+
|
188
|
+
"PL":
|
189
|
+
# Poland
|
190
|
+
length: 28
|
191
|
+
bban_pattern: "\d{8}[A-Z0-9]{16}"
|
192
|
+
|
193
|
+
"PT":
|
194
|
+
# Portugal
|
195
|
+
length: 25
|
196
|
+
bban_pattern: "\d{21}"
|
197
|
+
|
198
|
+
"RO":
|
199
|
+
# Romania
|
200
|
+
length: 24
|
201
|
+
bban_pattern: "[A-Z]{4}[A-Z0-9]{16}"
|
202
|
+
|
203
|
+
"RS":
|
204
|
+
# Serbia
|
205
|
+
length: 22
|
206
|
+
bban_pattern: "\d{18}"
|
207
|
+
|
208
|
+
"SA":
|
209
|
+
# Saudi Arabia
|
210
|
+
length: 24
|
211
|
+
bban_pattern: "\d{2}[A-Z0-9]{18}"
|
212
|
+
|
213
|
+
"SE":
|
214
|
+
# Sweden
|
215
|
+
length: 24
|
216
|
+
bban_pattern: "\d{20}"
|
217
|
+
|
218
|
+
"SI":
|
219
|
+
# Slovenia
|
220
|
+
length: 19
|
221
|
+
bban_pattern: "\d{15}"
|
222
|
+
|
223
|
+
"SK":
|
224
|
+
# Slovakia
|
225
|
+
length: 24
|
226
|
+
bban_pattern: "\d{20}"
|
227
|
+
|
228
|
+
"SM":
|
229
|
+
# San Marino
|
230
|
+
length: 27
|
231
|
+
bban_pattern: "[A-Z]\d{10}[A-Z0-9]{12}"
|
232
|
+
|
233
|
+
"TN":
|
234
|
+
# Tunisia
|
235
|
+
length: 24
|
236
|
+
bban_pattern: "\d{20}"
|
237
|
+
|
238
|
+
"TR":
|
239
|
+
# Turkey
|
240
|
+
length: 26
|
241
|
+
bban_pattern: "\d{5}[A-Z0-9]{17}"
|
242
|
+
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iban-tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Iulian Dogariu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-05 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Validates IBAN account numbers
|
17
|
+
email:
|
18
|
+
- code@iuliandogariu.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- README.md
|
27
|
+
- lib/iban-tools.rb
|
28
|
+
- lib/iban-tools/iban.rb
|
29
|
+
- lib/iban-tools/iban_rules.rb
|
30
|
+
- lib/iban-tools/rules.yml
|
31
|
+
has_rdoc: true
|
32
|
+
homepage:
|
33
|
+
licenses: []
|
34
|
+
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements:
|
53
|
+
- none
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 1.3.5
|
56
|
+
signing_key:
|
57
|
+
specification_version: 3
|
58
|
+
summary: IBAN validator
|
59
|
+
test_files: []
|
60
|
+
|