Écrire une fonction tableAscii qui affiche la table des caratères ASCII,
sous la forme code - caractère - hexadécimal ; exemple : 65 - A - 0x41.
Cette fonction prend en paramètre le code du premier et du dernier caractère
à afficher (par défaut, respectivement 32 et 126).
Écrire une fonction convertirEnMinuscule qui prend en paramètres un texte
et le renvoie avec les majuscules converties en minuscules. Ne pas utiliser
la fonction lower (l’objectif est de la reprogrammer). Ne pas traiter les
accents. Algorithme :
pour chaque caractère du texte
utiliser la fonction ord() pour obtenir son code ASCII
si le code ASCII est compris entre 65 ("A") et 90 ("Z"), alors
ajouter 32 (0x20) au code (65 + 32 = 97, code ASCII de "a")
finsi
utiliser la fonction chr() pour obtenir le caractère en minuscules
concaténer le caractère au résultat
finpour
Compléter le programme qui détecte l’encodage d’un fichier texte écrit en anglais ou en français ; ce programme prend en argument le chemin vers le fichier à analyser :
import sys
import os
def detect_byte_encoding(byte: int, prev: int) -> str:
""" Renvoie l'encodage d'un caractère pour un texte en anglais ou français.
@param byte la valeur numérique du caractère (65 pour 'A' par exemple)
@param prev la valeur numérique du caractère précédent (nécessaire pour UTF-8)
@return l'encodage: 'ASCII', 'UTF-8' ou 'ISO-8859-15'
Limite: ne traite pas '€' (0xA4 - 0xE282AC), ni 'œ' (0x9C - 0xC593)
>>> detect_byte_encoding(65, 0)
'ASCII'
>>> detect_byte_encoding(0xE9, 32)
'ISO-8859-15'
>>> detect_byte_encoding(0xA9, 0xC3)
'UTF-8'
"""
enc = "ASCII"
if byte > 127:
if prev == 0xC3:
enc = "UTF-8"
elif byte != 0xC3:
enc = "ISO-8859-15"
return enc
def detect_file_encoding(filename: str) -> str:
""" Analyse un fichier texte en anglais ou français pour déterminer son encodage.
@param filename le chemin vers le fichier à analyser
@return l'encodage: 'ASCII', 'UTF-8' ou 'ISO-8859-15'
Limite: ne traite pas '€' (0xA4 - 0xE282AC), ni 'œ' (0x9C - 0xC593)
"""
with open(sys.argv[1], "rb") as f:
byte = f.read(1)
enc = "ASCII"
prev = 0
while byte and enc == "ASCII": #arrêt dés le premier caractère non ASCII
enc = A_COMPLETER (détecter l'encodate)
prev = byte[0]
A_COMPLETER (lire l'octet suivant)
return enc
if __name__ == "__main__":
import doctest; doctest.testmod()
if A_COMPLETER != 2:
print("error: bad arguments count")
print("usage (detection): " + sys.argv[0] + " filename")
sys.exit(1)
if A_COMPLETER:
print("error: no such file + '" + sys.argv[1] + "'")
sys.exit(1)
enc = detect_file_encoding(sys.argv[1])
Compléter le programme précédent pour lui adjoindre deux fonctions de conversions : UTF-8 → ISO-8859-15 et l’inverse :
def convert_utf_to_iso(src_filename: str, dst_filename):
""" Convertit un fichier texte anglais ou français encodé en UTF-8 en ISO-8859-15.
@param src_filename le chemin vers le fichier UTF-8 à convertir
@param dst_filename le chemin vers le fichier ISO-8859-15 généré
Attention: dst_filename est écrasé si déjà existant
"""
with open(src_filename, "rb") as src, open(dst_filename, "wb") as dst:
while byte := src.read(1):
if byte[0] == 0xC3:
byte = bytes([src.read(1)[0] + A_COMPLETER (0xE0 - 0xA0)])
elif byte[0] == 0xC5:
byte = src.read(1)[0]
byte = bytes([0x9C if byte == 0x93 else 0x9A])
elif byte[0] == 0xE2:
byte = src.read(2)
byte = bytes([0xA4])
dst.write(byte)
def convert_iso_to_utf(src_filename: str, dst_filename):
""" Convertit un fichier texte anglais ou français encodé en ISO-8859-15 en UTF-8.
@param src_filename le chemin vers le fichier ISO-8859-15 à convertir
@param dst_filename le chemin vers le fichier UTF-8 généré
Attention: dst_filename est écrasé si déjà existant
"""
with open(src_filename, "rb") as src, open(dst_filename, "wb") as dst:
while byte := src.read(1):
if byte[0] >= 0xE0 and byte[0] <= 0xFC:
byte = bytes([0xC3, byte[0] - A_COMPLETER (0xE0 - 0xA0)])
elif byte[0] == 0x9C:
byte = bytes([0xC5, 0x93])
elif byte[0] == 0x9A:
byte = bytes([0xC5, 0x92])
elif byte[0] == 0xA4:
byte = bytes([0xE2, 0x82, 0xAC])
dst.write(byte)
Adapter le programme principal pour qu’il réagisse différement en fonction du nombre d’arguments de la ligne de commande :
- un seul argument (un nom de fichier) : détection de l’encodage du fichier
- deux arguments (deux noms de fichiers : conversion du fichier en UTF-8 si l’encodage d’origine est ISO-8859-15 et inversement.
Remarque : la commande iconv effectue ces opérations de conversion.
Compléter le programme qui imite le fonctionnement de la commande hexdump -C fichier,
c’est-à-dire affiche le contenu hexadécimal d’un fichier passé en argument :
import sys
import os.path
def hexdump(filename: str):
file = open(filename, "rb")
byte = file.read(1)
cpt = 0; text = ""
offset = 0
print(format(offset, '08x'), end= " ")
while byte: #lire le contenu du fichier octet par octet:
hexa = format(byte[0], '02x')
if byte[0] >= 32 and byte[0] < 128: #si le caractère est imprimable
char = byte.decode()
else:
char = A_COMPLETER
cpt += 1; text += char #le texte doit être affiché en fin de ligne
print(" " + hexa, end="")
if cpt == A_COMPLETER: #fin de ligne (16 octets)
print(" |" + text + "|")
A_COMPLETER (réinitialisation de cpt et de text)
offset += A_COMPLETER
A_COMPLETER (afficher le nouveau début de ligne — l'offset)
A_COMPLETER (lire l'octet suivant)
if len(text) != 0: #la dernière ligne peut-être incomplète
print(" " * (16 - len(text)) + " |" + text + " " * (16 - len(text)) + "|")
file.close()
if __name__ == "__main__":
if len(sys.argv) < 2:
print("error: missing filename")
sys.exit(1)
filename = sys.argv[1]
if not os.path.isfile(filename):
print("error: " + filename + " is not a file")
sys.exit(2)
hexdump(filename)