116 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| # -*- coding: utf-8 -*-
 | |
| """
 | |
| This module can generate EAN-8 and EAN-13 barcodes
 | |
| 
 | |
| (C) 2022 Louis Heredero  louis.heredero@edu.vs.ch
 | |
| """
 | |
| 
 | |
| import pygame
 | |
| 
 | |
| A = [
 | |
|     0b0001101,
 | |
|     0b0011001,
 | |
|     0b0010011,
 | |
|     0b0111101,
 | |
|     0b0100011,
 | |
|     0b0110001,
 | |
|     0b0101111,
 | |
|     0b0111011,
 | |
|     0b0110111,
 | |
|     0b0001011
 | |
| ]
 | |
| 
 | |
| # XOR 0b1111111
 | |
| C = list(map(lambda a: a^127, A))
 | |
| 
 | |
| # Reverse bit order
 | |
| B = list(map(lambda c: int(f"{c:07b}"[::-1], 2), C))
 | |
| 
 | |
| ean13_patterns = [
 | |
|     "AAAAAA",
 | |
|     "AABABB",
 | |
|     "AABBAB",
 | |
|     "AABBBA",
 | |
|     "ABAABB",
 | |
|     "ABBAAB",
 | |
|     "ABBBAA",
 | |
|     "ABABAB",
 | |
|     "ABABBA",
 | |
|     "ABBABA"
 | |
| ]
 | |
| 
 | |
| def bin_list(n):
 | |
|     return list(map(int, f"{n:07b}"))
 | |
| 
 | |
| def luhn(digits):
 | |
|     checksum = sum([
 | |
|         digits[-i-1]*(3-i%2*2)
 | |
|         for i in range(len(digits))
 | |
|     ])
 | |
|     ctrl_key = 10 - checksum%10
 | |
|     if ctrl_key == 10:
 | |
|         ctrl_key = 0
 | |
| 
 | |
|     return ctrl_key
 | |
| 
 | |
| def ean8(digits):
 | |
|     digits.append(luhn(digits))
 | |
|     elmts = []
 | |
| 
 | |
|     elmts += [1,0,1] #delimiter
 | |
|     for digit in digits[:4]:
 | |
|         elmts += bin_list(A[digit])
 | |
| 
 | |
|     elmts += [0,1,0,1,0] #middle delimiter
 | |
|     for digit in digits[4:]:
 | |
|         elmts += bin_list(C[digit])
 | |
| 
 | |
|     elmts += [1,0,1] #delimiter
 | |
|     return elmts
 | |
| 
 | |
| def ean13(digits):
 | |
|     pattern = ean13_patterns[digits[0]]
 | |
|     digits.append(luhn(digits))
 | |
|     elmts = []
 | |
| 
 | |
|     elmts += [1,0,1] #delimiter
 | |
|     for d in range(1,7):
 | |
|         _ = A if pattern[d-1] == "A" else B
 | |
|         digit = digits[d]
 | |
|         elmts += bin_list(_[digit])
 | |
| 
 | |
|     elmts += [0,1,0,1,0] #middle delimiter
 | |
|     for digit in digits[7:]:
 | |
|         elmts += bin_list(C[digit])
 | |
| 
 | |
|     elmts += [1,0,1] #delimiter
 | |
|     return elmts
 | |
| 
 | |
| def draw_barcode(barcode, win):
 | |
|     width = win.get_width()*0.8
 | |
|     height = win.get_height()*0.5
 | |
|     bar_w = width/len(barcode)
 | |
|     rnd_bar_w = round(bar_w)
 | |
| 
 | |
|     win.fill((255,255,255))
 | |
|     x = win.get_width()*0.1
 | |
|     y = win.get_height()*0.25
 | |
| 
 | |
|     for c in barcode:
 | |
|         if c:
 | |
|             pygame.draw.rect(win, (0,0,0), [x, y, rnd_bar_w, height])
 | |
| 
 | |
|         x += bar_w
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     import base
 | |
|     
 | |
|     b = base.Base(800, 500, "EAN-8 / EAN-13 barcode generator")
 | |
|     
 | |
|     #barcode = ean8([8,4,2,7,3,7,2])
 | |
|     barcode = ean13([9,7,8,2,9,4,0,6,2,1,0,5])
 | |
|     
 | |
|     draw_barcode(barcode, b.w)
 | |
|     
 | |
|     b.main() |