Hors programme. UTF-8 code un point de code compris entre U+0080 et…
Exercice supplémentaire · niveau 2 · NSI (première), chapitre 2 — Flottants, booléens et textes · Unicode dans le détail
Énoncé
Hors programme. UTF-8 code un point de code compris entre U+0080 et U+07FF sur deux octets, de la forme 110xxxxx 10xxxxxx où les reçoivent les bits du point de code. Le vérifier à la main pour (U+03C0), puis écrire la fonction qui le calcule.
Corrigé
À la main. s'écrit sur bits . On le coupe en : 01111 et 000000. On préfixe : et . Donc s'écrit CF 80 en UTF-8.
def utf8_deux_octets(pc):
"""Encode a la main un point de code sur deux octets.
Precondition : 0x80 <= pc <= 0x7FF. On place les 5 bits de poids
fort derriere le prefixe 110, les 6 suivants derriere 10.
"""
assert 0x80 <= pc <= 0x7FF, "hors du domaine a deux octets"
o1 = 0b11000000 | (pc >> 6)
o2 = 0b10000000 | (pc & 0b111111)
return bytes([o1, o2])
>>> utf8_deux_octets(0x03C0)
b'\xcf\x80'
>>> chr(0x03C0).encode("utf-8")
b'\xcf\x80'
>>> utf8_deux_octets(0x00E9), "é".encode("utf-8")
(b'\xc3\xa9', b'\xc3\xa9')
Pourquoi ces préfixes. Ils rendent l'encodage auto-synchronisant : un octet commençant par est un caractère ASCII, un octet commençant par ouvre une séquence, un octet commençant par la continue. En tombant au hasard au milieu d'un fichier, on retrouve la frontière du caractère suivant en reculant de quelques octets — impossible avec un encodage sans marqueur. C'est aussi ce qui fait échouer proprement le décodage d'octets latin-1 lus comme de l'UTF-8.
Contrôle : les deux octets produits coïncident avec ceux de Python. Piège : oublier le & 0b111111 sur le second octet — les bits de poids fort écraseraient alors le préfixe 10, et le résultat ne serait plus de l'UTF-8 valide.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.