Les systèmes de traitement de l'information ont toujours utilisé des techniques de codage, bien avant l'informatique : les différents systèmes d'écriture, le Braille, le Morse, la sténo. Avec la généralisation de la numérisation de l'information sous toutes ses formes, il existe maintenant une grande variété de codes, adaptés à ses divers supports de transmission et de stockage (cables coaxiaux, ondes hertziennes, disques magnétiques, CD-ROM, Mini-Disc, etc). Les codes sont conçus, outre la simple représentation de l'information, pour satisfaire à certaines exigences sur l'information codée :
Les codes font intervenir plusieurs notions, que nous définissons ici
brièvement. Un langage est un ensemble de mots, un mot est une suite
finie de symboles, un symbole est un élément d'un alphabet, et un
alphabet est un ensemble quelconque, de préférence fini. Quand on
s'intéresse à des textes, on travaille avec un alphabet formé d'un
jeu de caractères : par exemple l'alphabet formé des 26 lettres
de l'alphabet latin, en minuscules et en majuscules, des 10 chiffres,
des signes de ponctuation et de quelques symboles usuels (<
,
&
, @
, etc) que l'on trouve sur un clavier d'ordinateur
anglais (un clavier français devrait y ajouter les lettres accentuées).
Quand on s'intéresse à ce que contient la mémoire d'un ordinateur, c'est
l'alphabet binaire, formé des deux symboles 0 et 1 qui est à considérer.
Le traitement des langages a maintenant des applications très au-delà
des besoins de l'informatique. Par exemple, l'analyse du génome humain
se fait à l'aide des mêmes techniques et requiert des algorithmes
élaborés, vu la taille des données en jeu.
Soit A un ensemble dont les éléments seront appelés des symboles ; une suite finie de symboles est appelée un mot sur l'alphabet A ; un tel mot est aussi noté , et l'entier m est sa longueur. L'ensemble de tous les mots sur l'alphabet A est noté . Le produit (de concaténation ) des mots et est le mot , de longueur m+n. C'est une opération associative, pour laquelle le mot vide , de longueur nulle, est élément neutre. Un langage sur un alphabet A est un sous-ensemble de .
Un code est un langage C sur un certain alphabet A, muni d'un codage, qui est une application d'un certain ensemble S vers C et d'un décodage qui réalise l'opération inverse. Souvent, l'ensemble codé S est lui-même l'alphabet d'un langage, dit alphabet source et le codage s'étend naturellement en un codage de . Les codes les plus simples sont de longueur constante. Le plus connu est le code ASCII , qui contient tous les mots de longueur 7 sur l'alphabet binaire, autrement dit, les 128 (= 27) mots de 7 bits, et permet ainsi de représenter les caractères usuels anglais. Par exemple, le caractère A est codé par le mot binaire 1000001, écrit plus commodément 0x41 en notation hexadécimale (le préfixe 0x signale un nombre hexadécimal, c'est-à-dire en base 16). Le codage d'un mot de l'alphabet source se fait à l'aide d'une table, structure de données associant à chaque symbole de l'alphabet source son code :
Symbole | Code |
A | 1000001 |
B | 1000010 |
C | 1000011 |
... | ... |
Il existe des codes ASCII étendus, à 8 bits (un octet), qui représentent aussi les lettres accentuées, par exemple le code ISO8859-1, appelé aussi latin-1, adapté à la plupart des langues de l'Europe de l'ouest et du nord ; le caractère À est représenté dans ce code par le mot binaire 11000000, ou 0xC0. Un tel code ne peut représenter que 256 (= 28) caractères, ce qui est insuffisant. Par souci d'internationalisation, les caractères de Java (comme de la plupart des langages conçus pour l'Internet : XML, HTML4, ECMAScript, WML, etc.) utilisent le code Unicode, sur 16 bits. Celui-ci permet de représenter au plus 65 536 caractères, ce qui suffit pour un grand nombre de langues (mais pas vraiment pour toutes) ; par exemple, le nouveau symbole de l'euro a récemment reçu le code 0x20AC (en binaire, 00100000 10101100). Notons que toutes les valeurs des types primitifs de Java sont également représentées à l'aide de codes de longueur constante sur l'alphabet : des mots de 32 bits pour le type int, de 64 bits pour double, etc.