TP – afficheurs d’octets UTF8

Prérequis :

Se souvenir du cours sur l’utf8, comme ici.

NSI première : C’était pour mercredi 1er avril

ISN terminale : c’est le TP du jeudi 2 avril

Réaliser une fonction affiche_octets_utf8 qui … affiche les octets (en binaire) d’un caractère (encodé en utf8) envoyé en paramètre d’entrée (ou en argument si vous préférez).

Le découpage fonctionnel est le suivant :

def un_octet(chaine_de_bits):
    # renvoie par exemple pour l'espace :
    # 00100000
    # pour le A (code 65) :
    # 01000001
def deux_octets(c):
    # renvoie par exemple pour é :
    # 11000011 10101001
def trois_octets(c):
    # renvoie par exemple pour €  :
    # 11100010 10000010 10101100

def quatre_octets(c):
    # attention deux cas ici

def affiche_octets_utf8(caractere):
    # utilise une fonction native de python
    # pour avoir les bits de l'écriture binaire
    # et suivant la longueur ce cette chaîne binaire appelle
    # l'une des quatre fonctions ci-dessus
    # en leur envoyant la chaîne binaire pour qu'elles
    # renvoie les octets

print(affiche_octets_utf8(' '))
print(affiche_octets_utf8('A'))
print(affiche_octets_utf8('é'))
print(affiche_octets_utf8('€'))
print(affiche_octets_utf8(chr(2 ** 15)))
print("C'est le glyphe ou caractère pour un code de 2 ** 15")
print("D'après google translate, voudrait dire 'Yào' soit briller en chinois !")
print("L'afficheur quatre octets est un peu virtuel :")
print("Pas de code unicode à quatre octets à ce jour ...")
print("... compatibles avec Python 3.")
print("Mais, avec la fonction quatre_octets, un code de")

for k in range(17, 21):
    print("2 **", k, "doit afficher", quatre_octets(bin(2 ** k)[2:]))
    print("(" + str(k + 1) + " bits)")

Et ce code doit afficher :

  est codé sur 1 octet (ASCII) : 00100000
A est codé sur 1 octet (ASCII) : 01000001
é est codé sur 2 octets : 11000011 10101001
€ est codé sur 3 octets : 11100010 10000010 10101100
耀 est codé sur 3 octets : 11101000 10000000 10000000
C'est le glyphe ou caractère pour un code de 2 ** 15
D'après google translate, voudrait dire 'Yào' soit briller en chinois !
L'afficheur quatre octets est un peu virtuel :
Pas de code unicode à quatre octets à ce jour ...
... compatibles avec Python 3.
Mais, avec la fonction quatre_octets, un code de
2 ** 17 doit afficher 11110000 10100000 10000000 10000000
(18 bits)
2 ** 18 doit afficher 11110001 10000000 10000000 10000000
(19 bits)
2 ** 19 doit afficher 11110010 10000000 10000000 10000000
(20 bits)
2 ** 20 doit afficher 11110100 10000000 10000000 10000000
(21 bits)
>>>

A finir pour les courageux !

 

J’ai donné ce début de code sur discord

def un_octet(chaine_de_bits):
    '''renvoie par exemple pour l'espace : 00100000
    pour le A (code 65) : 01000001'''
    longueur = len(chaine_de_bits)
    nb_zeros = 8 - longueur
    return nb_zeros * '0' + chaine_de_bits #'00' + '100000'

def deux_octets(c):
    '''renvoie par exemple pour é : 11000011 10101001'''
    deuxieme_octet = '10' + c[-6:]
    premier_octet = '110' + '0' * (5 - len(c[:-6])) + c[:-6]
    return premier_octet + ' ' + deuxieme_octet

def affiche_octets_utf8(caractere):
    # utilise une fonction native de python
    # pour avoir les bits de l'écriture binaire
    code = ord(caractere)
    chaine = bin(code)
    chaine = chaine[2:]
    log2 = len(chaine)

    if log2 > 8:
        return un_octet(chaine)
    elif log2 > 12:
        return deux_octets(chaine)

    # et suivant la longueur ce cette chaîne binaire appelle
    # l'une des quatre fonctions ci-dessus
    # en leur envoyant la chaîne binaire pour qu'elles
    # renvoie les octets

print(affiche_octets_utf8(' ')) # 32 -> 00 100000
print(affiche_octets_utf8('A')) # 65 -> 0 1000001
print(affiche_octets_utf8('é'))

Et ces explications dans le shell

>>> 'é'
'é'
>>> chr(65)
'A'
>>> ord('é')
233
>>> bin(ord('é'))
'0b11101001'
>>> bin(233)
'0b11101001'
>>> hex(233)
'0xe9'
>>> bin(233)
'0b11101001'
>>> bin(ord('é'))
'0b11101001'
>>> bin(ord('é'))[0]
'0'
>>> bin(ord('é'))[1]
'b'
>>> bin(ord('é'))[0:2]
'0b'
>>> bin(ord('é'))[2:]
'11101001'
>>> bin(ord('A'))[2:]
'1000001'
>>> bin(ord(' '))[2:]
'100000'
>>> '0' * 2 + bin(ord(' '))[2:]
'00100000'
>>> 2 ** 15
32768
>>> 2 ** 17
131072
>>> 2 ** 16
65536
>>> print(chr(2 ** 15))
耀
>>> chr(108)
'l'
>>> bin(ord('€'))[2:]
'10000010101100'
>>> len(bin(ord('€'))[2:])
14
>>>

4 réflexions au sujet de « TP – afficheurs d’octets UTF8 »

  1. Bonsoir,

    J’ai des difficultés avec la fonction quatre_octets et je ne trouve pas d’exemple de caractères qui sont justement sur 4 octets (pour les utiliser comme exemples). Et puis pourquoi deux possibilités ? Je suis un peu perdue…

    Merci de votre aide !

    • Bonjour !
      Et bien moi non plus, je ne trouve pas d’exemples à 4 octets, et pour cause :
      -> Il y aurait pour l’instant 110 000 valeurs de point de code environ attribuées à ce jour, or 2^{17} = 131072 > 110 000, source ici dans la doc python.
      -> Même à 2^{16}, Idle me « jette » avec

      print(affiche_octets_utf8(chr(2 ** 16)))
      UnicodeEncodeError: 
      'UCS-2' codec can't encode character 
      '\U00010000' in position 0: 
      Non-BMP character not supported in Tk

      C’est donc purement théorique pour quatre_octets(c).

      Je répondais hier à Valentin :
      « en fait dès qu’on dépasse trois octets, ça veut dire que ça ne tient plus donc qu’on dépasse 4 + 6 + 6 = 16 bits
      -> avec 17 ou 18 bits, il n’y aura que des zéros dans le premier des quatre octets (premier cas)
      -> avec 19, 20 ou 21 bits (le max), on remplit le premier des quatre octets après le 11110 aussi ! (deuxième cas) »

      Bon courage !

N'hésitez-pas à poser une question, ou faire avancer le schmilblick

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.