Class: Barcode1DTools::Interleaved2of5
- Defined in:
- lib/barcode1dtools/interleaved2of5.rb
Overview
Barcode1DTools::Interleaved2of5 - Create pattern for Interleaved 2 of 5 (also known as I 2/5 or ITF) barcodes. The value encoded is an integer, and a checksum digit will be added. You can add the option :checksum_included => true when initializing to specify that you have already included a checksum, or :skip_checksum => true to specify that no checksum should be added or checked. A ChecksumError will be raised if :checksum_included => true, :skip_checksum is missing or false, and the last digit is invalid as a checksum.
I 2/5 can only encode an even number of digits (including the checksum), so a “0” will be prepended if there is an odd number of digits. The 0 has no effect on the checksum. Note that sometimes an odd number of digits is encoded with 5 narrow spaces for the last digit. We do not encode this way but can handle decoding.
Example
num = 238982
bc = Barcode1DTools::Interleaved2of5.new(num)
pattern = bc.
rle_pattern = bc.rle
wn_pattern = bc.wn
width = bc.width
check_digit = Barcode1DTools::Interleaved2of5.generate_check_digit_for(num)
The object created is immutable.
Barcode1DTools::Interleaved2of5 creates the patterns that you need to display Interleaved 2 of 5 (also known as I 2/5) barcodes. It can also decode a simple w/n string.
I 2/5 barcodes consist of lines and spaces that are either “wide” or “narrow”, with “wide” lines or spaces being twice the width of narrow lines or spaces.
Formats
There are three formats for the returned pattern:
bars - 1s and 0s specifying black lines and white spaces. Actual characters can be changed from “1” and 0“ with options :line_character and :space_character.
rle - Run-length-encoded version of the pattern. The first number is always a black line, with subsequent digits alternating between spaces and lines. The digits specify the width of each line or space.
wn - The native format for this barcode type. The string consists of a series of “w” and “n” characters. The first item is always a black line, with subsequent characters alternating between spaces and lines. A “wide” item is twice the width of a “narrow” item.
The “width” method will tell you the total end-to-end width, in units, of the entire barcode.
In this encoding, pairs of digits are interleaved with each other, so the first digit is the “bars” and the second digit is the “spaces”. Each digit consists of 5 sets of wide or narrow bars or spaces, with 2 of the 5 being wide. The pattern can be calculated by considering a “weight” for each position: 1, 2, 4, 7, and 0, with “0” itself being represented by 4 + 7. So, 3 is 1 + 2, or “wwnnn”, while 7 is “nnnww” (7 + 0). More information is available on Wikipedia.
Constant Summary collapse
- PATTERNS =
The patterns for each number and the guard patterns
{ 'start' => 'nnnn', '0' => 'nnwwn', '1' => 'wnnnw', '2' => 'nwnnw', '3' => 'wwnnn', '4' => 'nnwnw', '5' => 'wnwnn', '6' => 'nwwnn', '7' => 'nnnww', '8' => 'wnnwn', '9' => 'nwnwn', 'stop' => 'wnn' }
- WN_RATIO =
Default w/n ratio.
2
- DEFAULT_OPTIONS =
{ :w_character => 'w', :n_character => 'n', :line_character => '1', :space_character => '0', :wn_ratio => WN_RATIO }
Instance Attribute Summary
Attributes inherited from Barcode1D
#check_digit, #encoded_string, #options, #value
Class Method Summary collapse
-
.can_encode?(value) ⇒ Boolean
Returns true if the value can be encoded.
-
.decode(str, options = {}) ⇒ Object
Decode a string in w/n format.
-
.generate_check_digit_for(value) ⇒ Object
Generates check digit given a string to encode.
-
.validate_check_digit_for(value) ⇒ Object
Validates the check digit given a string - assumes check digit is last digit of string.
Instance Method Summary collapse
-
#bars ⇒ Object
Returns 1s and 0s (for “black” and “white”).
-
#initialize(value, options = {}) ⇒ Interleaved2of5
constructor
Create a new Interleaved2of5 object with the given value.
-
#rle ⇒ Object
Returns a run-length-encoded string representation.
-
#width ⇒ Object
Returns the total unit width of the bar code.
-
#wn ⇒ Object
Returns a string of “w” or “n” (“wide” and “narrow”).
Methods inherited from Barcode1D
bar_pair, bars_to_rle, rle_to_bars, rle_to_wn, wn_pair, wn_to_rle
Constructor Details
#initialize(value, options = {}) ⇒ Interleaved2of5
Create a new Interleaved2of5 object with the given value. Options are :line_character, :space_character, :w_character, :n_character, :skip_checksum, and :checksum_included.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 189 def initialize(value, = {}) @options = DEFAULT_OPTIONS.merge() # Can we encode this value? raise UnencodableCharactersError unless self.class.can_encode?(value) if @options[:skip_checksum] @encoded_string = value.to_s @value = value.to_i @check_digit = nil elsif @options[:checksum_included] raise ChecksumError unless self.class.validate_check_digit_for(value) @encoded_string = value.to_s @value = value.to_i / 10 @check_digit = value % 10 else # need to add a checksum @value = value.to_i @check_digit = self.class.generate_check_digit_for(@value) @encoded_string = "#{@value.to_s}#{@check_digit}" end @encoded_string = '0' + @encoded_string if @encoded_string.size.odd? end |
Class Method Details
.can_encode?(value) ⇒ Boolean
Returns true if the value can be encoded.
105 106 107 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 105 def can_encode?(value) value.is_a?(Integer) || value.to_s =~ /^[0-9]+$/ end |
.decode(str, options = {}) ⇒ Object
Decode a string in w/n format. This will return an Interleaved2of5 object.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 131 def decode(str, = {}) if str =~ /[^wn]/ raise UnencodableCharactersError, "Pattern must contain only \"w\" and \"n\"." end if str.reverse =~ /^#{PATTERNS['start']}.*?#{PATTERNS['stop']}$/ str.reverse! end unless str =~ /^#{PATTERNS['start']}(.*?)#{PATTERNS['stop']}$/ raise UnencodableCharactersError, "Start/stop pattern is not detected." end numeric_pattern = $1 unless numeric_pattern.size % 10 == 0 raise UnencodableCharactersError, "Wrong number of bars." end decoded_string = '' numeric_pattern.scan(/.{10}/).each do |chunk| num1 = chunk[0,1] + chunk[2,1] + chunk[4,1] + chunk[6,1] + chunk[8,1] num2 = chunk[1,1] + chunk[3,1] + chunk[5,1] + chunk[7,1] + chunk[9,1] found = false ('0'..'9').each do |digit| if PATTERNS[digit] == num1 decoded_string += digit found = true end end raise UndecodableCharactersError, "Invalid sequence: #{num1}" unless found # nnnnn is a sequence sometimes used in the spaces of the last # digit to indicate there is no last digit. if num2 != 'nnnnn' found = false ('0'..'9').each do |digit| if PATTERNS[digit] == num2 decoded_string += digit found = true end end raise UndecodableCharactersError, "Invalid sequence: #{num2}" unless found end end Interleaved2of5.new(decoded_string.to_i, ) end |
.generate_check_digit_for(value) ⇒ Object
Generates check digit given a string to encode. It assumes there is no check digit on the “value”. Note that if value has an even number of digits, a “0” will be prepended for this operation.
112 113 114 115 116 117 118 119 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 112 def generate_check_digit_for(value) raise UnencodableCharactersError unless self.can_encode?(value) mult = 1 value = value.to_s value = "0#{value}" if value.size.even? value = value.split('').inject(0) { |a,c| mult = 4 - mult ; a + c.to_i * mult } (10 - (value % 10)) % 10 end |
.validate_check_digit_for(value) ⇒ Object
Validates the check digit given a string - assumes check digit is last digit of string.
123 124 125 126 127 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 123 def validate_check_digit_for(value) raise UnencodableCharactersError unless self.can_encode?(value) md = value.to_s.match(/^(\d+)(\d)$/) self.generate_check_digit_for(md[1]) == md[2].to_i end |
Instance Method Details
#bars ⇒ Object
Returns 1s and 0s (for “black” and “white”)
226 227 228 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 226 def @bars ||= self.class.(self.rle, @options) end |
#rle ⇒ Object
Returns a run-length-encoded string representation
221 222 223 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 221 def rle @rle ||= self.class.wn_to_rle(self.wn, @options) end |
#width ⇒ Object
Returns the total unit width of the bar code
231 232 233 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 231 def width @width ||= rle.split('').inject(0) { |a,c| a + c.to_i } end |
#wn ⇒ Object
Returns a string of “w” or “n” (“wide” and “narrow”)
216 217 218 |
# File 'lib/barcode1dtools/interleaved2of5.rb', line 216 def wn @wn ||= wn_str.tr('wn', @options[:w_character].to_s + @options[:n_character].to_s) end |