Class: Barcode1DTools::EAN8
- Defined in:
- lib/barcode1dtools/ean8.rb
Overview
The value encoded is a 7-digit number, 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.
num = ‘96385074’ bc = Barcode1DTools::EAN8.new(num) pattern = bc.bars rle_pattern = bc.rle width = bc.width check_digit = Barcode1DTools::EAN83.generate_check_digit_for(num)
The object created is immutable.
There are two formats for the returned pattern (wn format is not available):
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. Each character
in the string renders to a single unit width.
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.
The “width” method will tell you the total end-to-end width, in units, of the entire barcode.
Unlike some of the other barcodes, e.g. Code 3 of 9, there is no “wnstr” for EAN & UPC style barcodes because the bars and spaces are variable width from 1 to 4 units.
A EAN-8 barcode has 3 elements:
-
A 2 or 3 digit “number system” designation
-
A 4 or 5 digit manufacturer’s code
-
A single digit checksum
Note than an EAN-8 is not analogous to a UPC-E. In particular, there is no way to create an EAN-13 from and EAN-8 and vice versa. The numbers are assigned within each system by a central authority.
The bar patterns are the same as EAN-13, with nothing encoded in the parity. All bars on the left use the “odd” parity set.
RENDERING
When rendered, two sets of four digits are shown at the bottom of the code, aligned with the bottom of the code, and with the middle guard pattern bars extending down between them. A supplemental 2 or 5 may be used.
Constant Summary collapse
- LEFT_PATTERNS =
patterns to create the bar codes:
EAN13::LEFT_PATTERNS
- LEFT_PATTERNS_RLE =
EAN13::LEFT_PATTERNS_RLE
- RIGHT_PATTERNS =
EAN13::RIGHT_PATTERNS
- RIGHT_PATTERNS_RLE =
EAN13::RIGHT_PATTERNS_RLE
- SIDE_GUARD_PATTERN =
EAN13::SIDE_GUARD_PATTERN
- MIDDLE_GUARD_PATTERN =
EAN13::MIDDLE_GUARD_PATTERN
- SIDE_GUARD_PATTERN_RLE =
EAN13::SIDE_GUARD_PATTERN_RLE
- MIDDLE_GUARD_PATTERN_RLE =
EAN13::MIDDLE_GUARD_PATTERN_RLE
- DEFAULT_OPTIONS =
{ :line_character => '1', :space_character => '0' }
Instance Attribute Summary collapse
-
#number_system ⇒ Object
readonly
Specific for EAN.
-
#product_code ⇒ Object
readonly
Returns the value of attribute product_code.
Attributes inherited from Barcode1D
#check_digit, #encoded_string, #options, #value
Class Method Summary collapse
-
.can_encode?(value, options = nil) ⇒ Boolean
returns true or false - must be 7-8 digits.
-
.decode(str) ⇒ Object
Decode a string representing an rle or bar pattern EAN-13.
-
.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 = {}) ⇒ EAN8
constructor
Options are :line_character, :space_character, and :checksum_included.
-
#rle ⇒ Object
returns a run-length-encoded string representation.
-
#width ⇒ Object
returns the total unit width of the bar code.
-
#wn ⇒ Object
not usable with EAN codes.
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 = {}) ⇒ EAN8
Options are :line_character, :space_character, and :checksum_included.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/barcode1dtools/ean8.rb', line 197 def initialize(value, = {}) @options = DEFAULT_OPTIONS.merge() # Can we encode this value? raise UnencodableCharactersError unless self.class.can_encode?(value, @options) if @options[:checksum_included] @encoded_string = sprintf('%08d', value.to_i) raise ChecksumError unless self.class.validate_check_digit_for(@encoded_string) md = @encoded_string.match(/^(\d+?)(\d)$/) @value, @check_digit = md[1], md[2].to_i else # need to add a checksum @value = sprintf('%07d', value.to_i) @check_digit = self.class.generate_check_digit_for(@value) @encoded_string = "#{@value}#{@check_digit}" end md = @value.match(/^(\d{3})(\d{4})/) @number_system, @product_code = md[1], md[2] end |
Instance Attribute Details
#number_system ⇒ Object (readonly)
Specific for EAN
86 87 88 |
# File 'lib/barcode1dtools/ean8.rb', line 86 def number_system @number_system end |
#product_code ⇒ Object (readonly)
Returns the value of attribute product_code.
87 88 89 |
# File 'lib/barcode1dtools/ean8.rb', line 87 def product_code @product_code end |
Class Method Details
.can_encode?(value, options = nil) ⇒ Boolean
returns true or false - must be 7-8 digits
91 92 93 94 95 96 97 98 99 |
# File 'lib/barcode1dtools/ean8.rb', line 91 def can_encode?(value, = nil) if ! value.to_s =~ /^\d{7,8}$/ elsif ([:checksum_included]) value.to_s =~ /^\d{8}$/ else value.to_s =~ /^\d{7}$/ end end |
.decode(str) ⇒ Object
Decode a string representing an rle or bar pattern EAN-13. Note that the string might be backward or forward. This will return an EAN8 object.
121 122 123 124 125 126 127 128 129 130 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 184 185 186 187 188 189 190 191 192 |
# File 'lib/barcode1dtools/ean8.rb', line 121 def decode(str) if str.length == 67 # bar pattern str = (str) elsif str.length == 43 # rle else raise UnencodableCharactersError, "Pattern must be 67 unit bar pattern or 43 character rle." end # Check the guard patterns unless str[0..2] == SIDE_GUARD_PATTERN_RLE && str[40..42] == SIDE_GUARD_PATTERN_RLE && str[19..23] == MIDDLE_GUARD_PATTERN_RLE raise UnencodableCharactersError, "Missing or incorrect guard patterns" end # Now I have an rle pattern, simply need to decode # according to the LEFT_PATTERNS_RLE, keeping track # of the parity for each position. # Set up the decoder left_parity_sequence = '' left_digits = '' right_parity_sequence = '' right_digits = '' left_initial_offset = SIDE_GUARD_PATTERN_RLE.length right_initial_offset = SIDE_GUARD_PATTERN_RLE.length + (4*4) + MIDDLE_GUARD_PATTERN_RLE.length # Decode the left side (0..3).each do |left_offset| found = false digit_rle = str[(left_initial_offset + left_offset*4),4] ['o','e'].each do |parity| ('0'..'9').each do |digit| if LEFT_PATTERNS_RLE[digit][parity] == digit_rle left_parity_sequence += parity left_digits += digit found = true break end end end raise UndecodableCharactersError, "Invalid sequence: #{digit_rle}" unless found end # Decode the right side (0..3).each do |right_offset| found = false digit_rle = str[(right_initial_offset + right_offset*4),4] ['o','e'].each do |parity| ('0'..'9').each do |digit| if LEFT_PATTERNS_RLE[digit][parity] == digit_rle right_parity_sequence += parity right_digits += digit found = true break end end end raise UndecodableCharactersError, "Invalid sequence: #{digit_rle}" unless found end # If left parity sequence is 'eeee', the string is reversed if left_parity_sequence == 'eeee' left_digits, right_digits, left_parity_sequence = right_digits.reverse, left_digits.reverse, right_parity_sequence.reverse.tr('eo','oe') end # Debugging #puts "Left digits: #{left_digits} Left parity: #{left_parity_sequence}" #puts "Right digits: #{right_digits} Right parity: #{right_parity_sequence}" EAN8.new(left_digits + right_digits, :checksum_included => true) 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”.
103 104 105 106 107 108 |
# File 'lib/barcode1dtools/ean8.rb', line 103 def generate_check_digit_for(value) raise UnencodableCharactersError unless self.can_encode?(value, :checksum_included => false) mult = 1 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.
112 113 114 115 116 |
# File 'lib/barcode1dtools/ean8.rb', line 112 def validate_check_digit_for(value) raise UnencodableCharactersError unless self.can_encode?(value, :checksum_included => true) md = value.match(/^(\d{7})(\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”)
236 237 238 |
# File 'lib/barcode1dtools/ean8.rb', line 236 def @bars ||= self.class.(self.rle, @options) end |
#rle ⇒ Object
returns a run-length-encoded string representation
226 227 228 229 230 231 232 233 |
# File 'lib/barcode1dtools/ean8.rb', line 226 def rle if @rle @rle else md = @encoded_string.match(/^(\d{4})(\d{4})/) @rle = gen_rle(md[1], md[2]) end end |
#width ⇒ Object
returns the total unit width of the bar code
241 242 243 |
# File 'lib/barcode1dtools/ean8.rb', line 241 def width @width ||= rle.split('').inject(0) { |a,c| a + c.to_i } end |
#wn ⇒ Object
not usable with EAN codes
221 222 223 |
# File 'lib/barcode1dtools/ean8.rb', line 221 def wn raise NotImplementedError end |