D o m i n i q u e   G u e b e y    J u n g l e      Bazar informatique

Le codage des caractères

Sommaire :

Préambule

Les documents Web, qui sont ici notre propos, et beaucoup d’échanges, protocoles et services associés, sont fondés sur une structure et des données texte, c’est à dire composés de suites de caractères identifiables (chiffres et lettres, signes de poncturation, espaces…). Sur l’opposition texte/binaire voir plus bas. Le texte a l’avantage d’être facilement convertible et portable entre différents types d’ordinateurs, terminaux, systèmes ou appareils de transmission. Mais cette universalité ne saurait être sans l’adoption de conventions et de normes. Dès lors, une initiation à l’encodage est un passage obligé si on veut répondre aux exigences minimales de qualité et ne pas se trouver dépourvu dans des cas comparables à ce qui suit.

Le texte attendu :

Ich bin der Geist, der stets verneint !
Und das mit Recht ; denn alles, was entsteht,
Ist wert, dass es zugrunde geht ;
Drum besser wär's, dass nichts entstünde. [1]

Le texte obtenu :

Ich bin der Geist, der stets verneint !
Und das mit Recht ; denn alles, was entsteht,
Ist wert, dass es zugrunde geht ;
Drum besser wär?s, dass nichts entstünde.

L’apostrophe du dernier vers pose problème. Explication classique : le directeur de publication s’est laissé convaincre par son neveu qu’il lui fallait un site internet. Bombardé webmestre, ledit neveu n’a eu de cesse que de coller dans des pages HTML dûment étiquetées au format standard iso-8859-1 des textes copiés tout droit de son traitement de texte Microsoft codant en cp-1252. L’anomalie sur le caractère apostrophe est un signe très sûr de cette aberration.

Il y a encore plus spectaculaire. Le texte attendu :

So ist denn alles, was ihr Sünde,
Zerstörung, kurz das Böse nennt,
Mein eigentliches Element.

Le texte obtenu :

So ist denn alles, was ihr Sünde,
Zerstörung, kurz das Böse nennt,
Mein eigentliches Element.

Explication : on a lu en iso-8859-1 un texte encodé en fait en UTF-8. Cette dernière norme permet de représenter un très grand nombre de caractères, mais pour beaucoup d’entre eux, comme les voyelles accentuées, l’encodage prend deux fois plus de place, d’où l’apparition des deux caractères bizarres à la place d’un seul.

Reprenons donc les choses par le début ; les connaisseurs passeront ce qui leur est superflu.


Du BIT à l’OCTET

Une mémoire d’ordinateur réside :

  1. soit dans une mémoire vive (circuit électrique miniaturisé) ; mémoire qui s’efface dès que le courant est coupé.
  2. soit sur un support de stockage permanent. Ce dernier est souvent un disque magnétique recouvert d’oxyde de fer (suivant la même technique que les classiques bandes magnétiques) ; ce peut être aussi un système optique (comme les CD-Rom).

L’information traitée sous forme d’unités élémentaires électriques ne peut prendre que 2 valeurs (0 ou 1), selon que l’emplacement est chargé positivement ou négativement. Cette unité d’information fondamentale est un « bit ». On conviendra que disposer de seulement 2 valeurs est très limitatif, à côté par exemple des 26 lettres de notre alphabet latin. [2]

En informatique, l’unité usuelle n’est pas le bit mais plutôt le groupe de 8 bits qu’on nomme octet, ou byte (prononcer baïte). On peut l’appeler “caractère” dans les cas d’encodage simple comme ASCII.

Un octet peut prendre 256 valeurs différentes (2x2x2x2x2x2x2x2 ou 2 puissance 8) allant de 0 à 255. Exemples avec l’équivalent en notation décimale habituelle :


Notation hexadécimale

Une notation commode est l’hexadécimale. Au lieu d’utiliser seulement la base dix avec les chiffres de 0 à 9, on utilise une base 16 (2 puissance 4) en ajoutant les 6 lettres de A à F. Ce qui s’inscrit en décimal : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 devient 0 1 2 3 4 5 6 7 8 9 A B C D E F en hexadécimal.

Pour signaler l’utilisation de l’hexadécimal, une habitude ancienne est d’ajouter “x” avant ou après. Exemple : le signe astérisque est 42 (décimal) ou 0x2a (hexadécimal) ; ou encore '2a'x. La même notation peut se trouver dans des entités en X/HTML : le u avec accent aigu, utile en espagnol, se code ֣ ce qui est la même chose que ֣ (sur la notion d’entité, voir plus loin [http://www.dg77.net/tekno/xhtml/specarac.htm#ent])

En hexadécimal, un octet se note avec seulement 2 caractères (le maximum est FF au lieu de 255) :

Voici une table de conversion. Les lignes correspondent au premier caractère hexadécimal, les colonnes au second. Le contenu donne les valeurs décimales. Exemple : x41=(4x16)+1=65 (1=2e colonne, ne pas oublier qu’il s’agit non pas de nombres mais de numérotage qui commence par zéro).

x   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
0  000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015
1  016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031
2  032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047
3  048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063
4  064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079
5  080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095
6  096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111
7  112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
8  128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
9  144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
A  160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
B  176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
C  192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
D  208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
E  224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
F  240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

Il est utile de disposer d’un éditeur hexadécimal, par exemple XVI32 (sous MS Windows), Shed, Khex, Ghex (UNIX/Linux), Hexedit (MacOs). Cet outil très simple permet d’inspecter et éventuellement modifier n’importe quelle donnée grâce à l’affichage exact du code interne des octets.


Binaire contre Texte, et autopsie de fichiers

L’objet couramment manipulé dans les ordinateurs est le fichier (en anglais file), bloc de données plus ou moins structurées. Un fichier peut contenir différents types d’informations, en fonction de son utilisation. Cela va de la table contenant un fichier client, avec ses colonnes bien définies (nom, adresse, références bancaires, etc.) jusqu’aux suites cabalistiques d’instructions et d’adresses machine des programmes compilés ; sans parler des fichiers d’images, sons et autres envahissants objets multimédia.

Il n’existe pas de définition formelle de ce qu’est un fichier binaire, et guère mieux pour le texte. En pratique, le contenu texte sera lisible par l’être humain, et le binaire ne le sera pas. On remarquera souvent qu’un fichier binaire n’est pas divisé en enregistrements ou lignes séparées par un caractère de saut ou fin-de-ligne, mais ceci n’est pas vraiment significatif. Des fichiers textes peuvent se retrouver sous forme binaire s’ils sont compressés [3] ou cryptés.

Figure 2

Un fichier peut contenir en même temps du texte et du binaire. C’est le cas pour un tableau Excel, ou un état PDF. L’illustration (fig. 2) donne un autre exemple : une image JPEG, d’un artiste aux mérites probablement méconnus. Le format JPEG (qui est une méthode de compression particulière) peut embarquer des indications textuelles sur le sujet. L’image suivante (fig. 3) montre le même fichier visionné dans l’éditeur hexadécimal XVI32. [http://www.chmaas.handshake.de/] Le panneau de gauche donne les codes hexadécimaux. Dans celui de droite, on distingue les mentions IPTC, renseignées pour les besoins de la démonstration (copyright, légende, source, auteur…). La suite contient les données binaires non représentables (en principe 24 bits pour chaque pixel) qui permettront à un programme adapté de faire apparaître l’image à l’écran ou en impression.


Figure 3

Les langages de programmation sont classés en langages interprétés et langages compilés. Dans le premier cas, c’est au stade de l’exécution que l’ordinateur, à l’aide d’un logiciel interpréteur, se charge de traduire en données binaires (code machine) les instructions. Dans le second cas, ces instruction produites par le programmeur sont converties préalablement, par une opération appelée compilation. Mais quel que soit le type de langage, il faut commencer par écrire les instructions sous forme texte.

Un intérêt des programmes compilés, qui sont des fichiers binaires, est d’être plus compacts et plus rapides d’utilisation que les programmes à interpréter. Ceci est dû au fait qu’ils sont plus proches du fonctionnement intime (au niveau matériel) de la machine. Mais il y a des contreparties à cette puissance des données binaires, en dehors du fait qu’elles sont proprement incompréhensibles. Elles doivent être lues et manipulées par un programme ad-hoc, et suivre les particularités de la plate-forme informatique utilisée [4]. A l’inverse, les fichiers textes ne souffrent pas de cette dépendance au système.

Ci-dessous un membre de programme en langage interprété REXX.

  if zsep > 0 & zsep < 5 then DO
    poslf = POS(' ',ligne,posl)
    trav2 = SUBSTR(ligne,1,zsep-1)
    if poslf == 0 then trav2 = trav2 || ' ' || SUBSTR(ligne,posl+1,long-posl)
                  else trav2 = trav2 || ' ' || SUBSTR(ligne,posl+1,poslf-posl)
    trav2 = trav2 || ' ' || SUBSTR(ligne,zsep+1,posl-zsep-1) || ' '
    if poslf > 0 then trav2 = trav2 || SUBSTR(ligne,poslf+1,long-poslf)
    ligne = trav2
  END

On observe que (comme dans tous les autres langages de programmation), le jeu de caractères utilisé dans les instructions est composé d’un ensemble limité. Il s’agit des codes ASCII.


ASCII

Norme fondamentale, ASCII (i.e. American Standard Code for Information Interchange), est un encodage en mode caractère basé sur l’alphabet anglais, dépourvu d’accents. Les codes ASCII représentent du texte dans les ordinateurs et tout appareil utilisant des informations en mode texte. Beaucoup d’encodages subséquents sont historiquement dérivés d’ASCII, standard publié en 1967 et dont la dernière version est de 1986. ASCII définit les codes pour 95 caractères ASCII “imprimables”, numérotés de 32 à 126 ; et 33 caractères dits non imprimables, la plupart obsolètes.

Type Binaire Déc. Hex. Caractères
Caractères "non imprimables" 00000000 à 00011111 0 à 31 x00 à x1F ex: touches Entrée, tabulation, fin de ligne, retour chariot, verrouillage/déverrouillage clavier…
01111111 127 x7F Touche de suppression [DEL]
Espace 00100000 32 x20
Caractères de ponctuation et signes divers 00100001 à 00101111 33 à 47 x21 à x2F ! " # $ % & ' ( ) * + , - . /
Chiffres 00110000 à 00111001 48 à 57 x30 à x39 0 1 2 3 4 5 6 7 8 9
Divers autres signes 00111010 à 01000000 58 à 64 x3A à x40 : ; < = > ? @
Lettres en majuscules 01000001 à 01011010 65 à 90 x41 à x5A A B C D … X Y Z
Divers autres signes 01011011 à 01100000 91 à 96 x5B à x60 [ \ ] ^ _ `
Lettres en minuscules 01100001 à 01111010 97 à 122 x60 à x7A a b c d … x y z
Divers autres signes 01111011 à 01111110 123 à 126 x7B à x7E { | } ~

Noter que pour passer de majuscules en minuscules, il suffit d’ajouter 32 (mettre à 1 le 3e bit, ou +100000).

Voir la TABLE COMPLETE en annexe.

Le code ASCII utilise 7 bits soit 128 possibilités, le 8e bit étant destiné au contrôle de parité [5], ou à gérer les interruptions. Ceci était bien conforme aux machines anciennes fonctionnant sur 8 bits. Aujourd’hui seulement 128 codes d’interruption ferait crier au scandale tout ingénieur-système [6]. Par ailleurs, en ASCII les caractères accentués manquent, ce qui indiffère les anglophones mais pêche pour à peu près tout le reste du monde.

John Donne s’affichais dès l’origine sans difficulté :

O my America ! my new-found-land,
My kingdome, safeliest when with one man man’d
My Myne of precious stones, My Emperie,
How blest am I in this discovering thee ! [7]

Mais il y avait problème pour un Luis de Góngora, avec ses ó, ¿, é, á, í et autres ñ  :

Si Amor entre las plumas de su nido
prendió mi libertad, ¿ qué hará ahora,
que en tus ojos, dulcísima señora,
armado vuela, ya que no vestido ? [8]

On s’est donc ingénié à concevoir des tables de codages qui prévoient le maximum de caractères accentués ou spéciaux.


CP850 et quelques autres pages de codes

Origines

CP = Code Page.

Ce sont les pages de code IBM PC, descendantes d’ASCII, mais codées sur 8 bits au lieu de 7, ce qui double les possibilités.

Quelques CP
CP437

CP437 est presque aussi ancien qu’ASCII et n’est cité ici que pour son rôle historique. Son affichage dans un éditeur graphique peut produire des effets curieux. CP437 ne permet pas une internationalisation satisfaisante.

CP850

CP850 est toujours susceptible d’être renconté. C’est l’encodage type de DOS « Latin-1 » d’Europe occidentale, encore utilisé dans les terminaux (“invite de commande”, “shell”…) sur les machines tournant sous MS-Windows en CP1252 (cf infra). Cette table a une partie commune avec CP437. Elle contient aussi les mêmes caractères (quoique à des positions différentes) qu’ISO-8859-1. Voir aussi :

KOI8

KOI8-R : page de code mono-octet pour le Russe et l’Albanais. KOI8-U : idem pour l’Ukrainien. Ces encodages furent mis au point de l’autre côté du rideau de fer. Ils permettent une translitération aisée (quoique inversant majuscules et minuscules) de l’alphabet cyrillique aux lettres latines, puisqu’il suffit de passer le premier bit de un à zéro pour passer du premier type au second. Il peut être utile de connaître l’existence de ces encodages, car on les rencontre plus souvent que les officiels ISO 8859-5 ou Windows-1251 (voir la suite). La table KOI8-R figure en annexe


ISO 8859

La « page de code » 8859-1 assez connue, souvent appelée Latin-1, forme la première partie de la norme internationale ISO/CEI 8859 (ISO = Organisation Internationale de Normalisation), pour le codage des caractères en informatique. Elle définit 191 caractères codés sur un octet (Voir en annexe).

Plus de 10 tables différentes ont été ainsi définies.

Le système ISO-8859 est peu satisfaisant. Je m’en suis rapidement rendu compte dans certaines pages de mon site Web, à l’origine défini en 8859-1. J’y enregistrais des résultats sportifs, et chaque fois que je voulais incorporer des classements tchèques ou polonais (pour ne citer que les cas les plus fréquents), il fallait que je les retouche manuellement. Je n’ai plus de soucis depuis le passage à UTF-8.


Windows-1252 / CP-1252

La série des pages de code CP1250 à 1258 visait à une meilleure internationalisation des affichages d’ordinateurs. Plus particulièrement, Windows-1252 est un encodage similaire à CP850 et ISO-8859-1, à la différence près que cette table comporte des caractères imprimables à la place de caractères de contrôle (0x80 à 0x9F) interdits en HTML. Cette page de code a d’ailleurs varié dans le temps tout en conservant la même référence… Voir la TABLE en annexe.

Comme il s’agit de l’encodage par défaut du très répandu système d’exploitation Microsoft Windows, il ne faut pas s’étonner de voir la plupart des navigateurs Web en tenir compte automatiquement. Quand se présente un code interdit dans une page censée être ISO-8859-n, ils le traîtent sous la forme prévue par Microsoft.

Ce n’est pas une raison pour tomber soi-même dans ce coupable laxisme quand on crée des documents XML. Il faut garder en tête que le XML/XHTML n’est pas simplement fait pour être affiché. Ces documents doivent pouvoir être traîtés par des programmes (robots, parsers et tout autre logiciel) ; sinon c’en est fait de l’interopérabilité.

On veillera toujours à ce que l’éditeur qu’on utilise ait l’encodage convenablement configuré.


Substitutions et échappements divers

Percent Escape

Les URL ou URI ne peuvent contenir qu’un jeu limité de caractères ; pour en représenter d’autres, un mécanisme a été défini [9]. En guise d’explication, on se limitera ici à donner un exemple minimum : supposons qu’un site web contienne des liens vers des documents bureautiques ou autres. On sait bien que leurs dénominations sont fréquemment laissées à la totale fantaisie de leurs auteurs, qui n’hésiterons pas à y mettre en particulier des espaces. On pourra avoir ainsi un état nommé “statistiques pour 2016.pdf”. L’URL pour l’atteindre et l’afficher dans le navigateur sera par exemple : http://www.duponddupont.com/archives/statistiques%20pour%202016.pdf.

La chaîne %20 spécifie le caractère ASCII "espace". Le signe pourcentage est dit « caractères d’échappement » (escape character). Outre l’espace, voici les autres codes réservés (à jour en janvier 2005) :


Quoted printable

Quoted printable est une technique destinée à contourner les limites du protocole d’envoi des courriers électroniques SMTP, qui ne connaît que l’ASCII, et est d’ailleurs basé sur seulement 7 bits. Supposons qu’un correspondant nous confie ce qui suit :

Coordonnées expéditeur Sender
Nom-Name:
eMail:

Texte:

Le texte transmis à votre programme client de courrier électronique sera un peu différent :

L=E0, j'ai eu =E0 r=E9veiller un monde qui n'=E9tait connu que de moi, =
je n'ai rencontr=E9, en errant dans cette soci=E9t=E9 =E9vanouie, que =
des souvenirs et le silence ; de toutes les personnes que j'ai connues, =
combien en existe-t-il aujourd'hui ? Les habitants de Saint-Malo =
s'adress=E8rent =E0 moi le 25 ao=FBt 1828, par l'entremise de leur =
maire, au sujet d'un bassin =E0 flot qu'ils d=E9siraient =E9tablir. Je =
m'empressai de r=E9pondre, sollicitant en =E9change de bienveillance, =
une concession de quelques pieds de terre, pour mon tombeau, sur le =
Grand-B=E9.

Il s’agit d’un e-Mail comportant dans sa partie prologue (occultée par les interfaces utilisateurs mais visible avec la fonction « affichage source ») une indication charset="iso-8859-1". Procédé : on utilise le signe égale ("=") comme caractère d’échappement : pour chaque caractère qui n’entre pas dans la liste des codes ASCII, on positionne un "=" suivi par la valeur hexadécimale (dans l’encodage spécifié, ici iso-8859-1) du caractère à représenter. Le "=" doit lui aussi être remplacé par "=61" bien qu’il entre dans la gamme ASCII. Il y a quelques autres règles, parmi lesquelles la limitation à 76 caractères de chaque ligne, qui doit se terminer par un "=" isolé (non traduit au décodage).

Si on veut concevoir son propre programme de réception et traîtement des informations, automatiser le décodage (comme l’encodage) quoted-printable n’est pas un problème : cela fait belle lurette que les programmeurs de tous les horizons ont rivalisé dans tous les langages pour fournir leurs scripts et autres API.

Quoted-printable fait partie des encodages MIME (voir dans la page Types MIME un e-Mail bulgare [http://www.dg77.net/tekno/xhtml/mime.htm#ex] comme autre exemple).


EBCDIC, CCSID et DBCS

Extended Binary Coded Decimal Interchange Code

Qui dit EBCDIC dit IBM. Comme les machines de Big Blue sont assez répandues, il n’est pas rare, en entreprise, de devoir aller piocher dans la base de données d’un de ces engins. Par conséquent, on se doit de connaître quelques termes et concepts de base, ne serait-ce que pour ne pas subir un trop vif choc culturel le jour où on rencontre l’équipe qui s’occupe de tout ça.

Carte perforee IBM

EBCDIC est un codage sur 8 bits, création d’IBM, utilisé depuis le S/360 sorti le 7 avril 1964. Sa conception d’origine est reliée aux cartes perforées utilisées à l’époque pour entrer les données dans les ordinateurs. EBCDIC a été maintenu depuis, et il est toujours mis en oeuvre sur les mainframes (aujourd’hui zSeries sous z/OS) et "mini" (AS/400, alias iSeries, alias System i5…). En revanche, les PC de type IBM n’utilisent pas EBCDIC mais les mêmes encodages issus d’ASCII que leurs concurrents. EBCDIC est ou était reconnu par d’autres machines, comme les Fujitsu-Siemens et certains Unisys.

En EBCDIC, un byte est divisé en deux parties (« nibbles »). La première, dite zone, indique la catégorie du caractère, la seconde, nommé digit, identifie le caractère lui-même. Dans l’exemple de table donnée en annexe, « & » porte le code 0x50 (hexadécimal) ou 80 (décimal) au lieu de 0x26/38 pour l’ASCII. La lettre L sera représentée par 0xD3…

Capture ecran iSeries, dsppfm vue hexadecimale

Noter quelques caractéristiques d’EBCDIC :

SBCS et DBCS

DBCS Double Byte Character Set : par opposition au SBCS (Simple…) ce codage sur deux octets connaît plusieurs variantes destinées à couvrir les besoins des écritures japonaises, coréennes et chinoises.

CCSID

IBM a prévu quelques dizaines de pages de code, chacune portant un numéro appelé le CCSID (Coded Character Set IDentifier). Voir en annexe les listes détaillées.

Quelques valeurs remarquables :

Un peu de pratique

WDSC - Websphere Developpment Studio Client permet de saisir une ligne de programme source en Hexadécimal, avec le choix simultané de plusieurs encodages. Pour cela : Clic droit sur la vue > Source > Edition hexa. ligne. Sur l’illustration, on voit que R se code U+0052 en Unicode, 0x52 en CP1252 et 0xD9 en EBCDIC.

WDSC

Pour ceux qui ont à mettre les mains dans le cambouis, spécialement sur iSeries (ex AS/400), voir la page dédiée à l’art du CCSID sur iSeries.


ISO 10646 et UNICODE

Cadre général

A côté d’ISO/IEC existe le consortium UNICODE issu de l’association de constructeurs d’ordinateurs, dont la visée première était de lutter contre le chaos des jeux de caractères et de favoriser l’internationalisation des systèmes. Unicode collabore depuis longtemps étroitement avec ISO/IEC et ses normes sont strictement compatibles avec les définitions d’ISO/IEC 10646.

Face aux limites du codage sur 8 bits, des encodages sur plus d’un octet ont été proposés. D’où ISO/IEC 10646 Universal Multiple-Octet Coded Character Set (Jeu de caractères multi-octets universel), abrégé en UCS. Le but est d’encoder tous les caractères de tous les langages du monde, plus les symboles, mathématiques et autres. Deux modes ont été défini : UCS-2 (sur 16 bits) et UCS-4 (sur 31 bits).

Présentation — BMP et Plans

De même que la notation hexadécimale se signale par un "x", un caractère Unicode se décrit avec "U+" suivi de la valeur hexadécimale correspondant au point de code (code point) défini par Unicode. Cette valeur comporte deux octets entre U+0000 et U+FFFF, plage qu’on appelle le plan de base multilingue ou BMP. Il s’agit des trois premières lignes du tableau ci-dessous. La suite (quatrième ligne) comporte 5 chiffres (hexa.) pour les 15 plans suivants (entre U+10000 et U+10FFF), ou 6 chiffres pour le dernier plan (U+100000 et la suite). UNICODE impose en fait une limite égale à +10FFFF.

Numéro UNICODE Nombre d’octets
Décimal Hexadécimal UTF-8 UTF-16 UTF-32
0 - 127 U+0000 - U+007F 1 2 4
128 - 2.047 U+0080 - U+07FF 2
2.048 - 65.535 U+0800 - U+FFFF 3
65.536 - 1.114.111 U+10000 - U+10FFFF 4 4
UCS-2

Dans la formule UCS à deux octets, on définit 256 rangées comprenant chacune 256 cellules. Soit 65.536 positions. La première rangée, ou rangée 0, contient tout simplement le jeu ISO/IEC-8859-1. [10]

UCS-4

La formule UCS à 4 octets utilise 31 octets seulement, le premier étant obligatoirement 0. Cet espace de codage de 2.147.483.648 positions, comporte 128 groupes de 256 plans. Le premier octet définit le groupe, le second indique le plan. Les troisièmes et quatrièmes donnent les rangées et numéro de cellule de chaque caractère. Le plan 0 du groupe 0 correspond à UCS-2(BMP).

Niveaux d’implémentation

Un système peut ne pas supporter toute l’étendue d’UCS. Trois niveaux ont été définis


UTF-8

UTF-8 (UCS transformation format 8 bits) est un format de longueur variable, défini pour les caractères Unicode. Chaque caractère est codé sur une suite de un à quatre octets. UTF-8 a été conçu pour assurer une bonne compatibilité avec les logiciels prévus pour traiter des caractères d’un seul octet. Les protocoles de communication d’Internet échangeant du texte doivent supporter UTF-8.

Description

Unicode attribue un numéro à chaque caractère. Les caractères de numéro 0 à 127 sont codés sur un octet dont le bit de poids fort est toujours nul. Les caractères de numéro supérieur à 127 sont codés sur plusieurs octets. Dans ce cas, les bits de poids fort du premier octet forment une suite de 1 de longueur égale au nombre d’octets utilisés pour coder le caractère, les octets suivants ayant 10 comme bits de poids fort.

Ce principe pourrait être étendu jusqu’à six octets pour un caractère, mais UTF-8 pose la limite à quatre. Ce principe permet également d’utiliser plus d’octets que nécessaire pour coder un caractère, mais UTF-8 l’interdit.

Dans toute chaîne de caractères UTF-8, on remarque que :

Définition du nombre d’octet utilisé
Représentation binaire Signification
0xxxxxxx 1 octet codant 1 à 7 bits
110xxxxx 10xxxxxx 2 octets codant 8 à 11 bits
1110xxxx 10xxxxxx 10xxxxxx 3 octets codant 12 à 16 bits
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4 octets codant 17 à 21 bits
Exemples de codage UTF-8
Caractère Commentaire Hex Numérique Binaire Binaire UTF-8
A x41 65 1000001 01000001
Ú xDA 0218 11011010 11000011 10011010
(Monnaie) signe Euro x20AC 8364 10000010101100 11100010 10000010 10101100
𝄞 (Musique) Clé de sol x1D11E 119070 11101000100011110 11110000 10011101 10000100 10011110

Dans la colonne de gauche, on voit s’afficher la clef de sol parce que la présente page est en UTF-8 ; en ISO-8859-1, ce ne serait pas possible. Si malgré cela le symbole ne s’affichait pas correctement, cela signifierai qu’il y a un problème avec votre navigateur [11].

Avantages
Inconvénients

UTF-16

UTF-16 (UCS-2 transformation format). UTF-16 est un format variable qui permet de représenter avec un mot de 2 octets tout le BMP, et avec 2 mots les autres plans Unicode. UCS-2 est le format ISO correspondant mais fixé à 2 bytes et donc limité aux possibilités du seul BMP. Sur le BMP, voir UCS-4 ci-dessus. En pratique, seul UTF-16 est utilisé.

L’UTF-16 est une solution très satisfaisante si la place mémoire n’est pas un problème primordial. En effet, la grande majorité des caractères Unicode assignés aux langues modernes (donc les caractères les plus fréquemment utilisés) le sont dans le plan multilingue de base et peuvent donc être représentés sur 16 bits

UTF-16 oblige à s’occuper de l’ordre dans lequel se présentent les octets quand il en faut plus d’un. Cela varie avec les différentes unités centrales informatiques ou normes de transmission.

UTF-16 en BE (big endian)
Bits 00000000 000uuuuu xxxxxxyy yyyyyyyy
UTF-16 BE (2 octets) si uuuuu = 00000 xxxxxxyy yyyyyyyy
UTF-16 BE (4 octets) 110110ww wwxxxxxx 110111yy yyyyyyyy
avec wwww = uuuuu - 1 si uuuuu > 00000
UTF-16 en LE (little endian)
Bits 00000000 000uuuuu xxxxxxyy yyyyyyyy
UTF-16 LE (2 octets) si uuuuu = 00000 yyyyyyyy xxxxxxyy
UTF-16 LE (4 octets) wwxxxxxx 110110ww yyyyyyyy 110111yy
avec wwww = uuuuu - 1 si uuuuu > 00000

UTF-32

UTF-32 (UCS-4 transformation format). Encodage sytématiques sur 4 octets, rarement utilisé. Cette formule fixe offre l’avantage de la simplicité mais constitue dans la plupart des cas un considérable gâchi de mémoire.


Identification et prologues

Différents procédés permettent de renseigner l’ordinateur sur l’encodage.

XML

Le premier caractère non blanc [12] d’un fichier XML doit être le signe “inférieur à” (60 ou x3C). La suite doit correspondre au prologue XML type :

<?xml version="1.0" encoding="ISO-8859-1"?>

Sans indication, le fichier sera censé être en UTF-8.

HTML

L’encodage d’une page Web est à spécifier dans une balise META, qui figure dans l’entête (partie head).

<head> … <meta charset="utf-8"/> … </head>

On peut utiliser l’attribut HTTP-EQUIV au lieu de charset :

<head> … <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> … </head>
BOM et phénomènes étranges

Dans les fichiers de type plain text (simple texte), il est possible d’utiliser le BOM - Byte Order Mark, “marque du sens des octets”. C’est une suite de caractères utilisée en tout début de fichier ou flot de données pour marquer l’endianness d’une chaîne de caractères Unicode encodée en UTF-16 ou UTF-32 et/ou comme marqueur pour indiquer que le texte est encodé en UTF-8, UTF-16 ou UTF-32.

En UTF-16, le BOM est une séquence de deux octets FE FF au début de la chaîne encodée, indiquant que les caractères encodés suivant utilisent l’ordre big-endian ; avec FF FE, ce sera little-endian. La valeur U+FFFE n’est PAS un caractère Unicode, et peut-être utilisée pour detecter l’ordre des octets, à l’inverse de U+FEFF qui est un caractère connu.

Encodage Séquence BOM
UTF-8 EF BB BF
UTF-32, big-endian 00 00 FE FF
UTF-32, little-endian FF FE 00 00
UTF-16, big-endian FE FF
UTF-16, little-endian FF FE
UTF-7 2B 2F 76 [ 38 | 39 | 2B | 2F | 38 2D ]
UTF-EBCDIC DD 73 66 73
SCSU (*) 0E FE FF
BOCU-1 (**) FB EE 28
(*) Standard Compression Scheme for Unicode
(**) Binary Ordered Compression for Unicode

Quand un programme a été correctement écrit, le BOM reste invisible de son utilisateur. Sinon, en tête de fichier on voit apparaître quelques signes étranges, comme  pour de l’UTF-8 ou þÿ pour l’UTF-16 "big-endian".

Beaucoup de logiciels Windows ajoutent la séquence aux fichiers UTF-8. Cependant, sur des systèmes Unix-like (dont Linux), qui utilisent beaucoup les fichiers textes pour la configuration, cette technique est dangereuse, car cela peut nuire au traîtement correct de codes importants tels que le hash-bang au début d’un script interprété. Il peut également interférer avec le source pour les langages de programmation qui ne le reconnaissent pas.

Le BOM explique dès lors certains problèmes : ne vous étonnez pas que votre script bash refuse de démarrer alors qu’il commence à première vue par le  #!/bin/bash  réglementaire (et que bash se trouve effectivement dans /bin !) : demandez vous si, à un moment quelconque, il n’a pas été modifié sous Windows. J’ai connu ce cas sur un PC utilisé en dual boot, en jouant entre Windows et Linux.


Entrée des codes au clavier

Ou : comment expérimenter les codes caractère.

Les traîtements de texte sophistiqués, comme Word ou Open Office, fournissent des moyens pour entrer les caractères complexe (accentués, ponctuation, symboles…). Dans d’autres cas (travail sous éditeur de texte, formulaire Web…), on peut se trouver limité par ce qu’offre le clavier. Mais le moyen existe d’utiliser le code interne pour obtenir en sortie tout caractère connu par l’ordinateur. Par exemple pour le O majuscule défini par la valeur 79 (x4F) dans la table ASCII, on peut utiliser la séquence : [Alt]+79 (frapper 79 tout en ayant la touche Alt enfoncée).

Il est rare que la touche Maj tombe en panne. Le procédé s’impose évidemment plutôt pour des caractères non prévus au clavier. Ainsi le code 0223 (xDF) permet d’avoir le "s gothique" (ß) cher aux germanophones. Attention : il faut entrer 0223 (quatre caractères) et non pas 223. Avec 0161 on aura le point d’exclamation inversé (xA1) que les espagnols placent en début d’une phrase terminée par le "!". Idem avec 0168 (xBF) pour le point d’interrogation. Plus particulièrement dans la zone francophone, on trouvera intérêt à connaître ces quelques codes (attention à bien entrer le zéro initial quand il est spécifié) :


Divers utilitaires et notes de programmation

Commandes
Commande iconv

iconv permet de sortir dans un encodage voulu des données encodées différemment lues en entrée.

Il s’agit d’une commande UNIX/LINUX. Les adeptes de ces pages savent qu’elle s’appliquera sans difficulté sur un système Windows grâce à Cygwin [http://www.dg77.net/tekno/manuel/cygwin.htm]. Voir des applications :

Langages de programmation
Langage Java

Java traîte les données en UNICODE. Des méthodes standard permettent de gérer les entrées et sorties dans d’autres encodages :

Langage REXX

Petit outil d’affichage (cf programme complêt) :

/* REXX */
  say " Caractere ? " ; parse pull caract
  say 'Hexadecimal : ' c2x(caract)
  say 'Decimal     : ' c2d(caract)
  say 'Binaire     : ' x2b(c2x(caract))

Application :

15:23:00,02>call bin\conv_hdb.rex
 Caractere ?
Ô
Hexadecimal :  E2
Decimal     :  226
Binaire     :  11100010

Les fonctions SYSTOUNICODE et SYSFROMUNICODE permettent de convertir une chaîne de caractère en unicode à partir d’un autre encodage, et vice-versa. On trouvera dans ces pages un exemple de programme les utilisant, ainsi qu’un cas ou la distinction little/big endian est nécessaire. Cf Generateur RSS à partir d’un fichier texte.

    ZONESORTIE.='NUL'; ZONESORTIE.0=0
    /* Convertir en UNICODE la zone "entree" codee UTF-8 */
    err = systounicode(entree, 'UTF8', , ZONESORTIE.)
    if err == 0 then sortie = ZONESORTIE.!TEXT
                else sortie = 'probleme car. ' || err
    …
      /* Insertion d’espaces en UTF-16 */
    DO travl/2
      tampon = tampon || '2000'x
      /* 0x2000 : octet de poids faible au début : 
      little endian, bon pour processeurs x86 */
    END
Systèmes
IBM AS/400 iSeries

Cf supra EBCDIC, CCSID et Cie.

MS Windows : invite de commande et sorties batch

Par défaut, les caractères sont censés être codés en CP850 (cf supra), ce qui donne un affichage déplorable de nos chers caractères accentués. Le problème se solutionne en appliquant la commande chcp 1252. Avec CP855, un Russophone verra apparaître son texte en cyrillique — sous réserve que sa console utilise une police adéquate.

Exemple avec quelques touches du clavier AZERTY français, qu’on a écrites dans un petit fichier (div.txt). Au départ, on est par défaut en CP850.

13:44:01,33>chcp
Page de codes active : 850
13:44:14,46>type div.txt
&Ú"'(-Þ_þÓ)=^$¨*,;:!¿ ú%Á?./º
13:44:25,56>chcp 1252
Page de codes active : 1252
13:44:31,29>type div.txt
&é"'(-è_çà)=^$ù*,;:!¨ £%µ?./§
Éditeurs
Éditeur Jext

Edit > Options > Editor > File encoding > Choisir la page de code

En chosissant ensuite Apply, le fichier sera enregistré avec le nouvel encodage à la prochaine mise à jour sur disque (Save, ou Save as…).

Éditeur Jedit

Jedit peut déterminer automatiquement l’encodage à l’ouverture d’un fichier. Si le résultat n’est pas satisfaisant, on peut faire ce qui suit :

Fichier > Recharger avec encodage > Choisir…

Paramétrage de base : Utilitaires > Jedit > Encodages.

On choisit alors le séparateur et l’encodage par défaut. On peut aussi agir sur la reconnaissance automatique de l’encodage et sur le BOM etc.

Éditeur VIM

VI/VIM cherche automatiquement l’encodage du fichier qu’on ouvre. À la sortie, il reste possible de préciser l’encodage. Exemple pour sortir en UTF-8 : set fileencodings=utf-8

Noter les options suivantes :

fileencoding
Encodage du fichier en cours.
inputencoding
Encodage des caractères entrés au clavier.

Notes


Cre : 24 aou 2006 - Maj : 25 avr 2017

A propos de ces pages / about these pages : http://www.dg77.net/about.htm
Gen : 22/05/2017-12:05:44,77