Skip to content

Instantly share code, notes, and snippets.

@alexpirine
Last active December 28, 2015 09:19
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 alexpirine/7477779 to your computer and use it in GitHub Desktop.
Save alexpirine/7477779 to your computer and use it in GitHub Desktop.
Produces SVG containing a Code 128 barcode
modes = {
'A': (
' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-',
'.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
'<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '\x00', '\x01', '\x02',
'\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B',
'\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12', '\x13', '\x14',
'\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D',
'\x1E', '\x1F', 'FNC3', 'FNC2', 'SHIFT', 'CODE C', 'CODE B', 'FNC4',
'FNC1', 'START A', 'START B', 'START C', 'STOP',
),
'B': (
' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-',
'.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
'<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '' , 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\x7F', 'FNC3',
'FNC2', 'SHIFT', 'CODE C', 'FNC4', 'CODE A', 'FNC1', 'START A',
'START B', 'START C', 'STOP',
),
'C': (
'00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11',
'12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23',
'24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35',
'36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47',
'48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59',
'60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71',
'72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83',
'84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95',
'96', '97', '98', '99', 'CODE B', 'CODE A', 'FNC1', 'START A',
'START B', 'START C', 'STOP',
),
}
codes = (
0x11492, 0x12452, 0x12491, 0xa293, 0xa2d2, 0xb292, 0xa48b, 0xa4ca, 0xb48a,
0x1228b, 0x122ca, 0x1328a, 0x949a, 0xa45a, 0xa499, 0x9692, 0xa652, 0xa691,
0x12689, 0x1225a, 0x12299, 0x1168a, 0x1264a, 0x19459, 0x19292, 0x1a252,
0x1a291, 0x1948a, 0x1a44a, 0x1a489, 0x11453, 0x114d1, 0x13451, 0x92d3,
0xb253, 0xb2d1, 0x94cb, 0xb44b, 0xb4c9, 0x112cb, 0x1324b, 0x132c9, 0x945b,
0x94d9, 0xb459, 0x9653, 0x96d1, 0xb651, 0x19651, 0x112d9, 0x13259, 0x1164b,
0x116c9, 0x11659, 0x19253, 0x192d1, 0x1b251, 0x1944b, 0x194c9, 0x1b449,
0x19849, 0x12309, 0x23249, 0x9294, 0x9312, 0xa254, 0xa311, 0xc252, 0xc291,
0x948c, 0x950a, 0xa44c, 0xa509, 0xc44a, 0xc489, 0x14289, 0x1224c, 0x21649,
0x1424a, 0xb849, 0x92a2, 0xa262, 0xa2a1, 0x988a, 0xa84a, 0xa889, 0x2128a,
0x2224a, 0x22289, 0x11461, 0x11851, 0x21451, 0x9263, 0x92e1, 0xb261,
0x984b, 0x98c9, 0x2124b, 0x212c9, 0x9661, 0x9859, 0x19261, 0x21259,
0x1130a, 0x1128c, 0x1129a, 0x4d9251,
)
def encodeData(mode, data, prev_mode = None):
if not prev_mode:
code = [modes[mode].index('START %s' % mode)]
elif prev_mode != mode:
code = [modes[prev_mode].index('CODE %s' % mode)]
if mode == 'C':
string, data = data, []
for i in range(0,len(string),2):
data.append(string[i] + string[i + 1])
for c in data:
code.append(modes[mode].index(c))
return code
def genCRC(code):
crc = code[0]
pos = 1
for n in code[1:]:
crc += pos * n
pos += 1
return crc % 103
def decodeBars(code):
value = codes[code]
bars = []
while value:
length = value % 8
value /= 8
bars.insert(0, length)
return bars
def code2bars(code):
bars = []
for n in code:
bars += decodeBars(n)
return bars
def bars2svg(bars, width = '0.45', height = '10'):
from decimal import getcontext, Decimal
getcontext().prec = 5
width = Decimal(width)
height = Decimal(height)
xml = ''
x = Decimal(0)
c = True
for length in bars:
length *= width
xml += '<rect x="%(x).2fmm" y="0" width="%(w).2fmm" height="%(h).2fmm" fill="%(color)s" />' % {
'x': x,
'w': length,
'h': height,
'color': 'black' if c else 'white'
}
x += Decimal(length)
c = not c
xmlns = 'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"'
xml = '<svg version="1.1" %(xmlns)s width="%(w).2fmm" height="%(h).2fmm">%(xml)s</svg>' % {
'xml': xml,
'xmlns': xmlns,
'w': x,
'h': height,
}
return (xml, x, height)
# ex: 2K00291723916
def genLaposteFranceSVG(number):
code = encodeData('B', number[:3]) + encodeData('C', number[3:], 'B')
code.append(genCRC(code))
code.append(modes['C'].index('STOP'))
return bars2svg(code2bars(code))
# ex: LE011587423FR
def genLaposteInternationalSVG(number):
code = encodeData('B', number[:3]) + encodeData('C', number[3:11], 'B') + encodeData('B', number[11:], 'C')
code.append(genCRC(code))
code.append(modes['C'].index('STOP'))
return bars2svg(code2bars(code), width = '0.40', height = '8')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment