Skip to content

Instantly share code, notes, and snippets.

@iljamaas
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iljamaas/9741965d373cb2ed94ea to your computer and use it in GitHub Desktop.
Save iljamaas/9741965d373cb2ed94ea to your computer and use it in GitHub Desktop.
Simple code to create a very clean SVG EAN13 code.
class Ean13BarcodeException(Exception):
pass
class Ean13Barcode(object):
"""Generate a SVG for a given EAN13 code with a specified width and height"""
def __init__(self, width, height, colorstring='rgb(0,0,0)'):
self.width = width
self.height = height
self.colorstring = colorstring
self.codes = {
'A': ['0001101', '0011001', '0010011', '0111101', '0100011',
'0110001', '0101111', '0111011', '0110111', '0001011'],
'B': ['0100111', '0110011', '0011011', '0100001', '0011101',
'0111001', '0000101', '0010001', '0001001', '0010111'],
'C': ['1110010', '1100110', '1101100', '1000010', '1011100',
'1001110', '1010000', '1000100', '1001000', '1110100'],
}
self.parities = [
('A', 'A', 'A', 'A', 'A', 'A'),
('A', 'A', 'B', 'A', 'B', 'B'),
('A', 'A', 'B', 'B', 'A', 'B'),
('A', 'A', 'B', 'B', 'B', 'A'),
('A', 'B', 'A', 'A', 'B', 'B'),
('A', 'B', 'B', 'A', 'A', 'B'),
('A', 'B', 'B', 'B', 'A', 'A'),
('A', 'B', 'A', 'B', 'A', 'B'),
('A', 'B', 'A', 'B', 'B', 'A'),
('A', 'B', 'B', 'A', 'B', 'A')
]
def generate(self, barcode, generate_controldigit=True):
"""the controldigit is the 13th digit which is a checksum.
Most likely you want this code to calculate it for you"""
barcode = str(barcode)
# Some sanity first.
if generate_controldigit and len(barcode) > 12:
raise Ean13BarcodeException('Length already 13 digits, cannot add controldigit')
if generate_controldigit and len(barcode) <= 12:
barcode = barcode.rjust(12, '0')
barcode = "%s%s" % (barcode, self.create_controldigit(barcode))
elif len(barcode) < 13:
barcode = barcode.rjust(13, '0')
if not generate_controldigit and not self.check_controldigit(barcode):
raise Ean13BarcodeException('Control digit is not correct! (13th digits)')
# Generate 'bit'-range
code = ['101']
p = self.parities[int(barcode[0])]
for i in range(1, 7):
code.append(self.codes[p[i-1]][int(barcode[i])])
code.append('01010')
for i in range(7, 13):
code.append(self.codes['C'][int(barcode[i])])
code.append('101')
# Create the svg
return self._svg(self._stack(''.join(code)))
def _svg(self, stack):
x = 0
bars = []
sbw = self.width / sum(stack)
for i, e in enumerate(stack):
w = e * sbw
if not i % 2: # only 'odd' ones should be painted
bars.append('<rect width="%s" height="%s" x="%s" y="0" style="fill:%s;"/>' %
(w, self.height, x, self.colorstring))
x += w
return '<svg width="%s" height="%s">%s</svg>' % (self.width, self.height, "\n".join(bars))
@staticmethod
def _stack(bitseries):
currentbit = '1'
rv = [0]
for i in bitseries:
if i == currentbit:
rv[len(rv)-1] += 1
else:
currentbit = i
rv.append(1)
return rv
@classmethod
def check_controldigit(cls, code):
assert(len(code) == 13)
c = code[0:12]
r = int(code[12:13])
return r == cls.create_controldigit(c)
@classmethod
def create_controldigit(cls, code):
assert(len(code) == 12)
s = 0
for i in range(1, 12, 2):
s += 3 * int(code[i])
for i in range(0, 11, 2):
s += int(code[i])
r = s % 10
if r > 0:
r = 10 - r
return r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment