konto_check_ruby 1.0.0
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 +7 -0
- data/CHANGELOG.md +26 -0
- data/COPYRIGHT +22 -0
- data/LICENSE +504 -0
- data/README.md +295 -0
- data/bin/konto_check_ruby +202 -0
- data/data/README.md +17 -0
- data/data/blz.lut2f +0 -0
- data/data/iban_regeln.txt +1260 -0
- data/lib/konto_check_ruby/bank_data.rb +421 -0
- data/lib/konto_check_ruby/blz_file.rb +705 -0
- data/lib/konto_check_ruby/check_methods/part1.rb +1634 -0
- data/lib/konto_check_ruby/check_methods/part2.rb +1604 -0
- data/lib/konto_check_ruby/check_methods/part3.rb +1905 -0
- data/lib/konto_check_ruby/check_methods/part4.rb +1738 -0
- data/lib/konto_check_ruby/check_methods/part5.rb +1407 -0
- data/lib/konto_check_ruby/check_methods.rb +147 -0
- data/lib/konto_check_ruby/collation.rb +52 -0
- data/lib/konto_check_ruby/engine.rb +1006 -0
- data/lib/konto_check_ruby/iban_rules.rb +1060 -0
- data/lib/konto_check_ruby/konto_check.rb +1578 -0
- data/lib/konto_check_ruby/lut_file.rb +457 -0
- data/lib/konto_check_ruby/raw.rb +614 -0
- data/lib/konto_check_ruby/retvals.rb +826 -0
- data/lib/konto_check_ruby/search.rb +440 -0
- data/lib/konto_check_ruby/update.rb +176 -0
- data/lib/konto_check_ruby/version.rb +18 -0
- data/lib/konto_check_ruby.rb +42 -0
- metadata +112 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of konto_check_ruby, a Ruby port of the C library
|
|
4
|
+
# konto_check, Copyright (C) 2002-2023 Michael Plugge <konto_check@yahoo.com>.
|
|
5
|
+
# Ruby port Copyright (C) 2026 tickettoaster GmbH <https://tickettoaster.de>.
|
|
6
|
+
#
|
|
7
|
+
# konto_check_ruby is free software; you can redistribute it and/or modify it
|
|
8
|
+
# under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
# the Free Software Foundation; either version 2.1 of the License, or (at
|
|
10
|
+
# your option) any later version. It is distributed WITHOUT ANY WARRANTY; see
|
|
11
|
+
# the file LICENSE for details.
|
|
12
|
+
|
|
13
|
+
require_relative "retvals"
|
|
14
|
+
|
|
15
|
+
module KontoCheckRuby
|
|
16
|
+
# Port of kto_check_int() from konto_check.c: the check-digit methods
|
|
17
|
+
# 00..E4 of the Deutsche Bundesbank.
|
|
18
|
+
#
|
|
19
|
+
# Every C `case N:` label of the big switch in kto_check_int() becomes a
|
|
20
|
+
# method `mN(kto, blz, um, rv)` in this module (see check_methods/part*.rb).
|
|
21
|
+
#
|
|
22
|
+
# kto : Array of 10 Integers (digits 0..9), the account number right
|
|
23
|
+
# aligned and left padded with zeros. Methods may modify it.
|
|
24
|
+
# blz : String with the bank code (8 digits) or nil
|
|
25
|
+
# um : Integer, requested sub-method (0 = none, 1 = 'a', 2 = 'b', ...)
|
|
26
|
+
# rv : Retvals struct (methode, pz_methode, pz, pz_pos) or nil
|
|
27
|
+
#
|
|
28
|
+
# Return value is one of the integer return codes (OK, FALSE, INVALID_KTO, ...).
|
|
29
|
+
module CheckMethods
|
|
30
|
+
extend self
|
|
31
|
+
|
|
32
|
+
Retvals = Struct.new(:methode, :pz_methode, :pz, :pz_pos)
|
|
33
|
+
|
|
34
|
+
# Weights for methods 27, 29 and 69 (m10h_digits in C)
|
|
35
|
+
M10H_DIGITS = [
|
|
36
|
+
[0, 1, 5, 9, 3, 7, 4, 8, 2, 6],
|
|
37
|
+
[0, 1, 7, 6, 9, 8, 3, 2, 5, 4],
|
|
38
|
+
[0, 1, 8, 4, 6, 2, 9, 5, 7, 3],
|
|
39
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
40
|
+
].freeze
|
|
41
|
+
|
|
42
|
+
# Tables for method 87
|
|
43
|
+
TAB1 = [0, 4, 3, 2, 6].freeze
|
|
44
|
+
TAB2 = [7, 1, 5, 9, 8].freeze
|
|
45
|
+
|
|
46
|
+
# Weights for methods 24, 52/53/B6/C0 and 93
|
|
47
|
+
W52 = [2, 4, 8, 5, 10, 9, 7, 3, 6, 1, 2, 4, 0, 0, 0, 0].freeze
|
|
48
|
+
W24 = [1, 2, 3, 1, 2, 3, 1, 2, 3].freeze
|
|
49
|
+
W93 = [2, 3, 4, 5, 6, 7, 2, 3, 4].freeze
|
|
50
|
+
|
|
51
|
+
# Methods that may contain omitted sub-account numbers (uk_pz_methoden in C)
|
|
52
|
+
UK_PZ_METHODEN = [13, 26, 50, 63, 76, 127].freeze
|
|
53
|
+
|
|
54
|
+
# Converts the account number string into an array of 10 digits, exactly
|
|
55
|
+
# as the prolog of kto_check_int() does: leading zeros, blanks and tabs
|
|
56
|
+
# are skipped, the number ends at the first blank/tab, it must have 1..10
|
|
57
|
+
# characters and is right aligned (zero padded) in a 10 digit field.
|
|
58
|
+
# Returns nil if the length is invalid.
|
|
59
|
+
def normalize_kto(kto)
|
|
60
|
+
s = kto.to_s
|
|
61
|
+
i = 0
|
|
62
|
+
i += 1 while i < s.length && (s[i] == "0" || s[i] == " " || s[i] == "\t")
|
|
63
|
+
j = i
|
|
64
|
+
j += 1 while j < s.length && s[j] != " " && s[j] != "\t"
|
|
65
|
+
len = j - i
|
|
66
|
+
return nil if len < 1 || len > 10
|
|
67
|
+
digits = Array.new(10, 0)
|
|
68
|
+
k = 10 - len
|
|
69
|
+
s.byteslice(i, len).each_byte do |b|
|
|
70
|
+
digits[k] = b - 48
|
|
71
|
+
k += 1
|
|
72
|
+
end
|
|
73
|
+
digits
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Converts a method string like "00", "51", "b6", "13a", "C0" into the
|
|
77
|
+
# numeric method used by the C library (bx2/b1/by4 tables) and the
|
|
78
|
+
# sub-method. Returns [pz_methode, untermethode] or nil for invalid input.
|
|
79
|
+
def parse_method(pz)
|
|
80
|
+
s = pz.to_s
|
|
81
|
+
return nil if s.length < 2 || s.length > 3
|
|
82
|
+
c1 = alnum_value(s[0])
|
|
83
|
+
c2 = s[1] =~ /\A\d\z/ ? s[1].to_i : nil
|
|
84
|
+
return nil if c1.nil? || c2.nil?
|
|
85
|
+
methode = c1 * 10 + c2
|
|
86
|
+
um = 0
|
|
87
|
+
if s.length == 3
|
|
88
|
+
um = letter_value(s[2])
|
|
89
|
+
return nil if um.nil?
|
|
90
|
+
methode += um * 1000
|
|
91
|
+
end
|
|
92
|
+
[methode, um]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Numeric method -> two character method string ("00".."99", "A0".."E4")
|
|
96
|
+
def method_string(pz_methode)
|
|
97
|
+
base = pz_methode % 1000
|
|
98
|
+
um = pz_methode / 1000
|
|
99
|
+
s = base < 100 ? format("%02d", base) : ((base / 10) - 10 + 65).chr + (base % 10).to_s
|
|
100
|
+
s += (96 + um).chr if um > 0
|
|
101
|
+
s
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Runs check method pz_methode (an integer as in the C switch, e.g. 13,
|
|
105
|
+
# 1013, 2013) for the account number kto (String). Returns the result code.
|
|
106
|
+
def check(pz_methode, kto, blz = nil, um = 0, rv = nil)
|
|
107
|
+
digits = normalize_kto(kto)
|
|
108
|
+
return INVALID_KTO_LENGTH unless digits
|
|
109
|
+
check_digits(pz_methode, digits, blz, um, rv)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Same as check(), but with an already normalized digit array.
|
|
113
|
+
def check_digits(pz_methode, digits, blz = nil, um = 0, rv = nil)
|
|
114
|
+
meth = :"m#{pz_methode}"
|
|
115
|
+
if respond_to?(meth)
|
|
116
|
+
send(meth, digits, blz, um, rv)
|
|
117
|
+
else
|
|
118
|
+
# default branch of the C switch
|
|
119
|
+
if rv
|
|
120
|
+
rv.methode = "(-)"
|
|
121
|
+
rv.pz_methode = -1
|
|
122
|
+
end
|
|
123
|
+
return UNDEFINED_SUBMETHOD if um && um != 0
|
|
124
|
+
NOT_IMPLEMENTED
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
def alnum_value(c)
|
|
131
|
+
case c
|
|
132
|
+
when /\A\d\z/ then c.to_i
|
|
133
|
+
when /\A[a-z]\z/ then c.ord - 97 + 10
|
|
134
|
+
when /\A[A-Z]\z/ then c.ord - 65 + 10
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def letter_value(c)
|
|
139
|
+
case c
|
|
140
|
+
when /\A[a-z]\z/ then c.ord - 96
|
|
141
|
+
when /\A[A-Z]\z/ then c.ord - 64
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
Dir[File.join(__dir__, "check_methods", "*.rb")].sort.each { |f| require f }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of konto_check_ruby, a Ruby port of the C library
|
|
4
|
+
# konto_check, Copyright (C) 2002-2023 Michael Plugge <konto_check@yahoo.com>.
|
|
5
|
+
# Ruby port Copyright (C) 2026 tickettoaster GmbH <https://tickettoaster.de>.
|
|
6
|
+
#
|
|
7
|
+
# konto_check_ruby is free software; you can redistribute it and/or modify it
|
|
8
|
+
# under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
# the Free Software Foundation; either version 2.1 of the License, or (at
|
|
10
|
+
# your option) any later version. It is distributed WITHOUT ANY WARRANTY; see
|
|
11
|
+
# the file LICENSE for details.
|
|
12
|
+
|
|
13
|
+
module KontoCheckRuby
|
|
14
|
+
# Case and accent insensitive collation used for the search functions and
|
|
15
|
+
# the sort index blocks (get_sortc / stri_cmp in the C source): letters are
|
|
16
|
+
# folded to lower case and accented letters are compared like their base
|
|
17
|
+
# letter (ä -> a, ß -> s, é -> e ...).
|
|
18
|
+
module Collation
|
|
19
|
+
FOLD = {
|
|
20
|
+
"ä" => "a", "à" => "a", "á" => "a", "â" => "a", "ã" => "a", "å" => "a",
|
|
21
|
+
"ö" => "o", "ò" => "o", "ó" => "o", "ô" => "o", "õ" => "o", "ø" => "o",
|
|
22
|
+
"ü" => "u", "ù" => "u", "ú" => "u", "û" => "u",
|
|
23
|
+
"è" => "e", "é" => "e", "ê" => "e", "ë" => "e",
|
|
24
|
+
"ì" => "i", "í" => "i", "î" => "i", "ï" => "i",
|
|
25
|
+
"ç" => "c", "ñ" => "n", "ý" => "y", "ÿ" => "y", "ß" => "s"
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
FOLD_RE = Regexp.union(FOLD.keys).freeze
|
|
29
|
+
|
|
30
|
+
# Sort key of a string: lower case, accents removed. Non-letters are kept.
|
|
31
|
+
def self.sort_key(str)
|
|
32
|
+
s = str.to_s
|
|
33
|
+
s = s.encode("UTF-8", invalid: :replace, undef: :replace) unless s.encoding == Encoding::UTF_8 && s.valid_encoding?
|
|
34
|
+
s.downcase.gsub(FOLD_RE, FOLD)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Words (alphanumeric sequences) of a string, for the full text search
|
|
38
|
+
def self.words(str)
|
|
39
|
+
s = str.to_s
|
|
40
|
+
s = s.encode("UTF-8", invalid: :replace, undef: :replace) unless s.encoding == Encoding::UTF_8 && s.valid_encoding?
|
|
41
|
+
s.scan(/[[:alnum:]]+/)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Prefix comparison like strni_cmp(): 0 if a is a prefix of b (after folding)
|
|
45
|
+
def self.prefix_cmp(a, b)
|
|
46
|
+
ka = sort_key(a)
|
|
47
|
+
kb = sort_key(b)
|
|
48
|
+
return 0 if kb.start_with?(ka)
|
|
49
|
+
ka <=> kb
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|