barcodes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +22 -0
  6. data/README.md +107 -0
  7. data/Rakefile +11 -0
  8. data/barcodes.gemspec +24 -0
  9. data/bin/barcodes +6 -0
  10. data/lib/barcodes.rb +63 -0
  11. data/lib/barcodes/exec.rb +74 -0
  12. data/lib/barcodes/renderer.rb +9 -0
  13. data/lib/barcodes/renderer/ascii.rb +199 -0
  14. data/lib/barcodes/renderer/pdf.rb +257 -0
  15. data/lib/barcodes/symbology.rb +47 -0
  16. data/lib/barcodes/symbology/base.rb +103 -0
  17. data/lib/barcodes/symbology/codabar.rb +36 -0
  18. data/lib/barcodes/symbology/code11.rb +74 -0
  19. data/lib/barcodes/symbology/code128.rb +317 -0
  20. data/lib/barcodes/symbology/code39.rb +48 -0
  21. data/lib/barcodes/symbology/code39extended.rb +93 -0
  22. data/lib/barcodes/symbology/code39extendedmod43.rb +73 -0
  23. data/lib/barcodes/symbology/code39mod43.rb +73 -0
  24. data/lib/barcodes/symbology/code93.rb +142 -0
  25. data/lib/barcodes/symbology/code93extended.rb +116 -0
  26. data/lib/barcodes/symbology/ean.rb +149 -0
  27. data/lib/barcodes/symbology/ean13.rb +27 -0
  28. data/lib/barcodes/symbology/ean8.rb +50 -0
  29. data/lib/barcodes/symbology/interleaved2of5.rb +30 -0
  30. data/lib/barcodes/symbology/interleaved2of5mod10.rb +40 -0
  31. data/lib/barcodes/symbology/msi.rb +30 -0
  32. data/lib/barcodes/symbology/msimod10.rb +50 -0
  33. data/lib/barcodes/symbology/msimod11.rb +37 -0
  34. data/lib/barcodes/symbology/planet.rb +83 -0
  35. data/lib/barcodes/symbology/postnet.rb +83 -0
  36. data/lib/barcodes/symbology/standard2of5.rb +30 -0
  37. data/lib/barcodes/symbology/standard2of5mod10.rb +40 -0
  38. data/lib/barcodes/symbology/upca.rb +27 -0
  39. data/lib/barcodes/version.rb +3 -0
  40. data/spec/barcodes/exec_spec.rb +14 -0
  41. data/spec/barcodes/renderer/ascii_spec.rb +12 -0
  42. data/spec/barcodes/renderer/pdf_spec.rb +12 -0
  43. data/spec/barcodes/symbology/base_spec.rb +8 -0
  44. data/spec/barcodes/symbology/codabar_spec.rb +8 -0
  45. data/spec/barcodes/symbology/code11_spec.rb +8 -0
  46. data/spec/barcodes/symbology/code128_spec.rb +8 -0
  47. data/spec/barcodes/symbology/code39_spec.rb +8 -0
  48. data/spec/barcodes/symbology/code39extended_spec.rb +8 -0
  49. data/spec/barcodes/symbology/code39extendedmod43_spec.rb +8 -0
  50. data/spec/barcodes/symbology/code39mod43_spec.rb +8 -0
  51. data/spec/barcodes/symbology/code93_spec.rb +8 -0
  52. data/spec/barcodes/symbology/code93extended_spec.rb +8 -0
  53. data/spec/barcodes/symbology/ean13_spec.rb +8 -0
  54. data/spec/barcodes/symbology/ean8_spec.rb +8 -0
  55. data/spec/barcodes/symbology/ean_spec.rb +8 -0
  56. data/spec/barcodes/symbology/interleaved2of5_spec.rb +8 -0
  57. data/spec/barcodes/symbology/interleaved2of5mod10_spec.rb +8 -0
  58. data/spec/barcodes/symbology/msi_spec.rb +8 -0
  59. data/spec/barcodes/symbology/msimod10_spec.rb +8 -0
  60. data/spec/barcodes/symbology/msimod11_spec.rb +8 -0
  61. data/spec/barcodes/symbology/planet_spec.rb +8 -0
  62. data/spec/barcodes/symbology/postnet_spec.rb +8 -0
  63. data/spec/barcodes/symbology/standard2of5_spec.rb +8 -0
  64. data/spec/barcodes/symbology/standard2of5mod10_spec.rb +8 -0
  65. data/spec/barcodes/symbology/upca_spec.rb +8 -0
  66. data/spec/barcodes_spec.rb +27 -0
  67. data/spec/spec_helper.rb +17 -0
  68. metadata +174 -0
@@ -0,0 +1,317 @@
1
+ require 'barcodes/symbology/base'
2
+
3
+ module Barcodes
4
+ module Symbology
5
+ class Code128 < Base
6
+ # Assigned to codesets are the following special characters representing Code 128 functions
7
+ # START_A - \xF4, START_B - \xF5, START_C - \xF6,
8
+ # CODE_A - \xF7, CODE_B - \xF8, CODE_C - \xF9,
9
+ # FNC1 - \xFA, FNC2 - \xFB, FNC3 - \xFC, FNC4 - \xFD,
10
+ # SHIFT - \xFE, STOP - \xFF
11
+ def self.charset
12
+ [].collect {|c| c.bytes.to_a[0] }
13
+ end
14
+
15
+ def self.charset_a
16
+ [
17
+ " ","!","\"","#","$","%","&","'","(",")","*","+",",","-",".","/",
18
+ "0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@",
19
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q",
20
+ "R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","\x00","\x01",
21
+ "\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0A","\x0B",
22
+ "\x0C","\x0D","\x0E","\x0F","\x10","\x11","\x12","\x13","\x14","\x15",
23
+ "\x16","\x17","\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
24
+ "\xFC","\xFB","\xFE","\xF9","\xF8","\xFD","\xFA","\xF4","\xF5","\xF6",
25
+ "\xFF"
26
+ ].collect {|c| c.bytes.to_a[0] }
27
+ end
28
+
29
+ def self.charset_b
30
+ [
31
+ " ","!","\"","#","$","%","&","'","(",")","*","+",",","-",".","/",
32
+ "0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@",
33
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q",
34
+ "R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`","a","b",
35
+ "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s",
36
+ "t","u","v","w","x","y","z","{","|","}","~","\x7F","\xFC","\xFB","\xFE",
37
+ "\xF9","\xFD","\xF7","\xFA","\xF4","\xF5","\xF6","\xFF"
38
+ ].collect {|c| c.bytes.to_a[0] }
39
+ end
40
+
41
+ def self.charset_c
42
+ [
43
+ "00","01","02","03","04","05","06","07","08","09","10","11","12","13",
44
+ "14","15","16","17","18","19","20","21","22","23","24","25","26","27",
45
+ "28","29","30","31","32","33","34","35","36","37","38","39","40","41",
46
+ "42","43","44","45","46","47","48","49","50","51","52","53","54","55",
47
+ "56","57","58","59","60","61","62","63","64","65","66","67","68","69",
48
+ "70","71","72","73","74","75","76","77","78","79","80","81","82","83",
49
+ "84","85","86","87","88","89","90","91","92","93","94","95","96","97",
50
+ "98","99","\xF8","\xF7","\xFA","\xF4","\xF5","\xF6","\xFF"
51
+ ].collect {|c| c.bytes.to_a.length > 1 ? c.bytes.to_a : c.bytes.to_a[0] }
52
+ end
53
+
54
+ def self.valueset
55
+ [
56
+ "11011001100","11001101100","11001100110","10010011000","10010001100",
57
+ "10001001100","10011001000","10011000100","10001100100","11001001000",
58
+ "11001000100","11000100100","10110011100","10011011100","10011001110",
59
+ "10111001100","10011101100","10011100110","11001110010","11001011100",
60
+ "11001001110","11011100100","11001110100","11101101110","11101001100",
61
+ "11100101100","11100100110","11101100100","11100110100","11100110010",
62
+ "11011011000","11011000110","11000110110","10100011000","10001011000",
63
+ "10001000110","10110001000","10001101000","10001100010","11010001000",
64
+ "11000101000","11000100010","10110111000","10110001110","10001101110",
65
+ "10111011000","10111000110","10001110110","11101110110","11010001110",
66
+ "11000101110","11011101000","11011100010","11011101110","11101011000",
67
+ "11101000110","11100010110","11101101000","11101100010","11100011010",
68
+ "11101111010","11001000010","11110001010","10100110000","10100001100",
69
+ "10010110000","10010000110","10000101100","10000100110","10110010000",
70
+ "10110000100","10011010000","10011000010","10000110100","10000110010",
71
+ "11000010010","11001010000","11110111010","11000010100","10001111010",
72
+ "10100111100","10010111100","10010011110","10111100100","10011110100",
73
+ "10011110010","11110100100","11110010100","11110010010","11011011110",
74
+ "11011110110","11110110110","10101111000","10100011110","10001011110",
75
+ "10111101000","10111100010","11110101000","11110100010","10111011110",
76
+ "10111101110","11101011110","11110101110","11010000100","11010010000",
77
+ "11010011100","1100011101011"
78
+ ]
79
+ end
80
+
81
+ def formatted_data
82
+ self._prepared_data + self.checksum + "\xFF"
83
+ end
84
+
85
+ def encoded_data
86
+ if self.valid?
87
+ encoded_data = ""
88
+ charset = 'B'
89
+ char_c = nil
90
+ self.formatted_data.each_byte do |char|
91
+ if char == "\xF4".bytes.to_a[0] || char == "\xF5".bytes.to_a[0] || char == "\xF6".bytes.to_a[0]
92
+ case char
93
+ when "\xF4".bytes.to_a[0]
94
+ encoded_data += self._encode_character_in_charset(char, 'A')
95
+ charset = 'A'
96
+ when "\xF5".bytes.to_a[0]
97
+ encoded_data += self._encode_character_in_charset(char, 'B')
98
+ charset = 'B'
99
+ when "\xF6".bytes.to_a[0]
100
+ encoded_data += self._encode_character_in_charset(char, 'C')
101
+ charset = 'C'
102
+ end
103
+ elsif char == "\xF7".bytes.to_a[0] || char == "\xF8".bytes.to_a[0] || char == "\xF9".bytes.to_a[0] || char == "\xFE".bytes.to_a[0]
104
+ case char
105
+ when "\xF7".bytes.to_a[0]
106
+ encoded_data += self._encode_character_in_charset(char, charset)
107
+ charset = 'A'
108
+ when "\xF8".bytes.to_a[0]
109
+ encoded_data += self._encode_character_in_charset(char, charset)
110
+ charset = 'B'
111
+ when "\xF9".bytes.to_a[0]
112
+ encoded_data += self._encode_character_in_charset(char, charset)
113
+ charset = 'C'
114
+ when "\xFE".bytes.to_a[0]
115
+ if charset == 'A'
116
+ encoded_data += self._encode_character_in_charset(char, charset)
117
+ charset = 'B'
118
+ elsif charset == 'B'
119
+ encoded_data += self._encode_character_in_charset(char, charset)
120
+ charset = 'A'
121
+ end
122
+ end
123
+ else
124
+ if charset == 'C'
125
+ if char > 127
126
+ encoded_data += self._encode_character_in_charset(char, charset)
127
+ else
128
+ if char_c.nil?
129
+ char_c = char
130
+ else
131
+ encoded_data += self._encode_character_in_charset([char_c, char], charset)
132
+ char_c = nil
133
+ end
134
+ end
135
+ else
136
+ encoded_data += self._encode_character_in_charset(char, charset)
137
+ end
138
+ end
139
+ end
140
+ return encoded_data
141
+ end
142
+ end
143
+
144
+ def checksum
145
+ if valid?
146
+ sum = 0
147
+ index = 0
148
+ charset = self.class.charset_b
149
+ char_c = nil
150
+ self._prepared_data.each_byte do |char|
151
+ if char == "\xF4".bytes.to_a[0] || char == "\xF5".bytes.to_a[0] || char == "\xF6".bytes.to_a[0]
152
+ sum += self.class.charset_a.index(char) if self.class.charset_a.include?(char)
153
+ index += 1
154
+
155
+ case char
156
+ when "\xF4".bytes.to_a[0]
157
+ charset = self.class.charset_a
158
+ when "\xF5".bytes.to_a[0]
159
+ charset = self.class.charset_b
160
+ when "\xF6".bytes.to_a[0]
161
+ charset = self.class.charset_c
162
+ end
163
+ elsif char == "\xF7".bytes.to_a[0] || char == "\xF8".bytes.to_a[0] || char == "\xF9".bytes.to_a[0] || char == "\xFE".bytes.to_a[0]
164
+ sum += charset.index(char) * index if charset.include?(char)
165
+ index += 1
166
+
167
+ case char
168
+ when "\xF7".bytes.to_a[0]
169
+ charset = self.class.charset_a
170
+ when "\xF8".bytes.to_a[0]
171
+ charset = self.class.charset_b
172
+ when "\xF9".bytes.to_a[0]
173
+ charset = self.class.charset_c
174
+ when "\xFE".bytes.to_a[0]
175
+ if charset == self.class.charset_a
176
+ charset = self.class.charset_b
177
+ elsif charset == self.class.charset_b
178
+ charset = self.class.charset_a
179
+ end
180
+ end
181
+ else
182
+ if charset == self.class.charset_c
183
+ if char_c.nil?
184
+ char_c = char
185
+ else
186
+ sum += charset.index([char_c, char]) * index if charset.include?([char_c, char])
187
+ index += 1
188
+ char_c = nil
189
+ end
190
+ else
191
+ sum += charset.index(char) * index if charset.include?(char)
192
+ index += 1
193
+ end
194
+ end
195
+ end
196
+
197
+ value = sum % 103
198
+
199
+ if charset == self.class.charset_c
200
+ return charset.at(value)[0].chr + charset.at(value)[1].chr
201
+ else
202
+ return charset.at(value).chr
203
+ end
204
+ end
205
+ end
206
+
207
+ def valid?
208
+ valid = @data.length > 0 ? true : false
209
+
210
+ @data.each_byte do |char|
211
+ if self._encode_character_in_charset(char, 'A').nil? &&
212
+ self._encode_character_in_charset(char, 'B').nil?
213
+ return false
214
+ end
215
+ end
216
+
217
+ return valid
218
+ end
219
+
220
+ protected
221
+
222
+ def _prepared_data
223
+ start = "\xF5"
224
+ charset = "B"
225
+ data = ""
226
+ cursor = 0
227
+
228
+ if /^[\d]{4,}/ === @data
229
+ start = "\xF6"
230
+ charset = "C"
231
+ elsif self._encode_character_in_charset(@data.bytes.to_a[0], 'B').nil?
232
+ start = "\xF4"
233
+ charset = "A"
234
+ end
235
+ data += start
236
+
237
+ (0...@data.length).each do |i|
238
+ if charset == 'C' && cursor > i
239
+ next
240
+ else
241
+ if charset == 'C' && /^[\d]{4,}/ === @data[i...@data.length]
242
+ integers = 0
243
+ (cursor...@data.length).each do |j|
244
+ if /^[\d]/ === @data[j]
245
+ integers += 1
246
+ else
247
+ break
248
+ end
249
+ end
250
+
251
+ if integers.even?
252
+ data += @data[cursor...(cursor + integers)]
253
+ cursor += integers
254
+ else
255
+ data += @data[cursor...(cursor + integers - 1)]
256
+ cursor += integers - 1
257
+ end
258
+ else
259
+ if /^[\d]{4,}/ === @data[i...@data.length] && charset != 'C'
260
+ data += "\xF9"
261
+ charset = "C"
262
+ elsif self._encode_character_in_charset(@data.bytes.to_a[i], charset).nil?
263
+ if charset == 'C'
264
+ if self._encode_character_in_charset(@data.bytes.to_a[i], 'B').nil?
265
+ data += "\xF7"
266
+ charset = "A"
267
+ else
268
+ data += "\xF8"
269
+ charset = "B"
270
+ end
271
+ else
272
+ # Shift
273
+ data += "\xFE"
274
+ if charset == "A"
275
+ charset = "B"
276
+ else
277
+ charset = "A"
278
+ end
279
+ end
280
+ data += @data[cursor]
281
+ cursor += 1
282
+ else
283
+ data += @data[cursor]
284
+ cursor += 1
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ return data
291
+ end
292
+
293
+ def _encode_character(character)
294
+ return nil
295
+ end
296
+
297
+ def _encode_character_in_charset(character, charset)
298
+ case charset
299
+ when 'A'
300
+ selected_charset = self.class.charset_a
301
+ when 'B'
302
+ selected_charset = self.class.charset_b
303
+ when 'C'
304
+ selected_charset = self.class.charset_c
305
+ else
306
+ return nil
307
+ end
308
+
309
+ if selected_charset.include? character
310
+ return self.class.valueset.at(selected_charset.index(character))
311
+ else
312
+ return nil
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,48 @@
1
+ require 'barcodes/symbology/base'
2
+
3
+ module Barcodes
4
+ module Symbology
5
+ class Code39 < Base
6
+ def self.charset
7
+ [
8
+ '0','1','2','3','4','5','6','7','8','9',
9
+ 'A','B','C','D','E','F','G','H','I','J',
10
+ 'K','L','M','N','O','P','Q','R','S','T',
11
+ 'U','V','W','X','Y','Z',' ','-','.','$',
12
+ '/','+','%','*'
13
+ ].collect {|c| c.bytes.to_a[0] }
14
+ end
15
+
16
+ def self.valueset
17
+ [
18
+ "1010011011010","1101001010110","1011001010110","1101100101010",
19
+ "1010011010110","1010011010110","1011001101010","1011001101010",
20
+ "1101001011010","1011001011010","1101010010110","1011010010110",
21
+ "1101101001010","1010110010110","1101011001010","1011011001010",
22
+ "1010100110110","1101010011010","1011010011010","1010110011010",
23
+ "1101010100110","1011010100110","1101101010010","1010110100110",
24
+ "1101011010010","1011011010010","1010101100110","1101010110010",
25
+ "1011010110010","1010110110010","1100101010110","1001101010110",
26
+ "1100110101010","1001011010110","1100101101010","1001101101010",
27
+ "1001101011010","1001010110110","1100101011010","1001001001010",
28
+ "1001001010010","1001010010010","1010010010010","1001011011010"
29
+ ]
30
+ end
31
+
32
+ def initialize(args={})
33
+ super(args)
34
+
35
+ @start_character = '*'
36
+ @stop_character = '*'
37
+ end
38
+
39
+ def caption_data
40
+ self.formatted_data
41
+ end
42
+
43
+ def formatted_data
44
+ @start_character + @data + @stop_character
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,93 @@
1
+ require 'barcodes/symbology/code39'
2
+
3
+ module Barcodes
4
+ module Symbology
5
+ class Code39Extended < Code39
6
+
7
+ protected
8
+
9
+ def _encode_character(character)
10
+ unless (character == 36 || character == 37 || character == 43)
11
+ unless super(character).nil?
12
+ return super(character)
13
+ end
14
+ end
15
+
16
+ case character
17
+ when 0
18
+ return super('%'.bytes.to_a[0]) + super('U'.bytes.to_a[0])
19
+ when 1..26
20
+ return super('$'.bytes.to_a[0]) + super((character.bytes.to_a[0] + 64))
21
+ when 27..31
22
+ return super('%'.bytes.to_a[0]) + super((character.bytes.to_a[0] + 38))
23
+ when 127
24
+ return super('%'.bytes.to_a[0]) + super('T'.bytes.to_a[0])
25
+ when '!'.bytes.to_a[0]
26
+ return super('/'.bytes.to_a[0]) + super('A'.bytes.to_a[0])
27
+ when '"'.bytes.to_a[0]
28
+ return super('/'.bytes.to_a[0]) + super('B'.bytes.to_a[0])
29
+ when '#'.bytes.to_a[0]
30
+ return super('/'.bytes.to_a[0]) + super('C'.bytes.to_a[0])
31
+ when '$'.bytes.to_a[0]
32
+ return super('/'.bytes.to_a[0]) + super('D'.bytes.to_a[0])
33
+ when '%'.bytes.to_a[0]
34
+ return super('/'.bytes.to_a[0]) + super('E'.bytes.to_a[0])
35
+ when '&'.bytes.to_a[0]
36
+ return super('/'.bytes.to_a[0]) + super('F'.bytes.to_a[0])
37
+ when '\''.bytes.to_a[0]
38
+ return super('/'.bytes.to_a[0]) + super('G'.bytes.to_a[0])
39
+ when '('.bytes.to_a[0]
40
+ return super('/'.bytes.to_a[0]) + super('H'.bytes.to_a[0])
41
+ when ')'.bytes.to_a[0]
42
+ return super('/'.bytes.to_a[0]) + super('I'.bytes.to_a[0])
43
+ when '*'.bytes.to_a[0]
44
+ return super('/'.bytes.to_a[0]) + super('J'.bytes.to_a[0])
45
+ when '+'.bytes.to_a[0]
46
+ return super('/'.bytes.to_a[0]) + super('K'.bytes.to_a[0])
47
+ when ','.bytes.to_a[0]
48
+ return super('/'.bytes.to_a[0]) + super('L'.bytes.to_a[0])
49
+ when '/'.bytes.to_a[0]
50
+ return super('/'.bytes.to_a[0]) + super('O'.bytes.to_a[0])
51
+ when ':'.bytes.to_a[0]
52
+ return super('/'.bytes.to_a[0]) + super('Z'.bytes.to_a[0])
53
+ when ';'.bytes.to_a[0]
54
+ return super('%'.bytes.to_a[0]) + super('F'.bytes.to_a[0])
55
+ when '<'.bytes.to_a[0]
56
+ return super('%'.bytes.to_a[0]) + super('G'.bytes.to_a[0])
57
+ when '='.bytes.to_a[0]
58
+ return super('%'.bytes.to_a[0]) + super('H'.bytes.to_a[0])
59
+ when '>'.bytes.to_a[0]
60
+ return super('%'.bytes.to_a[0]) + super('I'.bytes.to_a[0])
61
+ when '?'.bytes.to_a[0]
62
+ return super('%'.bytes.to_a[0]) + super('J'.bytes.to_a[0])
63
+ when '@'.bytes.to_a[0]
64
+ return super('%'.bytes.to_a[0]) + super('V'.bytes.to_a[0])
65
+ when '['.bytes.to_a[0]
66
+ return super('%'.bytes.to_a[0]) + super('K'.bytes.to_a[0])
67
+ when '\\'.bytes.to_a[0]
68
+ return super('%'.bytes.to_a[0]) + super('L'.bytes.to_a[0])
69
+ when ']'.bytes.to_a[0]
70
+ return super('%'.bytes.to_a[0]) + super('M'.bytes.to_a[0])
71
+ when '^'.bytes.to_a[0]
72
+ return super('%'.bytes.to_a[0]) + super('N'.bytes.to_a[0])
73
+ when '_'.bytes.to_a[0]
74
+ return super('%'.bytes.to_a[0]) + super('0'.bytes.to_a[0])
75
+ when '`'.bytes.to_a[0]
76
+ return super('%'.bytes.to_a[0]) + super('W'.bytes.to_a[0])
77
+ when 97..122
78
+ return super('+'.bytes.to_a[0]) + super(character.chr.upcase.bytes.to_a[0])
79
+ when '{'.bytes.to_a[0]
80
+ return super('%'.bytes.to_a[0]) + super('P'.bytes.to_a[0])
81
+ when '|'.bytes.to_a[0]
82
+ return super('%'.bytes.to_a[0]) + super('Q'.bytes.to_a[0])
83
+ when '}'.bytes.to_a[0]
84
+ return super('%'.bytes.to_a[0]) + super('R'.bytes.to_a[0])
85
+ when '~'.bytes.to_a[0]
86
+ return super('%'.bytes.to_a[0]) + super('S'.bytes.to_a[0])
87
+ else
88
+ return nil
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end