iso8583 0.1.6 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/a2800276/8583.svg?branch=master)](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).
|