qrcode_formats.py

Created by nicolas-patrois

Created on February 02, 2020

2.92 KB

Créer ou décoder des messages codés selon les formats ASCII et alphanumériques des codes QR, écrits en nombres ou en binaire.


#!/usr/bin/python3

"""
Voici une petite collection d'outils destinee
a etre utilises par le professeur
pour creer facilement des messages codes ou pour les decoder.

Voici les huit conversions possibles

nA numerique->ASCII
An ASCII->numerique

na numerique->alphanumerique
an alphanumerique->numerique

bn binaire->numerique
nb numerique->binaire

bA binaire->numerique->ASCII
Ab ASCII->numerique->binaire

ba binaire->numerique->alphanumerique
ab alphanumerique->numerique->binaire
"""

alphanum="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"

def nA(liste):
  """
  Convertit des nombres en ASCII
  Attention, les activites n'utilisent que l’ASCII 7 bits (sans les accents)
  """
  chaine=""
  for n in liste:
    if not 32<=int(n)<127:
      raise ValueError("Uniquement de l'ASCII 7 bits.")
    chaine+=chr(int(n))
  return chaine

def An(s):
  """
  Convertit de l'ASCII en nombres
  Attention, les activites n’utilisent que l'ASCII 7 bits (sans les accents)
  """
  liste=[]
  for c in " ".join(s):
    if not 32<=ord(c)<127:
      raise ValueError("Uniquement de l’ASCII 7 bits.")
    liste.append(str(ord(c)))
  return " ".join(liste)

def na(liste):
  """
  Convertit des nombres vers le format alphanumerique
  """
  chaine=""
  for c in liste:
    if not 0<=int(c)<2025:
      raise ValueError("Les nombres sont entre 0 et 2024.")
    q,r=divmod(int(c),45)
    if c[0]=="0":
      chaine+=alphanum[r]
    else:
      chaine+=alphanum[q]+alphanum[r]
  return chaine

def an(s):
  """
  Convertit le format alphanumerique en nombres
  """
  liste=[]
  message=s
  if not set(message) <= set(alphanum):
    raise ValueError("Les caracteres autorises sont "+alphanum)
  n,r=divmod(len(message),2)
  aim=lambda j:alphanum.index(message[j])
  for i in range(n):
    liste.append(str(45*aim(2*i)+aim(2*i+1)))
  if r==1:
    liste.append("0%d"%aim(-1))
  return " ".join(liste)

def bn(s):
  """
  Convertit du binaire en nombres a dix chiffres
  Par exemple, 011101 renvoie 29
  """
  return " ".join(str(int(c,2)) for c in s)

def nb(n):
  """
  Convertit un nombre en sa représentation binaire
  Par exemple, 29 renvoie 11101
  """
  return " ".join(bin(int(c))[2:] for c in n)

def bA(n):
  """
  Convertit une suite de binaires en ASCII
  """
  return nA(bn(n).split())

def Ab(s):
  """
  Convertit de lAASCII en binaire
  """
  l=nb(An(s).split()).split()
  return " ".join("0"*(8-len(c))+c for c in l)

def ba(n):
  """
  Convertit une suite de binaires en alphanumerique
  """
  l=bn(n).split()
  if len(n[-1])<7:
    l[-1]="0"+l[-1]
  return na(l)

def ab(s):
  """
  Convertit de l'alphanumérique en binaire
  """
  l=an(s).split()
  L=nb(l).split()
  return " ".join("0"*(11-5*(l[i][0]=="0")-len(c))+c for i,c in enumerate(L))

commandes=[nA,An,na,an,bn,nb,bA,Ab,ba,ab]

def outil(*l):
  """
  outil(ab,"BONJOUR")
  01000000111 10000011110 10001010110 011011
  """
  if len(l)<2:
    raise IndexError("Il faut deux arguments")
  print(l[0](l[1:]))