06 - Textes
Introduction
Un texte se compose de mots, eux-mêmes composés de caractères qui en constituent la « particule élémentaire ». Ce sont donc les caractères que l’ordinateur doit savoir représenter pour retranscrire un texte : à chaque caractère, on associe un nombre, selon une convention appelée encodage.
Ce chapitre décrit les principaux encodages, du code ASCII à Unicode et UTF-8, explique comment un texte encodé avec l’un est mal lu avec l’autre, et montre comment Python passe des caractères aux nombres. Il se termine par la distinction entre texte simple et texte enrichi.
La représentation des textes simples
Pour représenter des caractères (lettres minuscules et majuscules, chiffres, signes de ponctuation, symboles mathématiques), le principe consiste à attribuer un nombre à chacun d’entre eux. Pour cela un code est utilisé.
Le code ASCII
Le code le plus connu (historique), est le code ASCII (American Standard Code for Information Interchange) conçu à l’origine pour des textes écrits en anglais. Ce code attribue par exemple le nombre 65 à la lettre « A » (41 en hexadécimal, 01000001 en binaire), le nombre 66 à la lettre « B », le nombre 97 à la lettre « a » et le nombre 98 à la lettre « b ». Il permet de représenter 95 caractères : les 26 lettres minuscules, les 26 lettres majuscules, les 10 chiffres, les 32 symboles de ponctuation et 1 signe d’espace. Il permet également de représenter 33 autres symboles de mise en page (retour chariot, saut de page, etc.).
Le code ASCII représente donc \(95 + 33 = 128 = 2^{7}\) caractères. Un codage en 7 bits devrait théoriquement suffire ; en réalité, chacun des nombres utilisés dans le code ASCII est codé en 8 bits (1 octet), le premier bit étant toujours zéro.

Méthode pour trouver la représentation en ASCII binaire d’un texte : en utilisant une table, on cherche le code ASCII de chaque caractère puis on traduit chacun des nombres obtenus en représentation binaire.
Méthode pour décoder un texte représenté en ASCII binaire : on découpe la suite de bits en octets, on traduit chaque octet en décimal puis on cherche le caractère correspondant dans une table ASCII.
Exercice 1. Trouver le texte représenté en ASCII binaire par la suite de bits suivante : 01001010 00100111 01100001 01100100 01101111 01110010 01100101 00100000 01101100 00100111 01101001 01101110 01100110 01101111 01110010 01101101 01100001 01110100 01101001 01110001 01110101 01100101 00100000 00100001
Exercice 2. Trouver le texte représenté en ASCII hexadécimal par : 4a 27 61 76 61 6e 63 65 20 64 61 6e 73 20 6d 6f 6e 20 70 72 6f 6a 65 74 20 64 65 20 4e 53 49 2e
Exercice 3. Coder la phrase en ASCII hexadécimal « Un âne est passé par là » (sans guillemets). Remarque ?
Le code ASCII étendu
Certains constructeurs, comme IBM suivi de tous les fabricants, ont enrichi ce code ASCII en utilisant le \(8^{e}\) bit, ce qui double le nombre de caractères représentables (256). On y ajouta les caractères accentués, des symboles mathématiques et certains caractères semi-graphiques qui permettent de réaliser de petits dessins géométriques.
Le code ASCII 8 bits existe en deux variantes :
- le jeu de caractères IBM PC : c’est le jeu de caractères standard du DOS ;
- le jeu de caractères ISO-ANSI : jeu de caractères international utilisé dans Windows. Par exemple en Europe occidentale, c’est le code ISO-8859-1 (appelé aussi Latin-1, 191 caractères) qui est utilisé. D’autres variantes couvrent d’autres régions : ISO-8859-2 (Latin-2) pour l’Europe centrale, ou ISO-8859-15 (Latin-9), qui ajoute le symbole de l’euro à Latin-1.
Les logiciels sous Windows ont longtemps utilisé la norme ANSI, qui reprenait le code ASCII et proposait des extensions différentes selon la « page de code » retenue : la page de code 850 était très employée en France, la page de code 864 définissait un jeu de caractères arabes. Un même octet pouvait donc désigner des caractères différents selon la page de code, source d’innombrables erreurs d’affichage.
Unicode
L’avènement de la mondialisation a conduit à la nécessité de construire un encodage de caractères le plus universel possible. C’est la norme ISO/CEI 10646 intitulée Technologies de l’information — Jeu universel de caractères codés (JUC) qui tente depuis 1988 de définir un système de codage universel pour tous les systèmes d’écriture.
Ce code cherche à supprimer les pages de code et à reprendre l’ensemble des caractères utilisés de par le monde. Il reste basé sur la codification ASCII. Chaque caractère est identifié par un nom unique et associé à un nombre entier positif appelé son point de code. Plus de 150 000 caractères (symboles, lettres, nombres, idéogrammes, logogrammes) issus de langues, systèmes d’écriture, traditions du monde entier sont recensés dans le JUC. De nouveaux caractères provenant d’écritures plus rares ou plus anciennes, ou encore de systèmes nouveaux, sont fréquemment ajoutés ou mis à jour dans le JUC.
Depuis 1991, le Consortium Unicode collabore avec l’ISO pour développer le Standard Unicode (« Unicode »). Chaque publication d’une nouvelle version d’Unicode donne ensuite lieu à une mise à jour de la norme, c’est-à-dire l’adjonction de nouveaux caractères et la mise à jour de ceux déjà présents.
Dans le standard Unicode, chaque caractère reçoit une identification numérique sous la forme U+xxxx (où xxxx est un nombre hexadécimal de 4 à 6 chiffres, entre U+0000 et U+10FFFF) : U+0041 pour « A », U+00E9 pour « é », U+20AC pour « € ». La plage définie permet d’attribuer jusqu’à 1 114 112 points de code.
Le point de code est un nombre ; reste à décider comment l’écrire en octets. Unicode existe pour cela en trois déclinaisons :
- avec UTF-32, chaque caractère occupe 32 bits, soit 4 octets, quel que soit le caractère ;
- avec UTF-16, chaque caractère occupe 1 ou 2 mots de 16 bits ;
- avec UTF-8, chaque caractère occupe de 1 à 4 octets. C’est la déclinaison la plus utilisée, car elle est rétro-compatible avec ASCII : les 128 caractères ASCII sont codés à l’identique sur un octet.
Les systèmes Unix, Linux et macOS utilisent UTF-8 par défaut ; Windows travaille en interne en UTF-16 mais lit et écrit couramment de l’UTF-8.
Exercice 4. Ouvrir un document texte en utilisant un éditeur de texte de votre choix (Google Docs, LibreOffice, Microsoft Word, Pages, etc.). Dans le menu « Insertion », cliquer sur « Caractères spéciaux » et donner le point de code Unicode des caractères suivants : é - € - @ - & - à
La table complète se trouve sur symbl.cc (le code est donné en hexadécimal : par exemple U+0041 pour la lettre A majuscule).
Le mécanisme UTF-8
UTF-8 découpe le point de code en morceaux répartis dans 1 à 4 octets. Les premiers bits de chaque octet indiquent son rôle : un octet qui commence par 0 est un caractère ASCII à lui seul ; un octet qui commence par 110, 1110 ou 11110 ouvre une séquence de 2, 3 ou 4 octets ; les octets suivants de la séquence commencent tous par 10.
| Point de code | Nombre d’octets | Forme binaire |
|---|---|---|
| U+0000 à U+007F | 1 | 0xxxxxxx |
| U+0080 à U+07FF | 2 | 110xxxxx 10xxxxxx |
| U+0800 à U+FFFF | 3 | 1110xxxx 10xxxxxx 10xxxxxx |
| U+10000 à U+10FFFF | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Exemple : le caractère « é ». Son point de code U+00E9 vaut 233, soit 11101001 en binaire : il faut 2 octets. On répartit ses 11 bits (000 1110 1001, complétés par des zéros à gauche) dans les cases x de la forme 110xxxxx 10xxxxxx :
110 00011 10 101001
C 3 A 9
« é » s’écrit donc C3 A9 en UTF-8, contre le seul octet E9 en Latin-1. Un emoji comme « 😀 » (U+1F600) occupe quatre octets : F0 9F 98 80.
Un texte mal décodé. Si un fichier écrit en UTF-8 est lu comme du Latin-1, les deux octets C3 A9 sont interprétés comme deux caractères, « à » et « © » : « été » s’affiche « été ». À l’inverse, un fichier Latin-1 lu comme de l’UTF-8 produit des caractères de remplacement « � ». Ces symptômes signalent toujours un décalage entre l’encodage d’écriture et l’encodage de lecture.
Malgré les efforts des comités de normalisation, il est donc parfois nécessaire de convertir un texte d’un encodage à un autre. Tous ces formats reposent sur la même idée : associer un nombre, c’est-à-dire un mot binaire, à chaque caractère.
En Python
Les fonctions ord et chr passent d’un caractère à son point de code (donné en décimal) et réciproquement :
ord(caractere): donne le point de code du caractère ;chr(numero): donne le caractère correspondant au point de code.
print(ord('B'))
print(chr(67))
print(ord('é'), hex(ord('é')))
66
C
233 0xe9
La méthode encode d’une chaîne de caractères donne ses octets dans l’encodage choisi, et la méthode decode d’une suite d’octets reconstitue la chaîne :
print("é".encode("utf-8"))
print("é".encode("latin-1"))
print(len("été".encode("utf-8")), len("été".encode("latin-1")))
print(b"\xc3\xa9".decode("utf-8"))
print("été".encode("utf-8").decode("latin-1"))
b'\xc3\xa9'
b'\xe9'
5 3
é
été
La dernière ligne reproduit le défaut d’affichage décrit plus haut. Pour lire ou écrire un fichier texte, on précise toujours l’encodage ; convertir un fichier d’un encodage à l’autre tient en quelques lignes :
with open("texte-latin1.txt", encoding="latin-1") as source:
contenu = source.read()
with open("texte-utf8.txt", "w", encoding="utf-8") as destination:
destination.write(contenu)
Texte simple et texte enrichi
Les textes en ASCII ou en Unicode ne sont que des suites de caractères. Les logiciels de traitement de texte y ajoutent une mise en forme : police, taille, italique, gras, couleurs, titres, liens vers d’autres textes. Un texte qui porte ces informations est un texte enrichi, par opposition au texte simple. Un format enrichi repose sur des balises qui structurent et mettent en forme le contenu : c’est le principe du langage HTML des pages web, étudié dans la partie sur le web.
Les formats enrichis sont nombreux : les langages à balises GML (1969) puis SGML (1986), dont HTML (1990) et XML (années 1990) sont dérivés ; le format RTF (1987), lisible mais limité ; les formats de bureautique fondés sur XML, OpenDocument (norme ISO en 2006, fichiers .odt de LibreOffice) et Office Open XML (2006, fichiers .docx, .xlsx et .pptx) ; enfin \(\TeX{}\), présenté en annexe.
Annexe : un exemple de document LaTeX
Donald Knuth, auteur de « L’Art de la programmation », s’est un jour de 1977 indigné de la qualité d’impression de ses ouvrages. Il développa \(\TeX{}\), une syntaxe très élaborée destinée à l’écriture humaine, spécialement puissante pour les équations mathématiques. \(\TeX{}\) reste le standard de l’édition scientifique de qualité. Toutefois, cela reste un langage de programmation destiné à la mise en forme, davantage conçu pour l’apparence des documents que pour stocker ou transférer des données.
Le document \(\TeX{}\) suivant…
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage{amsmath}
\usepackage{booktabs}
\title{Exemple de document compilé en \LaTeX}
\author{Razik Ikhlef}
\date{\today}
\begin{document}
\maketitle
\section*{Exercice 1}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam vestibulum accumsan nisl.
\section*{Exercice 2}
Résoudre dans $\mathbb{R}$ l'inéquation suivante : \[x^2-3x+9\geq0.\]
\section*{Exercice 3}
Voici un tableau centré horizontalement :
\begin{center}
\begin{tabular}{@{}llr@{}} \toprule
\multicolumn{2}{c}{Item} \\ \cmidrule(r){1-2}
Animal & Description & Price (\$)\\ \midrule
Gnat & per gram & 13.65 \\
& each & 0.01 \\
Gnu & stuffed & 92.50 \\
Emu & stuffed & 33.33 \\
Armadillo & frozen & 8.99 \\ \bottomrule
\end{tabular}
\end{center}
\end{document}
… donne le PDF suivant après compilation :

Pour ceux qui veulent en savoir plus :
Il est possible de créer un compte gratuitement sur la plateforme Overleaf pour s’entraîner (utiliser votre compte Google CSI) :