325 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
| \appendix
 | |
| 
 | |
| \chapter{Python code base display module}
 | |
| \label{app:base_py}
 | |
| 
 | |
| \textbf{\emph{All figures, \LaTeX\  and Python files are available on the dedicated \hreffn{https://github.com/LordBaryhobal/5D\_Heredero\_Louis\_TM2022}{GitHub repository}}}
 | |
| 
 | |
| \vspace{12pt}
 | |
| 
 | |
| This module is used by the other generator scripts to display codes.
 | |
| 
 | |
| \begin{tcolorbox}[breakable,colback=white,title=base.py]
 | |
| \begin{minted}{python}
 | |
| #!/usr/bin/env python
 | |
| # -*- coding: utf-8 -*-
 | |
| """
 | |
| This module provides a base class to display codes and enable saving
 | |
| 
 | |
| (C) 2022 Louis Heredero  louis.heredero@edu.vs.ch
 | |
| """
 | |
| 
 | |
| import pygame
 | |
| 
 | |
| class Base:
 | |
|   def __init__(self, width, height, caption):
 | |
|       pygame.init()
 | |
| 
 | |
|       pygame.display.set_caption(caption)
 | |
|       self.w = pygame.display.set_mode([width, height])
 | |
| 
 | |
|       self.controls([
 | |
|           "CTRL + S: save as",
 | |
|           "ESC: quit"
 | |
|       ])
 | |
| 
 | |
|   def controls(self, controls, margin=2):
 | |
|       longest = max(list(map(len, controls))+[10])
 | |
|       print("┌─" + "─"*(longest+margin) + "─┐")
 | |
| 
 | |
|       _ = "\x1b[1;4mControls:\x1b[0m"
 | |
|       _ += " "*(longest+margin-9)
 | |
|       print(f"│ " + _ + " │")
 | |
|       for c in controls:
 | |
|           print("│ " + " "*margin + c.ljust(longest) + " │")
 | |
|       print("└─" + "─"*(longest+margin) + "─┘")
 | |
| 
 | |
|   def main(self):
 | |
|       pygame.display.flip()
 | |
| 
 | |
|       stop = False
 | |
|       while not stop:
 | |
|           event = pygame.event.wait()
 | |
|           # ESC or close button -> quit
 | |
|           if event.type == pygame.QUIT:
 | |
|               stop = True
 | |
| 
 | |
|           elif event.type == pygame.KEYDOWN:
 | |
|               if event.key == pygame.K_ESCAPE:
 | |
|                   stop = True
 | |
| 
 | |
|               # CTRL+S -> save image
 | |
|               elif event.key == pygame.K_s and \
 | |
|                    event.mod & pygame.KMOD_CTRL:
 | |
|                   self.save()
 | |
| 
 | |
|   def save(self):
 | |
|       path = input("Save as: ")
 | |
|       pygame.image.save(self.w, path)
 | |
| \end{minted}
 | |
| \end{tcolorbox}
 | |
| 
 | |
| \chapter{Code 39 python implementation}
 | |
| \label{app:code39_py}
 | |
| 
 | |
| \begin{tcolorbox}[breakable,colback=white,title=code39.py]
 | |
| \begin{minted}{python}
 | |
| #!/usr/bin/env python
 | |
| # -*- coding: utf-8 -*-
 | |
| """
 | |
| This module can generate Code-39 barcodes
 | |
| 
 | |
| (C) 2022 Louis Heredero  louis.heredero@edu.vs.ch
 | |
| """
 | |
| 
 | |
| import pygame
 | |
| 
 | |
| code39_dict = {
 | |
|     "A": "100001001", "B": "001001001",
 | |
|     "C": "101001000", "D": "000011001",
 | |
|     "E": "100011000", "F": "001011000",
 | |
|     "G": "000001101", "H": "100001100",
 | |
|     "I": "001001100", "J": "000011100",
 | |
|     "K": "100000011", "L": "001000011",
 | |
|     "M": "101000010", "N": "000010011",
 | |
|     "O": "100010010", "P": "001010010",
 | |
|     "Q": "000000111", "R": "100000110",
 | |
|     "S": "001000110", "T": "000010110",
 | |
|     "U": "110000001", "V": "011000001",
 | |
|     "W": "111000000", "X": "010010001",
 | |
|     "Y": "110010000", "Z": "011010000",
 | |
|     "0": "000110100", "1": "100100001",
 | |
|     "2": "001100001", "3": "101100000",
 | |
|     "4": "000110001", "5": "100110000",
 | |
|     "6": "001110000", "7": "000100101",
 | |
|     "8": "100100100", "9": "001100100",
 | |
|     " ": "011000100", "-": "010000101",
 | |
|     "$": "010101000", "%": "000101010",
 | |
|     ".": "110000100", "/": "010100010",
 | |
|     "+": "010001010", "*": "010010100"
 | |
| }
 | |
| 
 | |
| def code39(text):
 | |
|     text = text.upper()
 | |
|     text = list(map(lambda c: code39_dict[c], text))
 | |
|     return "0".join(text)
 | |
| 
 | |
| def draw_barcode(barcode, win):
 | |
|     barcode = list(map(int, barcode))
 | |
|     width = win.get_width()*0.8
 | |
|     height = win.get_height()*0.5
 | |
|     thicks = sum(barcode)
 | |
|     thins = len(barcode)-thicks
 | |
|     bar_w = width/(thicks*2+thins)
 | |
| 
 | |
|     win.fill((255,255,255))
 | |
|     x = win.get_width()*0.1
 | |
|     y = win.get_height()*0.25
 | |
| 
 | |
|     for i, c in enumerate(barcode):
 | |
|         w = 2*bar_w if c else bar_w
 | |
|         if i%2 == 0:
 | |
|             pygame.draw.rect(win, (0,0,0), [x, y, w, height])
 | |
| 
 | |
|         x += w
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     import base
 | |
| 
 | |
|     b = base.Base(800, 500, "Code-39 barcode generator")
 | |
| 
 | |
|     barcode = code39("*CODE-39*")
 | |
|     draw_barcode(barcode, b.w)
 | |
| 
 | |
|     b.main()
 | |
| \end{minted}
 | |
| \end{tcolorbox}
 | |
| 
 | |
| \chapter{EAN python implementation}
 | |
| \label{app:ean_py}
 | |
| 
 | |
| \begin{tcolorbox}[breakable,colback=white,title=ean.py]
 | |
| \begin{minted}{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()
 | |
| \end{minted}
 | |
| \end{tcolorbox}
 | |
| 
 | |
| \chapter{QR-Code tables}
 | |
| \label{app:qr_tabs}
 | |
| 
 | |
| \def\arraystretch{1.2}
 | |
| \begin{table}[H]
 | |
|   \centering
 | |
|   \begin{tabu}{|[2pt]c|c|[2pt]c|c|[2pt]c|c|[2pt]}
 | |
|     \tabucline[2pt]{-}
 | |
|     Index & Char & Index & Char & Index & Char \\
 | |
|     \hline
 | |
|     0 & 0 & 15 & F & 30 & U \\
 | |
|     \hline
 | |
|     1 & 1 & 16 & G & 31 & V \\
 | |
|     \hline
 | |
|     2 & 2 & 17 & H & 32 & W \\
 | |
|     \hline
 | |
|     3 & 3 & 18 & I & 33 & X \\
 | |
|     \hline
 | |
|     4 & 4 & 19 & J & 34 & Y \\
 | |
|     \hline
 | |
|     5 & 5 & 20 & K & 35 & Z \\
 | |
|     \hline
 | |
|     6 & 6 & 21 & L & 36 & \emph{space} \\
 | |
|     \hline
 | |
|     7 & 7 & 22 & M & 37 & \$ \\
 | |
|     \hline
 | |
|     8 & 8 & 23 & N & 38 & \% \\
 | |
|     \hline
 | |
|     9 & 9 & 24 & O & 39 & * \\
 | |
|     \hline
 | |
|     10 & A & 25 & P & 40 & + \\
 | |
|     \hline
 | |
|     11 & B & 26 & Q & 41 & - \\
 | |
|     \hline
 | |
|     12 & C & 27 & R & 42 & . \\
 | |
|     \hline
 | |
|     13 & D & 28 & S & 43 & / \\
 | |
|     \hline
 | |
|     14 & E & 29 & T & 44 & : \\
 | |
|     \tabucline[2pt]{-}
 | |
|   \end{tabu}
 | |
|   \caption{List of alphanumerical characters}
 | |
|   \label{tab:qr_alphanum}
 | |
| \end{table}
 | |
| \def\arraystretch{1}
 | |
| 
 | |
| \input{appendices/qr_versions}
 | |
| 
 | |
| % Rotated headers
 | |
| % https://tex.stackexchange.com/a/98439
 | |
| \input{appendices/error_correction}
 | |
| 
 | |
| \input{appendices/alignment}
 |