iso8583 0.1.6 → 0.2.4
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 +5 -13
- data/AUTHORS +6 -0
- data/CHANGELOG +30 -4
- data/Gemfile +3 -0
- data/README.md +29 -0
- data/Rakefile +1 -2
- data/lib/iso8583/berlin.rb +1 -1
- data/lib/iso8583/bitmap.rb +6 -7
- data/lib/iso8583/codec.rb +20 -1
- data/lib/iso8583/exception.rb +1 -1
- data/lib/iso8583/field.rb +5 -5
- data/lib/iso8583/fields.rb +22 -0
- data/lib/iso8583/message.rb +13 -6
- data/lib/iso8583/util.rb +9 -4
- data/lib/iso8583/version.rb +1 -1
- data/test/BitmapTests.rb +13 -2
- data/test/message_test.rb +21 -3
- data/test/test_codec.rb +44 -6
- data/test/test_fields.rb +9 -7
- data/test/test_message_metaclass.rb +30 -0
- data/test/test_util.rb +13 -4
- metadata +11 -10
- data/README +0 -26
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzQ0OTBiYmI4MGQ0NjViMTI2YzNlM2NiZTUzNTIxZTliYWU4OTQzOQ==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4c551d563390f55d323d8aea190eb31b20dcc98f786a9f872faa5df24fd229d1
|
4
|
+
data.tar.gz: c448bfe8446285da07c61ac8b5cfbb908477cf98a9e1bf703cfdae47d17cb2c9
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NjY4M2QzNWIxNTlkNDAwM2Y5ZjUzZTM3ZTc3ZGNhMGQ3ODI4Zjg1OWVmOGMx
|
11
|
-
YmIzZWE4YWJlNDc5ZGIwNWJjMmMyZDBkZDE2M2EzMjdjNjU0OTg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzQ2YzU2N2E1YzM2YjRjZThiNTdiOWE2NGViYjA1NmMzNWQwZGNjZmJkMTg2
|
14
|
-
MDBlOWU2MTdmOTkyOWZkYmQwYWVmNjJkMTkxMDkyMTY3NDk1MjcyYjI3OWM2
|
15
|
-
MGU1MDVlN2QzNTAxNTAzZjQ4YzA0NmQ2ZmVmMzI0ZDlkMzYyZWQ=
|
6
|
+
metadata.gz: 1fe629ddc4d985d96b63d20e6bacfb7e9c7d7cbe429232a9dcb8f5e972f9be5e0263bb675e11d78e272de4a3c58d0ced9a7a8b2646e2f94d64d0aea8b632f66c
|
7
|
+
data.tar.gz: 05bb98f645a560bf44bc2b64884a301b0869f7df1b7694291c82d991abe21538df5b8a08d57ab716e8e30482770e9db8dc6f49146de2ba36aa9640e355265329
|
data/AUTHORS
CHANGED
@@ -1,3 +1,9 @@
|
|
1
1
|
Tim Becker (tim@kuriositaet.de)
|
2
2
|
Slava Kravchenko (cordawyn@gmail.com)
|
3
3
|
Tonni Aagesen (https://github.com/ta)
|
4
|
+
Lasse Skindstad Ebert (https://github.com/lasseebert)
|
5
|
+
Joel Ibaceta (https://github.com/joelibaceta)
|
6
|
+
Jackson Harper <jackson@juvo.com>
|
7
|
+
absrd (https://github.com/absrd)
|
8
|
+
Nicolas Leger (https://github.com/nicolasleger)
|
9
|
+
Jérémie Bonal (https://github.com/Aquaj)
|
data/CHANGELOG
CHANGED
@@ -1,12 +1,38 @@
|
|
1
|
+
0.2.4
|
2
|
+
=========
|
3
|
+
better errors for missing bitmap
|
4
|
+
cleanup warnings
|
5
|
+
|
6
|
+
0.2.3
|
7
|
+
=========
|
8
|
+
Change Fixnum to Integer as Fixnum is deprecated
|
9
|
+
|
10
|
+
|
11
|
+
0.2.2
|
12
|
+
=========
|
13
|
+
Thu Feb 16 13:29:41 CET 2017
|
14
|
+
|
15
|
+
Added network big order codec
|
16
|
+
|
17
|
+
|
18
|
+
0.2.0
|
19
|
+
=========
|
20
|
+
no more 1.8 compatibility, byte encoding for 1.9+, ci
|
21
|
+
Inherit ISOException from StandardError
|
22
|
+
Add bundler stuff, and dev dependancy for test-unit which was removed
|
23
|
+
for no good reason in 2.2
|
24
|
+
Use ASCII for all forced_encodings
|
25
|
+
|
1
26
|
0.1.6
|
2
27
|
=========
|
3
|
-
restrict to ruby < 2
|
4
|
-
allow removal of empty fields
|
28
|
+
restrict to ruby < 2
|
29
|
+
allow removal of empty fields
|
30
|
+
Thanks: Lasse Skindstad Ebert https://github.com/lasseebert
|
5
31
|
|
6
32
|
0.1.5
|
7
33
|
=========
|
8
|
-
MMDD Codec
|
9
|
-
BCD encoder checks odd length fields
|
34
|
+
MMDD Codec
|
35
|
+
BCD encoder checks odd length fields
|
10
36
|
|
11
37
|
0.1.4
|
12
38
|
=========
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# ISO 8583 Financial Messaging for Ruby
|
2
|
+
|
3
|
+
This package currently contains code for coding an decoding ISO 8583
|
4
|
+
Financial Message.
|
5
|
+
|
6
|
+
## Developing
|
7
|
+
|
8
|
+
In case you're using a ruby version >= 2.2, test-unit is no longer in
|
9
|
+
the std lib, so it needs to be available. Bundler installs this, if not
|
10
|
+
using bundler, you need to run `gem install test-unit` before running
|
11
|
+
the tests.
|
12
|
+
|
13
|
+
## Installing
|
14
|
+
|
15
|
+
You can install the last version of the +iso8583+ package by executing:
|
16
|
+
|
17
|
+
gem install iso8583
|
18
|
+
|
19
|
+
## Source
|
20
|
+
|
21
|
+
The source is most readily available on github[http://github.com/a2800276/8583].
|
22
|
+
|
23
|
+
## Mailing List
|
24
|
+
|
25
|
+
In case you discover bugs, spelling errors, offer suggestions for
|
26
|
+
improvements or would like to help out with the project, you can contact
|
27
|
+
me directly (tim@kuriositaet.de).
|
28
|
+
|
29
|
+
[](https://travis-ci.org/a2800276/8583)
|
data/Rakefile
CHANGED
@@ -84,7 +84,6 @@ spec = Gem::Specification.new do |s|
|
|
84
84
|
s.requirements << "none"
|
85
85
|
s.require_path = "lib"
|
86
86
|
s.description = LONG_DESC
|
87
|
-
s.has_rdoc = true
|
88
87
|
s.authors = ["Tim Becker", "Slava Kravchenko"]
|
89
88
|
s.email = ["tim.becker@kuriositaet.de","cordawyn@gmail.com"]
|
90
89
|
s.homepage = "http://github.com/a2800276/8583/"
|
@@ -125,7 +124,7 @@ end
|
|
125
124
|
Rake::TestTask.new do |t|
|
126
125
|
t.libs << "test"
|
127
126
|
t.libs << "."
|
128
|
-
t.ruby_opts = ["-
|
127
|
+
t.ruby_opts = ["-rrubygems"]
|
129
128
|
t.test_files = FileList["test/*.rb"]
|
130
129
|
t.verbose = true
|
131
130
|
end
|
data/lib/iso8583/berlin.rb
CHANGED
data/lib/iso8583/bitmap.rb
CHANGED
@@ -17,18 +17,17 @@ module ISO8583
|
|
17
17
|
# not, this initializes and empty bitmap.
|
18
18
|
def initialize(message = nil)
|
19
19
|
@bmp = Array.new(128, false)
|
20
|
-
if
|
21
|
-
|
22
|
-
else
|
20
|
+
if message
|
23
21
|
initialize_from_message message
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
# yield once with the number of each set field.
|
28
|
-
|
29
|
-
|
26
|
+
# :yields: each bit set in the bitmap. Except for the first bit which is used to determine the bitmap sizec
|
27
|
+
def each
|
28
|
+
@bmp.each_with_index {|set, i| yield i+1 if set && i != 0}
|
30
29
|
end
|
31
|
-
|
30
|
+
|
32
31
|
# Returns whether the bit is set or not.
|
33
32
|
def [](i)
|
34
33
|
@bmp[i-1]
|
@@ -76,7 +75,7 @@ module ISO8583
|
|
76
75
|
break
|
77
76
|
end
|
78
77
|
}
|
79
|
-
str = ""
|
78
|
+
str = "".force_encoding("ASCII-8BIT")
|
80
79
|
1.upto(self[1] ? 128 : 64) {|i|
|
81
80
|
str << (self[i] ? "1" : "0")
|
82
81
|
}
|
data/lib/iso8583/codec.rb
CHANGED
@@ -53,6 +53,8 @@ module ISO8583
|
|
53
53
|
# during encoding, no validity check during decoding.
|
54
54
|
# [+ANS_Codec+] passes through ASCII string checking they conform to [\x20-\x7E]
|
55
55
|
# during encoding, no validity check during decoding.
|
56
|
+
# [BE_U16] 16-bit unsigned, network (big-endian) byte order
|
57
|
+
# [BE_U32] 32-bit unsigned, network (big-endian) byte order
|
56
58
|
# [+Null_Codec+] passes anything along untouched.
|
57
59
|
# [<tt>Track2</tt>] rudimentary check that string conforms to Track2
|
58
60
|
# [+MMDDhhmmssCodec+] encodes Time, Datetime or String to the described date format, checking
|
@@ -111,7 +113,7 @@ module ISO8583
|
|
111
113
|
[val].pack("H*")
|
112
114
|
}
|
113
115
|
Packed_Number.decoder = lambda{|encoded|
|
114
|
-
|
116
|
+
encoded.unpack("H*")[0].to_i
|
115
117
|
}
|
116
118
|
|
117
119
|
A_Codec = Codec.new
|
@@ -141,6 +143,23 @@ module ISO8583
|
|
141
143
|
str
|
142
144
|
}
|
143
145
|
ANS_Codec.decoder = PASS_THROUGH_DECODER
|
146
|
+
|
147
|
+
BE_U16 = Codec.new
|
148
|
+
BE_U16.encoder = lambda {|num|
|
149
|
+
raise ISO8583Exception.new("Invalid value: #{num} must be 0<= X <=2^16-1") unless 0 <= num && num <= 2**16-1
|
150
|
+
[num].pack("n")
|
151
|
+
}
|
152
|
+
BE_U16.decoder = lambda { |encoded|
|
153
|
+
encoded.unpack("n")[0]
|
154
|
+
}
|
155
|
+
BE_U32 = Codec.new
|
156
|
+
BE_U32.encoder = lambda {|num|
|
157
|
+
raise ISO8583Exception.new("Invalid value: #{num} must be 0<= X <=2^32-1") unless 0 <= num && num <= 2**32-1
|
158
|
+
[num].pack("N")
|
159
|
+
}
|
160
|
+
BE_U32.decoder = lambda { |encoded|
|
161
|
+
encoded.unpack("N")[0]
|
162
|
+
}
|
144
163
|
|
145
164
|
Null_Codec = Codec.new
|
146
165
|
Null_Codec.encoder = lambda {|str|
|
data/lib/iso8583/exception.rb
CHANGED
data/lib/iso8583/field.rb
CHANGED
@@ -19,7 +19,7 @@ module ISO8583
|
|
19
19
|
|
20
20
|
def parse(raw)
|
21
21
|
len, raw = case length
|
22
|
-
when
|
22
|
+
when Integer
|
23
23
|
[length, raw]
|
24
24
|
when Field
|
25
25
|
length.parse(raw)
|
@@ -27,7 +27,7 @@ module ISO8583
|
|
27
27
|
raise ISO8583Exception.new("Cannot determine the length of '#{name}' field")
|
28
28
|
end
|
29
29
|
|
30
|
-
raw_value = raw
|
30
|
+
raw_value = raw.byteslice(0,len)
|
31
31
|
|
32
32
|
# make sure we have enough data ...
|
33
33
|
if raw_value.length != len
|
@@ -35,7 +35,7 @@ module ISO8583
|
|
35
35
|
raise ISO8583ParseException.new(mes)
|
36
36
|
end
|
37
37
|
|
38
|
-
rest = raw
|
38
|
+
rest = raw.byteslice(len, raw.length)
|
39
39
|
begin
|
40
40
|
real_value = codec.decode(raw_value)
|
41
41
|
rescue
|
@@ -67,10 +67,10 @@ module ISO8583
|
|
67
67
|
end
|
68
68
|
|
69
69
|
len_str = case length
|
70
|
-
when
|
70
|
+
when Integer
|
71
71
|
raise ISO8583Exception.new("Too long: #{value} (#{name})! length=#{length}") if encoded_value.length > length
|
72
72
|
raise ISO8583Exception.new("Too short: #{value} (#{name})! length=#{length}") if encoded_value.length < length
|
73
|
-
""
|
73
|
+
"".force_encoding("ASCII-8BIT")
|
74
74
|
when Field
|
75
75
|
raise ISO8583Exception.new("Max lenth exceeded: #{value}, max: #{max}") if max && encoded_value.length > max
|
76
76
|
length.encode(encoded_value.length)
|
data/lib/iso8583/fields.rb
CHANGED
@@ -57,63 +57,75 @@ module ISO8583
|
|
57
57
|
}
|
58
58
|
|
59
59
|
LL_BCD = BCDField.new
|
60
|
+
LL_BCD.name = "LL_BCD"
|
60
61
|
LL_BCD.length = 2
|
61
62
|
LL_BCD.codec = Packed_Number
|
62
63
|
|
63
64
|
# Two byte variable length ASCII numeral, payload ASCII numerals
|
64
65
|
LLVAR_N = Field.new
|
66
|
+
LLVAR_N.name = "LLVAR_N"
|
65
67
|
LLVAR_N.length = LL
|
66
68
|
LLVAR_N.codec = ASCII_Number
|
67
69
|
|
68
70
|
# Three byte variable length ASCII numeral, payload ASCII numerals
|
69
71
|
LLLVAR_N = Field.new
|
72
|
+
LLLVAR_N.name = "LLLVAR_N"
|
70
73
|
LLLVAR_N.length = LLL
|
71
74
|
LLLVAR_N.codec = ASCII_Number
|
72
75
|
|
73
76
|
# Two byte variable length ASCII numeral, payload Track2 data
|
74
77
|
LLVAR_Z = Field.new
|
78
|
+
LLVAR_Z.name = "LLVAR_Z"
|
75
79
|
LLVAR_Z.length = LL
|
76
80
|
LLVAR_Z.codec = Track2
|
77
81
|
|
78
82
|
# Two byte variable length ASCII numeral, payload ASCII, fixed length, zeropadded (right)
|
79
83
|
LLVAR_AN = Field.new
|
84
|
+
LLVAR_AN.name = "LLVAR_AN"
|
80
85
|
LLVAR_AN.length = LL
|
81
86
|
LLVAR_AN.codec = AN_Codec
|
82
87
|
|
83
88
|
# Two byte variable length ASCII numeral, payload ASCII+special
|
84
89
|
LLVAR_ANS = Field.new
|
90
|
+
LLVAR_ANS.name = "LLVAR_ANS"
|
85
91
|
LLVAR_ANS.length = LL
|
86
92
|
LLVAR_ANS.codec = ANS_Codec
|
87
93
|
|
88
94
|
# Three byte variable length ASCII numeral, payload ASCII, fixed length, zeropadded (right)
|
89
95
|
LLLVAR_AN = Field.new
|
96
|
+
LLLVAR_AN.name = "LLLVAR_AN"
|
90
97
|
LLLVAR_AN.length = LLL
|
91
98
|
LLLVAR_AN.codec = AN_Codec
|
92
99
|
|
93
100
|
# Three byte variable length ASCII numeral, payload ASCII+special
|
94
101
|
LLLVAR_ANS = Field.new
|
102
|
+
LLLVAR_ANS.name = "LLLVAR_ANS"
|
95
103
|
LLLVAR_ANS.length = LLL
|
96
104
|
LLLVAR_ANS.codec = ANS_Codec
|
97
105
|
|
98
106
|
# Two byte variable length binary payload
|
99
107
|
LLVAR_B = Field.new
|
108
|
+
LLVAR_B.name = "LLVAR_B"
|
100
109
|
LLVAR_B.length = LL
|
101
110
|
LLVAR_B.codec = Null_Codec
|
102
111
|
|
103
112
|
|
104
113
|
# Three byte variable length binary payload
|
105
114
|
LLLVAR_B = Field.new
|
115
|
+
LLLVAR_B.name = "LLLVAR_B"
|
106
116
|
LLLVAR_B.length = LLL
|
107
117
|
LLLVAR_B.codec = Null_Codec
|
108
118
|
|
109
119
|
# Fixed lengh numerals, repesented in ASCII, padding right justified using zeros
|
110
120
|
N = Field.new
|
121
|
+
N.name = "N"
|
111
122
|
N.codec = ASCII_Number
|
112
123
|
N.padding = lambda {|val, len|
|
113
124
|
sprintf("%0#{len}d", val)
|
114
125
|
}
|
115
126
|
|
116
127
|
N_BCD = BCDField.new
|
128
|
+
N_BCD.name = "N_BCD"
|
117
129
|
N_BCD.codec = Packed_Number
|
118
130
|
|
119
131
|
PADDING_LEFT_JUSTIFIED_SPACES = lambda {|val, len|
|
@@ -122,25 +134,30 @@ module ISO8583
|
|
122
134
|
|
123
135
|
# Fixed length ASCII letters [A-Za-z]
|
124
136
|
A = Field.new
|
137
|
+
A.name = "A"
|
125
138
|
A.codec = A_Codec
|
126
139
|
|
127
140
|
# Fixed lengh ASCII [A-Za-z0-9], padding left justified using spaces.
|
128
141
|
AN = Field.new
|
142
|
+
AN.name = "AN"
|
129
143
|
AN.codec = AN_Codec
|
130
144
|
AN.padding = PADDING_LEFT_JUSTIFIED_SPACES
|
131
145
|
|
132
146
|
# Fixed lengh ASCII [A-Za-z0-9] and space, padding left, spaces
|
133
147
|
ANP = Field.new
|
148
|
+
ANP.name = "ANP"
|
134
149
|
ANP.codec = ANP_Codec
|
135
150
|
ANP.padding = PADDING_LEFT_JUSTIFIED_SPACES
|
136
151
|
|
137
152
|
# Fixed length ASCII [\x20-\x7E], padding left, spaces
|
138
153
|
ANS = Field.new
|
154
|
+
ANS.name = ANS
|
139
155
|
ANS.codec = ANS_Codec
|
140
156
|
ANS.padding = PADDING_LEFT_JUSTIFIED_SPACES
|
141
157
|
|
142
158
|
# Binary data, padding left using nulls (0x00)
|
143
159
|
B = Field.new
|
160
|
+
B.name = "B"
|
144
161
|
B.codec = Null_Codec
|
145
162
|
B.padding = lambda {|val, len|
|
146
163
|
while val.length < len
|
@@ -151,24 +168,29 @@ module ISO8583
|
|
151
168
|
|
152
169
|
# Date, formatted as described in ASCII numerals
|
153
170
|
MMDDhhmmss = Field.new
|
171
|
+
MMDDhhmmss.name = "MMDDhhmmss"
|
154
172
|
MMDDhhmmss.codec = MMDDhhmmssCodec
|
155
173
|
MMDDhhmmss.length = 10
|
156
174
|
|
157
175
|
#Date, formatted as described in ASCII numerals
|
158
176
|
YYMMDDhhmmss = Field.new
|
177
|
+
YYMMDDhhmmss.name = "YYMMDDhhmmss"
|
159
178
|
YYMMDDhhmmss.codec = YYMMDDhhmmssCodec
|
160
179
|
YYMMDDhhmmss.length = 12
|
161
180
|
|
162
181
|
#Date, formatted as described in ASCII numerals
|
163
182
|
YYMM = Field.new
|
183
|
+
YYMM.name = "YYMM"
|
164
184
|
YYMM.codec = YYMMCodec
|
165
185
|
YYMM.length = 4
|
166
186
|
|
167
187
|
MMDD = Field.new
|
188
|
+
MMDD.name = "MMDD"
|
168
189
|
MMDD.codec = MMDDCodec
|
169
190
|
MMDD.length = 4
|
170
191
|
|
171
192
|
Hhmmss = Field.new
|
193
|
+
Hhmmss.name = "Hhmmss"
|
172
194
|
Hhmmss.codec = HhmmssCodec
|
173
195
|
Hhmmss.length = 6
|
174
196
|
|
data/lib/iso8583/message.rb
CHANGED
@@ -135,7 +135,7 @@ module ISO8583
|
|
135
135
|
# mes = MyMessage.new
|
136
136
|
# mes.mti = 1100 # or mes.mti = "Authorization Request Acquirer Gateway"
|
137
137
|
def mti=(value)
|
138
|
-
num,
|
138
|
+
num, _ = _get_mti_definition(value)
|
139
139
|
@mti = num
|
140
140
|
end
|
141
141
|
|
@@ -173,8 +173,10 @@ module ISO8583
|
|
173
173
|
# Retrieve the byte representation of the bitmap.
|
174
174
|
def to_b
|
175
175
|
raise ISO8583Exception.new "no MTI set!" unless mti
|
176
|
-
mti_enc = self.class._mti_format.encode(mti)
|
177
|
-
|
176
|
+
mti_enc = self.class._mti_format.encode(mti)
|
177
|
+
str_body="".force_encoding('ASCII-8BIT')
|
178
|
+
_body.map {|b| str_body+=b.force_encoding('ASCII-8BIT')}
|
179
|
+
mti_enc << str_body
|
178
180
|
end
|
179
181
|
|
180
182
|
# Returns a nicely formatted representation of this
|
@@ -202,7 +204,7 @@ module ISO8583
|
|
202
204
|
# [bitmap_bytes, message_bytes]
|
203
205
|
def _body
|
204
206
|
bitmap = Bitmap.new
|
205
|
-
message = ""
|
207
|
+
message = "".force_encoding('ASCII-8BIT')
|
206
208
|
@values.keys.sort.each do |bmp_num|
|
207
209
|
bitmap.set(bmp_num)
|
208
210
|
enc_value = @values[bmp_num].encode
|
@@ -341,14 +343,19 @@ module ISO8583
|
|
341
343
|
# @values[bmp] = bmp_def
|
342
344
|
}
|
343
345
|
end
|
344
|
-
|
346
|
+
|
345
347
|
# Parse the bytes `str` returning a message of the defined type.
|
348
|
+
#
|
349
|
+
# returns an instance of Message
|
350
|
+
#
|
351
|
+
# will raise an ISO8583Exception if the bitmap definition can't be found
|
346
352
|
def parse(str)
|
353
|
+
str = str.force_encoding('ASCII-8BIT')
|
347
354
|
message = self.new
|
348
355
|
message.mti, rest = _mti_format.parse(str)
|
349
356
|
bmp,rest = Bitmap.parse(rest)
|
350
357
|
bmp.each {|bit|
|
351
|
-
bmp_def =
|
358
|
+
bmp_def = message._get_definition(bit)
|
352
359
|
value, rest = bmp_def.field.parse(rest)
|
353
360
|
message[bit] = value
|
354
361
|
}
|
data/lib/iso8583/util.rb
CHANGED
@@ -19,20 +19,25 @@ module ISO8583
|
|
19
19
|
#
|
20
20
|
# Convert a String containing hex data to
|
21
21
|
# a String containing the corresponding bytes:
|
22
|
-
#
|
22
|
+
#
|
23
23
|
# hex2b "abcd12" => "\xa\cd\12"
|
24
24
|
#
|
25
25
|
def hex2b(hex_string)
|
26
|
+
|
26
27
|
string = hex_string.gsub(/\s+/, "")
|
28
|
+
|
27
29
|
raise ISO8583Exception.new("Invalid Hex chars: #{hex_string}") unless string =~ /^[A-Fa-f0-9]*$/
|
28
30
|
raise ISO8583Exception.new("Uneven number of Hex chars #{hex_string}") unless ( (string.length % 2) == 0)
|
29
|
-
|
31
|
+
|
32
|
+
[string].pack("H*").force_encoding('ASCII-8BIT')
|
33
|
+
|
30
34
|
end
|
31
35
|
|
36
|
+
|
32
37
|
def _conv(str, mapping)
|
33
|
-
_str = ""
|
38
|
+
_str = "".force_encoding('ASCII-8BIT')
|
34
39
|
str.each_byte{|byte|
|
35
|
-
_str << mapping[byte]
|
40
|
+
_str << [mapping[byte]].pack("C")
|
36
41
|
}
|
37
42
|
_str
|
38
43
|
end
|
data/lib/iso8583/version.rb
CHANGED
data/test/BitmapTests.rb
CHANGED
@@ -22,14 +22,14 @@ class BitmapTests < Test::Unit::TestCase
|
|
22
22
|
|
23
23
|
assert_raises(ISO8583Exception) {b.set 1000 }
|
24
24
|
assert_raises(ISO8583Exception) { b.set 1 }
|
25
|
-
assert_raises(ISO8583Exception) { b.set
|
25
|
+
assert_raises(ISO8583Exception) { b.set(-1) }
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_out_of_bounds_errors
|
29
29
|
b = Bitmap.new
|
30
30
|
assert_raises(ISO8583Exception) {b.set 1000 }
|
31
31
|
assert_raises(ISO8583Exception) { b.set 1 }
|
32
|
-
assert_raises(ISO8583Exception) { b.set
|
32
|
+
assert_raises(ISO8583Exception) { b.set(-1) }
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_parse_bmp
|
@@ -76,5 +76,16 @@ class BitmapTests < Test::Unit::TestCase
|
|
76
76
|
assert_equal [2,3,5,6], arr
|
77
77
|
end
|
78
78
|
|
79
|
+
def test_each_w_two_bitmaps_doesnt_yield_first_field
|
80
|
+
#10000000000000000001000000100000010000001000000100000010000001000000100000010000001000000100000010000001000000100000010000001000
|
81
|
+
# generated by: 20.step(128,7) {|i| mp.set(i)}
|
82
|
+
tst = "\x80\x00\x10\x20\x40\x81\x02\x04\x08\x10\x20\x40\x81\x02\x04\x08"
|
83
|
+
bmp = Bitmap.new tst
|
84
|
+
arr = []
|
85
|
+
bmp.each{|bit|
|
86
|
+
arr.push bit
|
87
|
+
}
|
88
|
+
assert_equal 20, arr.first
|
89
|
+
end
|
79
90
|
end
|
80
91
|
|
data/test/message_test.rb
CHANGED
@@ -38,13 +38,31 @@ class MessageTest < Test::Unit::TestCase
|
|
38
38
|
pan = 474747474747
|
39
39
|
|
40
40
|
assert_raises(ISO8583Exception) {
|
41
|
-
|
41
|
+
BerlinMessage.parse "@\000\000\000\000\000\000\00012474747474747"
|
42
42
|
}
|
43
43
|
mes = BerlinMessage.parse "1430@\000\000\000\000\000\000\00012474747474747"
|
44
44
|
assert_equal pan, mes.pan
|
45
45
|
assert_equal 1430, mes.mti
|
46
46
|
end
|
47
47
|
|
48
|
+
def test_unknown_field
|
49
|
+
assert_raises(ISO8583Exception.new("no definition for field: 8")) {
|
50
|
+
mes = BerlinMessage.parse "1430A\000\000\000\000\000\000\00012474747474747"
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_rescue_standard_error
|
55
|
+
rescued = false
|
56
|
+
begin
|
57
|
+
BerlinMessage.parse("bogus")
|
58
|
+
rescue => error
|
59
|
+
assert_instance_of ISO8583Exception, error
|
60
|
+
rescued = true
|
61
|
+
end
|
62
|
+
|
63
|
+
assert rescued
|
64
|
+
end
|
65
|
+
|
48
66
|
def test_to_s
|
49
67
|
mes = BerlinMessage.new
|
50
68
|
mes.mti = "Network Management Request Response Issuer Gateway or Acquirer Gateway"
|
@@ -157,8 +175,8 @@ END
|
|
157
175
|
mes[64] = "\xF0\xF0\xF0\xF0"
|
158
176
|
|
159
177
|
bytes = mes.to_b
|
160
|
-
mes2 = BerlinMessage.parse(
|
161
|
-
assert_equal(
|
178
|
+
mes2 = BerlinMessage.parse(bytes)
|
179
|
+
assert_equal(bytes, mes2.to_b)
|
162
180
|
end
|
163
181
|
|
164
182
|
def test_remove_field
|
data/test/test_codec.rb
CHANGED
@@ -101,7 +101,7 @@ class FieldTest < Test::Unit::TestCase
|
|
101
101
|
end
|
102
102
|
def test_A_Codec
|
103
103
|
assert_raise(ISO8583Exception) {
|
104
|
-
|
104
|
+
A_Codec.encode "!!!"
|
105
105
|
}
|
106
106
|
assert_equal "bla", AN_Codec.encode("bla")
|
107
107
|
assert_equal "bla", AN_Codec.decode("bla")
|
@@ -109,7 +109,7 @@ class FieldTest < Test::Unit::TestCase
|
|
109
109
|
|
110
110
|
def test_AN_Codec
|
111
111
|
assert_raise(ISO8583Exception) {
|
112
|
-
|
112
|
+
AN_Codec.encode "!!!"
|
113
113
|
}
|
114
114
|
assert_equal "bla", AN_Codec.encode("bla")
|
115
115
|
assert_equal "bla", AN_Codec.decode("bla")
|
@@ -117,10 +117,10 @@ class FieldTest < Test::Unit::TestCase
|
|
117
117
|
|
118
118
|
def test_Track2_Codec
|
119
119
|
assert_raise(ISO8583Exception) {
|
120
|
-
|
120
|
+
Track2.encode "!!!"
|
121
121
|
}
|
122
122
|
assert_raise(ISO8583Exception) {
|
123
|
-
|
123
|
+
Track2.encode ";12312312=123?5"
|
124
124
|
}
|
125
125
|
assert_equal ";123123123=123?5", Track2.encode(";123123123=123?5")
|
126
126
|
assert_equal ";123123123=123?5", Track2.decode(";123123123=123?5")
|
@@ -133,10 +133,48 @@ class FieldTest < Test::Unit::TestCase
|
|
133
133
|
assert_equal "\x02", Packed_Number.encode(2)
|
134
134
|
assert_equal "\x02\x55", Packed_Number.encode(0xff)
|
135
135
|
assert_raise(ISO8583Exception) {
|
136
|
-
|
136
|
+
Packed_Number.encode ";12312312=123?5"
|
137
137
|
}
|
138
138
|
assert_raise(ISO8583Exception) {
|
139
|
-
|
139
|
+
Packed_Number.encode "F"
|
140
140
|
}
|
141
141
|
end
|
142
|
+
|
143
|
+
def test_BE_U16
|
144
|
+
assert_raise(ISO8583Exception) {
|
145
|
+
BE_U16.encode 2**16
|
146
|
+
}
|
147
|
+
assert_raise(ISO8583Exception) {
|
148
|
+
BE_U16.encode(-1)
|
149
|
+
}
|
150
|
+
assert_equal "\0\0", BE_U16.encode(0)
|
151
|
+
expected = "\xff\xff".force_encoding('ASCII-8BIT')
|
152
|
+
assert_equal expected, BE_U16.encode(2**16-1)
|
153
|
+
expected = "\x0f\xf0".force_encoding('ASCII-8BIT')
|
154
|
+
assert_equal expected, BE_U16.encode(0x00000ff0)
|
155
|
+
expected = "\xf0\x0f".force_encoding('ASCII-8BIT')
|
156
|
+
assert_equal expected, BE_U16.encode(0x0000f00f)
|
157
|
+
expected = "\x5A\xA5".force_encoding('ASCII-8BIT')
|
158
|
+
assert_equal expected, BE_U16.encode(0b0101101010100101)
|
159
|
+
|
160
|
+
assert_equal 0x5aa5, BE_U16.decode(expected)
|
161
|
+
end
|
162
|
+
def test_BE_U32
|
163
|
+
assert_raise(ISO8583Exception) {
|
164
|
+
BE_U32.encode 2**32
|
165
|
+
}
|
166
|
+
assert_raise(ISO8583Exception) {
|
167
|
+
BE_U32.encode(-1)
|
168
|
+
}
|
169
|
+
assert_equal "\0\0\0\0", BE_U32.encode(0)
|
170
|
+
expected = "\xff\xff\xff\xff".force_encoding('ASCII-8BIT')
|
171
|
+
assert_equal expected, BE_U32.encode(2**32-1)
|
172
|
+
expected = "\xf0\xf0\x0f\x0f".force_encoding('ASCII-8BIT')
|
173
|
+
assert_equal expected, BE_U32.encode(0xf0f00f0f)
|
174
|
+
expected = "\0\0\0\x1".force_encoding('ASCII-8BIT')
|
175
|
+
assert_equal expected, BE_U32.encode(1)
|
176
|
+
|
177
|
+
assert_equal 1, BE_U32.decode(expected)
|
178
|
+
assert_equal 10, BE_U32.decode("\0\0\0\xa")
|
179
|
+
end
|
142
180
|
end
|
data/test/test_fields.rb
CHANGED
@@ -10,7 +10,7 @@ class FieldTest < Test::Unit::TestCase
|
|
10
10
|
assert_equal "456", rest
|
11
11
|
|
12
12
|
assert_raise(ISO8583ParseException) {
|
13
|
-
|
13
|
+
_,rest = LLL.parse "12"
|
14
14
|
}
|
15
15
|
|
16
16
|
enc = LLL.encode 123
|
@@ -50,10 +50,10 @@ class FieldTest < Test::Unit::TestCase
|
|
50
50
|
assert_equal "123ABC", value
|
51
51
|
assert_equal "", rest
|
52
52
|
assert_raise(ISO8583ParseException) {
|
53
|
-
|
53
|
+
_,rest = LLLVAR_AN.parse "12"
|
54
54
|
}
|
55
55
|
assert_raise(ISO8583ParseException) {
|
56
|
-
|
56
|
+
_,rest = LLVAR_AN.parse "12123"
|
57
57
|
}
|
58
58
|
|
59
59
|
enc = LLVAR_AN.encode "123A"
|
@@ -83,10 +83,10 @@ class FieldTest < Test::Unit::TestCase
|
|
83
83
|
assert_equal 1234, value
|
84
84
|
assert_equal "", rest
|
85
85
|
assert_raise(ISO8583ParseException) {
|
86
|
-
|
86
|
+
_,rest = LLLVAR_N.parse "12"
|
87
87
|
}
|
88
88
|
assert_raise(ISO8583ParseException) {
|
89
|
-
|
89
|
+
_,rest = LLVAR_N.parse "12123"
|
90
90
|
}
|
91
91
|
|
92
92
|
enc = LLVAR_N.encode 1234
|
@@ -116,10 +116,10 @@ class FieldTest < Test::Unit::TestCase
|
|
116
116
|
assert_equal ";123123123=123?5", value
|
117
117
|
assert_equal "", rest
|
118
118
|
assert_raise(ISO8583ParseException) {
|
119
|
-
|
119
|
+
_,rest = LLVAR_Z.parse "12"
|
120
120
|
}
|
121
121
|
assert_raise(ISO8583ParseException) {
|
122
|
-
|
122
|
+
_,rest = LLVAR_Z.parse "17;123123123=123?5"
|
123
123
|
}
|
124
124
|
|
125
125
|
enc = LLVAR_Z.encode ";123123123=123?5"
|
@@ -213,6 +213,7 @@ class FieldTest < Test::Unit::TestCase
|
|
213
213
|
fld.length=3
|
214
214
|
value, rest = fld.parse "\x01\x23\x45"
|
215
215
|
assert_equal 123, value
|
216
|
+
assert_equal "\x45", rest
|
216
217
|
|
217
218
|
assert_equal "\x01\x23", fld.encode(123)
|
218
219
|
assert_equal "\x01\x23", fld.encode("123")
|
@@ -241,6 +242,7 @@ class FieldTest < Test::Unit::TestCase
|
|
241
242
|
assert_equal 12, dt.hour
|
242
243
|
assert_equal 34, dt.min
|
243
244
|
assert_equal 56, dt.sec
|
245
|
+
assert_equal "", rest
|
244
246
|
|
245
247
|
assert_raise(ISO8583Exception) {
|
246
248
|
fld.encode 1234567
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'lib/iso8583'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
|
5
|
+
class TestMessage < Message
|
6
|
+
mti_format N, :length => 4
|
7
|
+
mti 1100, "Authorization Request Acquirer Gateway"
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestMessage2 < Message
|
11
|
+
mti_format N_BCD, :length => 4
|
12
|
+
mti 1100, "Authorization Request Acquirer Gateway"
|
13
|
+
end
|
14
|
+
|
15
|
+
class MessageMetaclassTest < Test::Unit::TestCase
|
16
|
+
def test_mti
|
17
|
+
t = TestMessage.new
|
18
|
+
t.mti = 1100
|
19
|
+
expected = "1100\0\0\0\0\0\0\0\0"
|
20
|
+
bs = t.to_b
|
21
|
+
assert_equal expected, bs
|
22
|
+
end
|
23
|
+
def test_len_prefix
|
24
|
+
t = TestMessage2.new
|
25
|
+
t.mti = 1100
|
26
|
+
expected = "\x11\0\0\0\0\0\0\0\0\0"
|
27
|
+
bs = t.to_b
|
28
|
+
assert_equal expected, bs
|
29
|
+
end
|
30
|
+
end
|
data/test/test_util.rb
CHANGED
@@ -5,9 +5,18 @@ include ISO8583
|
|
5
5
|
|
6
6
|
class UtilTest < Test::Unit::TestCase
|
7
7
|
def test_hex2b
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# weird ruby 2.0 workaround:
|
9
|
+
# literal:
|
10
|
+
# "\xab\xcd\x12"
|
11
|
+
# is interpretted as:
|
12
|
+
# "\xAB\xCD\u0012"
|
13
|
+
# ...force_encoding(...) fixes this.
|
14
|
+
|
15
|
+
expected = "\xab\xcd\x12".force_encoding("ASCII-8BIT")
|
16
|
+
|
17
|
+
assert_equal expected, hex2b("abcd12")
|
18
|
+
assert_equal expected, hex2b("a b c d 1 2")
|
19
|
+
assert_equal expected, hex2b("ABCD12")
|
11
20
|
assert_raise(ISO8583Exception){
|
12
21
|
# non hex
|
13
22
|
hex2b("ABCDEFGH")
|
@@ -27,6 +36,6 @@ class UtilTest < Test::Unit::TestCase
|
|
27
36
|
end
|
28
37
|
|
29
38
|
def test_ascii2ebcdic
|
30
|
-
assert_equal "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9", ascii2ebcdic("0123456789")
|
39
|
+
assert_equal "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9".force_encoding('ASCII-8BIT'), ascii2ebcdic("0123456789")
|
31
40
|
end
|
32
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iso8583
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Becker
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description:
|
14
|
+
description: 'Ruby implementation of ISO 8583 financial messaging
|
15
15
|
|
16
|
-
'
|
16
|
+
'
|
17
17
|
email:
|
18
18
|
- tim.becker@kuriositaet.de
|
19
19
|
- cordawyn@gmail.com
|
@@ -23,8 +23,9 @@ extra_rdoc_files: []
|
|
23
23
|
files:
|
24
24
|
- AUTHORS
|
25
25
|
- CHANGELOG
|
26
|
+
- Gemfile
|
26
27
|
- LICENSE
|
27
|
-
- README
|
28
|
+
- README.md
|
28
29
|
- Rakefile
|
29
30
|
- TODO
|
30
31
|
- lib/8583.rb
|
@@ -42,6 +43,7 @@ files:
|
|
42
43
|
- test/message_test.rb
|
43
44
|
- test/test_codec.rb
|
44
45
|
- test/test_fields.rb
|
46
|
+
- test/test_message_metaclass.rb
|
45
47
|
- test/test_seperate_msg.rb
|
46
48
|
- test/test_util.rb
|
47
49
|
homepage: http://github.com/a2800276/8583/
|
@@ -53,19 +55,18 @@ require_paths:
|
|
53
55
|
- lib
|
54
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
57
|
requirements:
|
56
|
-
- -
|
58
|
+
- - ">="
|
57
59
|
- !ruby/object:Gem::Version
|
58
60
|
version: '0'
|
59
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
62
|
requirements:
|
61
|
-
- -
|
63
|
+
- - ">="
|
62
64
|
- !ruby/object:Gem::Version
|
63
65
|
version: '0'
|
64
66
|
requirements:
|
65
67
|
- none
|
66
|
-
|
67
|
-
rubygems_version: 2.2.2
|
68
|
+
rubygems_version: 3.1.2
|
68
69
|
signing_key:
|
69
70
|
specification_version: 4
|
70
|
-
summary:
|
71
|
+
summary: 'iso8583: Ruby implementation of ISO 8583 financial messaging'
|
71
72
|
test_files: []
|
data/README
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
= ISO 8583 Financial Messaging for Ruby
|
2
|
-
|
3
|
-
This package currently contains code for coding an decoding ISO 8583
|
4
|
-
Financial Message.
|
5
|
-
|
6
|
-
== Using
|
7
|
-
|
8
|
-
The best place to get started using the library is the documentation of the
|
9
|
-
Message class. Once a stable state is reached, this should be the only
|
10
|
-
class you need to use ...
|
11
|
-
|
12
|
-
== Installing
|
13
|
-
|
14
|
-
You can install the +iso8583+ package by executing:
|
15
|
-
|
16
|
-
gem install iso8583
|
17
|
-
|
18
|
-
== Source
|
19
|
-
|
20
|
-
The source is most readily available on github[http://github.com/a2800276/8583].
|
21
|
-
|
22
|
-
== Mailing List
|
23
|
-
|
24
|
-
In case you discover bugs, spelling errors, offer suggestions for
|
25
|
-
improvements or would like to help out with the project, you can contact
|
26
|
-
me directly (tim@kuriositaet.de).
|