Tutoriel : Ne plus se laisser avoir par le phishing
Table des matières
Ne plus se laisser avoir par le phishing Qu'est-ce-que le phishing? Reconnaître l'email Reconnaître le faux site
Ne plus se laisser avoir par le phishing
Bonjour à toi, Zér0 !
Combien de fois vous est-il arrivé de recevoir un email d'une banque chez laquelle vous n'avez pas de comptes, ou d'un jeu massivement multijoueur auquel vous n'avez jamais touché, vous demandant de vous connecter à votre compte ?
Parfois même, vous avez un compte chez cette banque ou ce jeu... Mais l'email n'était pas envoyé par la véritable institution. C'était une manipulation habile pour vous soutirer vos informations. C'est ce qu'on appelle le phishing.
Et des gens se font avoir. Ils entrent leurs informations secrètes, et se trouvent avec un personage principal tout nu dans leur jeu préféré. Ou plus gênant, avec des euros en moins, ou un compte email qui envoie des milliers de spam journaliers...
C'est pourtant souvent facile de repérer le phishing. Je ne suis pas du tout un expert, mais je vais vous faire partager ce que je sais, parce-que je me retrouve souvent à le répéter à mes connaissances. Alors pourquoi ne pas le faire partager à tous les Zér0s ?
Qu'est-ce-que le phishing?
Un peu de culture générale
Le phishing est un terme informatique qui relève de l'envoi d'emails frauduleux incitant les utilisateurs à se connecter sur un site ressemblant à un site de leur connaissance avec leurs identifiants, permettant de stocker lesdits identifiants dans une base de données pour utilisation future.
Techniquement, en français, on dit filoutage, ou hameçonnage si on est québécois. Phishing est le terme anglais, dérivé de fishing, qui signifie pêche. Bref, c'est de la pêche de filous, quoi ! :lol:
Pour en savoir plus, comme d'habitude, un petit coup de Wikipédia !
À quoi ça ressemble?
Généralement, ça consiste en un email envoyé à des milliers d'utilisateurs par des techniques de spam. Cet email prend la forme d'un envoi d'une banque, d'une entreprise gérant un jeu vidéo en ligne, d'un service de poste électronique, etc. globalement connu, demandant à l'utilisateur de se connecter sur le site, via un lien fourni, pour une raison quelconque.
Si l'on suit le lien, on arrive en général sur une copie conforme du site où l'on pense se diriger. Si l'on ne réfléchi pas, on entre ses identifiants, on confirme, et on arrive soit sur une page d'erreur, soit sur une page vous remerciant, disant que votre connexion a été confirmée, ou quelque excuse correspondant à l'email envoyé.
Tout content, on repart vaquer à ses occupations, pour se rendre compte plus tard que quelqu'un s'est connecté à votre compte. Et fort probablement, qu'il ne s'est pas contenté de faire un petit coucou...
Pourquoi ça marche ?
Ça marche parce que les personnes qui reçoivent ces emails ne prennent pas le temps de vérifier que l'email est légitime.
L'email est envoyé à tellement de gens qu'il touche forcément des personnes qui ont un compte sur le site émulé. De plus, la raison invoquée demandant une connexion impose souvent une notion de temps limité et de problèmes en cas de non-connexion. En général, cela s'exprime par quelque chose du style "Votre compte a été compromis. Veuillez vous connecter suivant le lien ci-dessous pour éviter la suppression de votre compte."
Alors évidemment, on ne veut pas risquer de perdre son compte. Et qui sait quand le compte va être supprimé ? Mieux vaut se connecter sans perdre de temps...
En plus, personne ne peut rien faire pour contrer cela. Le pirate n'a même pas touché au site officiel, ni à votre ordinateur. Il a juste envoyé un mail vous demandant vos coordonnées, et vous les lui avez gentiment données. Évidemment, en cas de vol, ça reste un crime, mais il est difficile d'aller chercher un pirate Russe ou Troudukistanais...
Mais heureusement, avec un peu de bon sens et de logique, il est facile de repérer ces emails frauduleux ! C'est ce que je vais vous apprendre dans la suite de ce tutoriel.
Reconnaître l'email
Tout d'abord, il est souvent facile de voir si l'email est légitime ou non.
L'expéditeur
L'expéditeur de l'email est malheureusement souvent peu indicatif. Bien sûr, si jojo_le_pirate@hackerZ.org vous écrit de la part de votre banque, c'est même pas la peine de vous fatiguer à ouvrir le message.
Malheureusement, il est très facile d'envoyer un message soi-disant en provenance de n'importe quelle adresse. Ou alors de créer une adresse email qui ressemble à quelque chose de légitime.
Jetez donc un oeil à l'expéditeur, mais ne basez pas votre jugement uniquement sur ceci !
Le contenu
Lisez le contenu du message d'un oeil critique. Les pirates informatiques sont souvent assez mauvais en ortographe. :) Surtout s'ils écrivent dans une langue qui n'est pas leur langue maternelle !
Déjà, si Amazon, dont vous n'avez jamais fréquenté que la partie française, vous écrit en anglais, c'est louche.
Ensuite, guettez les petites fautes, comme les "-é" à la place des "-er". Les institutions professionnelles ont généralement les moyens de se payer des gens qui savent écrire dans leur langue. Et ils savent que les fautes font mauvais effet. Il y a rarement de fautes dans les emails des professionnels.
Non. À ce niveau-là, c'est pas qu'il n'est probablement pas légitime. C'est que c'est du phishing. Et ne rigolez pas trop, j'ai déjà reçu pire que ça...
Mais certains pirates sont suffisamment organisés pour vérifier leur orthographe. Ou alors ils sont cultivés ! o_O
Donc une bonne orthographe n'est pas suffisante. (De la même manière qu'une petite faute perdue toute seule ne veut pas forcément dire que l'email est du phishing ! Même les meilleurs font des fautes de temps en temps !)
Le lien fourni
Le plus décisif, à ce niveau, c'est le lien fourni. Parce-qu'au final, les pirates ne peuvent pas vous envoyer vers le site officiel. Il y a plein de moyens de déguiser un lien (parce-que peu de gens vont cliquer sur http://www.jojoLePirate.org/hackerZ... bien que...). Je vais vous expliquer un peu plus comment repérer les liens frauduleux.
Structure de l'URL
Tout d'abord, je vais commencer par vous expliquer à quoi ressemble une URL (autre mot pour une adresse internet).
Une URL est de la forme suivante: protocole://sous-domaine.domaine.extension(autre)
Vous remarquerez que chaque partie est séparée par un point. Les points dans une URL ne peuvent être utilisés que pour séparer ces parties.
Le protocole est généralement http ou https.
Le sous-domaine est généralement www mais peut être n'importe quoi !
Le domaine définit véritablement chez qui vous êtes.
L'extension est importante aussi, puisqu'il peut exister des sites avec le même nom de domaine mais des extensions différentes. monsite.fr et monsite.com n'ont probablement rien à voir !
Après l'adresse, on peut trouver plein de choses qui disent dans quelle partie du site aller, séparées de l'adresse principale par un symbole tel que # ou ?.
Pourquoi tu nous explique tout ça ? En quoi ça va nous aider ?
Ça va nous aider parce-que si on comprend comment marche une adresse internet, on peut facilement identifier les adresses déguisées. ^^
En effet, ce qui définit sur quel site vous êtes, c'est le domaine et l'extension. C'est tout. Tout le reste peut être n'importe quoi.
On va prendre un exemple, pour simplifier les choses. Supposons que le site de ma banque est http://www.banquedekatz.fr. :p banquedekatz.fr est ce qui défini le site de ma banque. Et il faut que ce soit à la bonne position. Qu'est-ce-que ça veut dire ?
Ça veut dire que les adresses suivantes ne me mèneront pas sur le site de ma banque:
Les adresses ci-dessus mèneront en fait vers les domaines suivants, au lieu de vers le domaine banquedekatz.fr:
jojolepirate.fr
banquedekatz.com
jojolepirate.fr
jojolepirate.fr
En revanche, l'adresse http://jojolepirate.banquedekatz.fr mènera bel et bien vers le site de ma banque. Peut-être vers une partie du site dédiée entièrement à combattre ce malin qu'est Jojo le Pirate.
Évidemment, les adresses ci-dessus sont pour la plupart assez évidentes. Mais qu'arrive-t-il si Jojo le Pirate est plus futé que ça, et que son site devient: http://banquedekatz.servicesconso.fr ? Cette adresse nous guide vers le domaine servicesconso.fr, qui n'est probablement pas déposé par ma banque...
Une URL différente
Bien entendu, ceci n'était qu'un des moyens de déguiser une URL. Un autre moyen tout simple est de changer l'adresse, carrément.
Reprenons l'exemple de ma banque imaginaire (je suis millionnaire dans cette banque :p ), dont l'adresse est http://www.banquedekatz.fr.
Beaucoup de gens ne connaissant pas l'adresse exacte de leur banque. Et si Jojo le Pirate avait réussi à acquérir l'adresse http://www.labanquedekatz.fr ?
Il y a un moyen simple pour contrer cela, si je ne connais pas le domaine exact de ma banque. Google !
Je vais sur Google (ou mon moteur de recherche favori), et je cherche "banque de katz". Il y a de grandes chances que le premier lien soit le bon ! En tout cas, le lien du pirate a peu de chances de tomber dans les 50 premières pages...
Maintenant, même si je sais que le domaine de ma banque est banquedekatz.fr, il faut faire attention à bien lire l'URL fournie dans l'email: www.bnaquedekatz.fr n'est pas bon ! wwwb.anquedekatz.fr non plus !
Il y a aussi toutes les lettres qui se ressemblent si on lit trop vite: banquedekatz.fr et barquedekatz.fr, par exemple. Ou BANQUEDEKATZ.FR et BANQUEDEKAT2.FR (les majuscules ne font pas de différences dans une URL). Ou encore, spécialement avec les liens soulignés banquedekatz.fr et banguedekatz.fr
Enfin, prêtez attention à l'extension. Comme on me l'a fait remarquer, l'extension du cameroun est .cm. Il suffit d'un peu d'inattention pour cliquer sur http://www.facebook.cm en croyant arriver sur sa page Facebook...
Le HTML
De nos jours, on peut recevoir des emails en code HTML. C'est-à-dire codés comme un site internet. La plupart des grandes compagnies envoient d'ailleurs leurs messages en code internet, c'est pour ça qu'il y a plein de couleurs et des tableaux (et des pubs... :colere: ).
Essayez par exemple le lien ci-dessous (et ne paniquez pas, tout est sous contrôle ! ;) ): http://www.banquedekatz.fr
:waw: Mais comment on peut combattre ça ? Y'a rien qui dit que le lien n'est pas celui qu'on croit !
Plusieurs façons, en fait:
Ne pas accepter les emails en HTML. L'option est disponibles dans la plupart des clients de courrier électronique. (Malheureusement, je ne crois pas qu'on puisse faire grand-chose si vous regardez vos emails sur un site internet comme MSN)
Regarder en bas de votre client ou de votre navigateur. Dans la petite barre en bas. Dans Firefox ou Thunderbird, par exemple (et je suis sûr que c'est pareil dans d'autres, bien que probablement pas dans tous), l'adresse réelle apparaît quand vous passez la souris sur un lien.
Souvent, il est possible de faire clic droit sur le lien, puis de copier la destination du lien. Vous pouvez coller cela quelque part et examiner cette adresse.
Enfin, au pire, cliquez dessus ! Et examinez l'adresse une fois arrivés sur la page concernée ! Tant que vous n'entrez pas vos informations, et que vous n'acceptez aucun téléchargement, il ne devrait rien vous arriver ! (Bon, il parait qu'il peut arriver des trucs... Mais c'est plus rare, surtout si vous avez un bon anti-virus et un explorateur internet intelligent. En cas de doute, rendez-vous sur le site via Google ou vos favoris !)
Autres déguisements
Enfin, il existe d'autres moyens de déguiser une adresse. http://www.banquedekatz.fr@jojolepirate.fr est un exemple. Utiliser des signes de pourcentage (%) permet de camoufler une adresse en utilisant le code ASCII au lieu des lettres. Donc évitez de cliquer sur une adresse qui contient un %. Toute partie de l'adresse se trouvant après un sera aussi ignorée. (Merci Grabeuh pour cette précision.)
Il est aussi possible de donner une URL par son adresse IP. Comment savoir si http://152.165.23.241 est légitime ou non ? (Quoique par défaut, si ce n'est pas facile à identifier, c'est louche...)
Si vous avez le moindre doute, la méthode la plus sûre est toujours la suivante:
Allez sur le site concerné en suivant l'adresse que vous suivez habituellement, ou en cherchant sur Google. Connectez-vous depuis ce site-là. Si votre compte est vraiment en danger, vous pouvez être sûr que les administrateurs du site auront laissé un message vous prévenant et vous donnant la marche à suivre pour y remédier bien en vue.
Reconnaître le faux site
Supposons que vous n'avez pas réussi à identifier l'email comme un faux. Vous avez suivi le lien. Vous êtes sur le site. Ici encore, il y a plusieurs façons d'identifier un site de phishing !
L'adresse
Comme énoncé plus tôt, vérifiez que vous êtes sur le bon site. L'adresse dans votre barre d'adresse est beaucoup plus difficile à camoufler que dans un email !
Les liens
Maintenant, le site devrait avoir l'air très proche du site sur lequel vous êtes censé croire être. Le pirate aura été chercher toutes les images dont il a besoin sur le vrai site. Il est même assez facile de récupérer les feuilles de style qui définissent l'aspect d'un site.
Mais il va rarement avoir pris le temps de recopier le site en entier. La plupart du temps, il se contente de recopier la page de connexion à votre compte.
Je ne sais pas si vous avez remarqué, mais sur la plupart des grands sites, il y a toujours un myriade de liens, même sur la page de connexion: Aide, Page d'Accueil, News, Nous contacter, Ouvrez un nouveau compte avec nous et gagnez 3.57€, etc.
Or, sur toutes ces pages se trouvent probablement d'autres liens, et des pages et des pages de textes, d'images, etc. Des trucs qui prendraient un temps monstre à reconstruire.
Donc les pirates ont trois possibilités pour ne pas avoir à reconstruire le site en entier:
Soit ils font des liens morts, qui ne font rien du tout quand vous cliquez dessus
Soit ils font des liens qui conduisent tous à la page sur laquelle vous vous trouvez déjà.
Soit ils font des liens qui conduisent vers le site officiel.
Les deux premières options sont faciles à débusquer: il suffit de cliquer sur quelques liens !
La dernière est un peu plus délicate, mais je ne l'ai jamais vu mise en application. Une des raisons est peut-être que d'une part, s'ils vous renvoient vers le site original, ils risquent de vous perdre si vous suivez les liens là-bas plutôt que de faire "Retour". Une autre est que le site original peut être au courant de la tentative de phishing, et avoir un gros message en rouge sur toutes ses pages disant: "Attention, phishing en cours ! Suivez ce lien pour vous connecter !" :p
Quoi qu'il en soit, si vous avez suivi mon cours sur la forme d'une URL plus haut, vous devriez pouvoir reconnaître si vous changez de domaine en suivant ces liens.
Connectez-vous!
Finalement, si vous ne savez plus si le site est justifié ou non, il reste un moyen très simple... Connectez-vous sur ce site !
Quoi ? Mais si c'est du phishing, je vais pas avoir des problèmes ?
Si, si vous utilisez vos vraies informations... Maintenant, si vous utilisez le nom d'utilisateur "JojoLePirate", avec le mot de passe "TuNousPrendsPourDesC*?", et que le site ne vous dit pas "Nom d'utilisateur ou mot de passe incorrect" (ou une variation appropriée), c'est que soit vous avez une chance inouïe, et vous vous êtes connectés sur le compte de Jojo le Pirate (auquel cas je vous conseille de jouer au loto TOUT DE SUITE ! :p ), soit le site accepte tout et n'importe quoi... Phishing !
Voilà, j'espère que ceci vous permettra de ne plus vous faire avoir par le phishing. N'hésitez pas à faire partager ce tutoriel à vos connaissances ! Si plus personne ne se fait avoir, les phisheurs disparaîtront !
Et reviendrons sans doutes avec d'autres méthodes... Mais on apprendra à s'en méfier aussi vite ! ;)
Dernier point: Aucune des méthodes que je donne ci-dessus n'est réellement 100% sûre. Presque tout est possible, si le pirate a suffisamment de connaissances et y passe suffisamment de temps. Cela arrive rarement, parce-qu'il parait que le phisheur gagne peu, donc il n'a pas intérêt a mettre trop de moyens dans une attaque par phishing.
D'ailleurs, si vous vous connectez sur votre compte d'après le site officiel, vous pouvez réessayer de cliquer sur votre lien. Normalement, si vous avez laissé votre explorateur ouvert, vous devriez sauter l'étape de connexion et arriver directement à votre compte ! ;)
Si vous voulez en savoir plus sur certaines techniques, jetez un oeil sur les commentaires, il y a des choses intéressantes ! ;)
Tutoriel : Ne plus se laisser avoir par le phishing
Table des matières
Ne plus se laisser avoir par le phishing Qu'est-ce-que le phishing? Reconnaître l'email Reconnaître le faux site
Ne plus se laisser avoir par le phishing
Bonjour à toi, Zér0 !
Combien de fois vous est-il arrivé de recevoir un email d'une banque chez laquelle vous n'avez pas de comptes, ou d'un jeu massivement multijoueur auquel vous n'avez jamais touché, vous demandant de vous connecter à votre compte ?
Parfois même, vous avez un compte chez cette banque ou ce jeu... Mais l'email n'était pas envoyé par la véritable institution. C'était une manipulation habile pour vous soutirer vos informations. C'est ce qu'on appelle le phishing.
Et des gens se font avoir. Ils entrent leurs informations secrètes, et se trouvent avec un personage principal tout nu dans leur jeu préféré. Ou plus gênant, avec des euros en moins, ou un compte email qui envoie des milliers de spam journaliers...
C'est pourtant souvent facile de repérer le phishing. Je ne suis pas du tout un expert, mais je vais vous faire partager ce que je sais, parce-que je me retrouve souvent à le répéter à mes connaissances. Alors pourquoi ne pas le faire partager à tous les Zér0s ?
Qu'est-ce-que le phishing?
Un peu de culture générale
Le phishing est un terme informatique qui relève de l'envoi d'emails frauduleux incitant les utilisateurs à se connecter sur un site ressemblant à un site de leur connaissance avec leurs identifiants, permettant de stocker lesdits identifiants dans une base de données pour utilisation future.
Techniquement, en français, on dit filoutage, ou hameçonnage si on est québécois. Phishing est le terme anglais, dérivé de fishing, qui signifie pêche. Bref, c'est de la pêche de filous, quoi ! :lol:
Pour en savoir plus, comme d'habitude, un petit coup de Wikipédia !
À quoi ça ressemble?
Généralement, ça consiste en un email envoyé à des milliers d'utilisateurs par des techniques de spam. Cet email prend la forme d'un envoi d'une banque, d'une entreprise gérant un jeu vidéo en ligne, d'un service de poste électronique, etc. globalement connu, demandant à l'utilisateur de se connecter sur le site, via un lien fourni, pour une raison quelconque.
Si l'on suit le lien, on arrive en général sur une copie conforme du site où l'on pense se diriger. Si l'on ne réfléchi pas, on entre ses identifiants, on confirme, et on arrive soit sur une page d'erreur, soit sur une page vous remerciant, disant que votre connexion a été confirmée, ou quelque excuse correspondant à l'email envoyé.
Tout content, on repart vaquer à ses occupations, pour se rendre compte plus tard que quelqu'un s'est connecté à votre compte. Et fort probablement, qu'il ne s'est pas contenté de faire un petit coucou...
Pourquoi ça marche ?
Ça marche parce que les personnes qui reçoivent ces emails ne prennent pas le temps de vérifier que l'email est légitime.
L'email est envoyé à tellement de gens qu'il touche forcément des personnes qui ont un compte sur le site émulé. De plus, la raison invoquée demandant une connexion impose souvent une notion de temps limité et de problèmes en cas de non-connexion. En général, cela s'exprime par quelque chose du style "Votre compte a été compromis. Veuillez vous connecter suivant le lien ci-dessous pour éviter la suppression de votre compte."
Alors évidemment, on ne veut pas risquer de perdre son compte. Et qui sait quand le compte va être supprimé ? Mieux vaut se connecter sans perdre de temps...
En plus, personne ne peut rien faire pour contrer cela. Le pirate n'a même pas touché au site officiel, ni à votre ordinateur. Il a juste envoyé un mail vous demandant vos coordonnées, et vous les lui avez gentiment données. Évidemment, en cas de vol, ça reste un crime, mais il est difficile d'aller chercher un pirate Russe ou Troudukistanais...
Mais heureusement, avec un peu de bon sens et de logique, il est facile de repérer ces emails frauduleux ! C'est ce que je vais vous apprendre dans la suite de ce tutoriel.
Reconnaître l'email
Tout d'abord, il est souvent facile de voir si l'email est légitime ou non.
L'expéditeur
L'expéditeur de l'email est malheureusement souvent peu indicatif. Bien sûr, si jojo_le_pirate@hackerZ.org vous écrit de la part de votre banque, c'est même pas la peine de vous fatiguer à ouvrir le message.
Malheureusement, il est très facile d'envoyer un message soi-disant en provenance de n'importe quelle adresse. Ou alors de créer une adresse email qui ressemble à quelque chose de légitime.
Jetez donc un oeil à l'expéditeur, mais ne basez pas votre jugement uniquement sur ceci !
Le contenu
Lisez le contenu du message d'un oeil critique. Les pirates informatiques sont souvent assez mauvais en ortographe. :) Surtout s'ils écrivent dans une langue qui n'est pas leur langue maternelle !
Déjà, si Amazon, dont vous n'avez jamais fréquenté que la partie française, vous écrit en anglais, c'est louche.
Ensuite, guettez les petites fautes, comme les "-é" à la place des "-er". Les institutions professionnelles ont généralement les moyens de se payer des gens qui savent écrire dans leur langue. Et ils savent que les fautes font mauvais effet. Il y a rarement de fautes dans les emails des professionnels.
Non. À ce niveau-là, c'est pas qu'il n'est probablement pas légitime. C'est que c'est du phishing. Et ne rigolez pas trop, j'ai déjà reçu pire que ça...
Mais certains pirates sont suffisamment organisés pour vérifier leur orthographe. Ou alors ils sont cultivés ! o_O
Donc une bonne orthographe n'est pas suffisante. (De la même manière qu'une petite faute perdue toute seule ne veut pas forcément dire que l'email est du phishing ! Même les meilleurs font des fautes de temps en temps !)
Le lien fourni
Le plus décisif, à ce niveau, c'est le lien fourni. Parce-qu'au final, les pirates ne peuvent pas vous envoyer vers le site officiel. Il y a plein de moyens de déguiser un lien (parce-que peu de gens vont cliquer sur http://www.jojoLePirate.org/hackerZ... bien que...). Je vais vous expliquer un peu plus comment repérer les liens frauduleux.
Structure de l'URL
Tout d'abord, je vais commencer par vous expliquer à quoi ressemble une URL (autre mot pour une adresse internet).
Une URL est de la forme suivante: protocole://sous-domaine.domaine.extension(autre)
Vous remarquerez que chaque partie est séparée par un point. Les points dans une URL ne peuvent être utilisés que pour séparer ces parties.
Le protocole est généralement http ou https.
Le sous-domaine est généralement www mais peut être n'importe quoi !
Le domaine définit véritablement chez qui vous êtes.
L'extension est importante aussi, puisqu'il peut exister des sites avec le même nom de domaine mais des extensions différentes. monsite.fr et monsite.com n'ont probablement rien à voir !
Après l'adresse, on peut trouver plein de choses qui disent dans quelle partie du site aller, séparées de l'adresse principale par un symbole tel que # ou ?.
Pourquoi tu nous explique tout ça ? En quoi ça va nous aider ?
Ça va nous aider parce-que si on comprend comment marche une adresse internet, on peut facilement identifier les adresses déguisées. ^^
En effet, ce qui définit sur quel site vous êtes, c'est le domaine et l'extension. C'est tout. Tout le reste peut être n'importe quoi.
On va prendre un exemple, pour simplifier les choses. Supposons que le site de ma banque est http://www.banquedekatz.fr. :p banquedekatz.fr est ce qui défini le site de ma banque. Et il faut que ce soit à la bonne position. Qu'est-ce-que ça veut dire ?
Ça veut dire que les adresses suivantes ne me mèneront pas sur le site de ma banque:
Les adresses ci-dessus mèneront en fait vers les domaines suivants, au lieu de vers le domaine banquedekatz.fr:
jojolepirate.fr
banquedekatz.com
jojolepirate.fr
jojolepirate.fr
En revanche, l'adresse http://jojolepirate.banquedekatz.fr mènera bel et bien vers le site de ma banque. Peut-être vers une partie du site dédiée entièrement à combattre ce malin qu'est Jojo le Pirate.
Évidemment, les adresses ci-dessus sont pour la plupart assez évidentes. Mais qu'arrive-t-il si Jojo le Pirate est plus futé que ça, et que son site devient: http://banquedekatz.servicesconso.fr ? Cette adresse nous guide vers le domaine servicesconso.fr, qui n'est probablement pas déposé par ma banque...
Une URL différente
Bien entendu, ceci n'était qu'un des moyens de déguiser une URL. Un autre moyen tout simple est de changer l'adresse, carrément.
Reprenons l'exemple de ma banque imaginaire (je suis millionnaire dans cette banque :p ), dont l'adresse est http://www.banquedekatz.fr.
Beaucoup de gens ne connaissant pas l'adresse exacte de leur banque. Et si Jojo le Pirate avait réussi à acquérir l'adresse http://www.labanquedekatz.fr ?
Il y a un moyen simple pour contrer cela, si je ne connais pas le domaine exact de ma banque. Google !
Je vais sur Google (ou mon moteur de recherche favori), et je cherche "banque de katz". Il y a de grandes chances que le premier lien soit le bon ! En tout cas, le lien du pirate a peu de chances de tomber dans les 50 premières pages...
Maintenant, même si je sais que le domaine de ma banque est banquedekatz.fr, il faut faire attention à bien lire l'URL fournie dans l'email: www.bnaquedekatz.fr n'est pas bon ! wwwb.anquedekatz.fr non plus !
Il y a aussi toutes les lettres qui se ressemblent si on lit trop vite: banquedekatz.fr et barquedekatz.fr, par exemple. Ou BANQUEDEKATZ.FR et BANQUEDEKAT2.FR (les majuscules ne font pas de différences dans une URL). Ou encore, spécialement avec les liens soulignés banquedekatz.fr et banguedekatz.fr
Enfin, prêtez attention à l'extension. Comme on me l'a fait remarquer, l'extension du cameroun est .cm. Il suffit d'un peu d'inattention pour cliquer sur http://www.facebook.cm en croyant arriver sur sa page Facebook...
Le HTML
De nos jours, on peut recevoir des emails en code HTML. C'est-à-dire codés comme un site internet. La plupart des grandes compagnies envoient d'ailleurs leurs messages en code internet, c'est pour ça qu'il y a plein de couleurs et des tableaux (et des pubs... :colere: ).
Essayez par exemple le lien ci-dessous (et ne paniquez pas, tout est sous contrôle ! ;) ): http://www.banquedekatz.fr
:waw: Mais comment on peut combattre ça ? Y'a rien qui dit que le lien n'est pas celui qu'on croit !
Plusieurs façons, en fait:
Ne pas accepter les emails en HTML. L'option est disponibles dans la plupart des clients de courrier électronique. (Malheureusement, je ne crois pas qu'on puisse faire grand-chose si vous regardez vos emails sur un site internet comme MSN)
Regarder en bas de votre client ou de votre navigateur. Dans la petite barre en bas. Dans Firefox ou Thunderbird, par exemple (et je suis sûr que c'est pareil dans d'autres, bien que probablement pas dans tous), l'adresse réelle apparaît quand vous passez la souris sur un lien.
Souvent, il est possible de faire clic droit sur le lien, puis de copier la destination du lien. Vous pouvez coller cela quelque part et examiner cette adresse.
Enfin, au pire, cliquez dessus ! Et examinez l'adresse une fois arrivés sur la page concernée ! Tant que vous n'entrez pas vos informations, et que vous n'acceptez aucun téléchargement, il ne devrait rien vous arriver ! (Bon, il parait qu'il peut arriver des trucs... Mais c'est plus rare, surtout si vous avez un bon anti-virus et un explorateur internet intelligent. En cas de doute, rendez-vous sur le site via Google ou vos favoris !)
Autres déguisements
Enfin, il existe d'autres moyens de déguiser une adresse. http://www.banquedekatz.fr@jojolepirate.fr est un exemple. Utiliser des signes de pourcentage (%) permet de camoufler une adresse en utilisant le code ASCII au lieu des lettres. Donc évitez de cliquer sur une adresse qui contient un %. Toute partie de l'adresse se trouvant après un sera aussi ignorée. (Merci Grabeuh pour cette précision.)
Il est aussi possible de donner une URL par son adresse IP. Comment savoir si http://152.165.23.241 est légitime ou non ? (Quoique par défaut, si ce n'est pas facile à identifier, c'est louche...)
Si vous avez le moindre doute, la méthode la plus sûre est toujours la suivante:
Allez sur le site concerné en suivant l'adresse que vous suivez habituellement, ou en cherchant sur Google. Connectez-vous depuis ce site-là. Si votre compte est vraiment en danger, vous pouvez être sûr que les administrateurs du site auront laissé un message vous prévenant et vous donnant la marche à suivre pour y remédier bien en vue.
Reconnaître le faux site
Supposons que vous n'avez pas réussi à identifier l'email comme un faux. Vous avez suivi le lien. Vous êtes sur le site. Ici encore, il y a plusieurs façons d'identifier un site de phishing !
L'adresse
Comme énoncé plus tôt, vérifiez que vous êtes sur le bon site. L'adresse dans votre barre d'adresse est beaucoup plus difficile à camoufler que dans un email !
Les liens
Maintenant, le site devrait avoir l'air très proche du site sur lequel vous êtes censé croire être. Le pirate aura été chercher toutes les images dont il a besoin sur le vrai site. Il est même assez facile de récupérer les feuilles de style qui définissent l'aspect d'un site.
Mais il va rarement avoir pris le temps de recopier le site en entier. La plupart du temps, il se contente de recopier la page de connexion à votre compte.
Je ne sais pas si vous avez remarqué, mais sur la plupart des grands sites, il y a toujours un myriade de liens, même sur la page de connexion: Aide, Page d'Accueil, News, Nous contacter, Ouvrez un nouveau compte avec nous et gagnez 3.57€, etc.
Or, sur toutes ces pages se trouvent probablement d'autres liens, et des pages et des pages de textes, d'images, etc. Des trucs qui prendraient un temps monstre à reconstruire.
Donc les pirates ont trois possibilités pour ne pas avoir à reconstruire le site en entier:
Soit ils font des liens morts, qui ne font rien du tout quand vous cliquez dessus
Soit ils font des liens qui conduisent tous à la page sur laquelle vous vous trouvez déjà.
Soit ils font des liens qui conduisent vers le site officiel.
Les deux premières options sont faciles à débusquer: il suffit de cliquer sur quelques liens !
La dernière est un peu plus délicate, mais je ne l'ai jamais vu mise en application. Une des raisons est peut-être que d'une part, s'ils vous renvoient vers le site original, ils risquent de vous perdre si vous suivez les liens là-bas plutôt que de faire "Retour". Une autre est que le site original peut être au courant de la tentative de phishing, et avoir un gros message en rouge sur toutes ses pages disant: "Attention, phishing en cours ! Suivez ce lien pour vous connecter !" :p
Quoi qu'il en soit, si vous avez suivi mon cours sur la forme d'une URL plus haut, vous devriez pouvoir reconnaître si vous changez de domaine en suivant ces liens.
Connectez-vous!
Finalement, si vous ne savez plus si le site est justifié ou non, il reste un moyen très simple... Connectez-vous sur ce site !
Quoi ? Mais si c'est du phishing, je vais pas avoir des problèmes ?
Si, si vous utilisez vos vraies informations... Maintenant, si vous utilisez le nom d'utilisateur "JojoLePirate", avec le mot de passe "TuNousPrendsPourDesC*?", et que le site ne vous dit pas "Nom d'utilisateur ou mot de passe incorrect" (ou une variation appropriée), c'est que soit vous avez une chance inouïe, et vous vous êtes connectés sur le compte de Jojo le Pirate (auquel cas je vous conseille de jouer au loto TOUT DE SUITE ! :p ), soit le site accepte tout et n'importe quoi... Phishing !
Voilà, j'espère que ceci vous permettra de ne plus vous faire avoir par le phishing. N'hésitez pas à faire partager ce tutoriel à vos connaissances ! Si plus personne ne se fait avoir, les phisheurs disparaîtront !
Et reviendrons sans doutes avec d'autres méthodes... Mais on apprendra à s'en méfier aussi vite ! ;)
Dernier point: Aucune des méthodes que je donne ci-dessus n'est réellement 100% sûre. Presque tout est possible, si le pirate a suffisamment de connaissances et y passe suffisamment de temps. Cela arrive rarement, parce-qu'il parait que le phisheur gagne peu, donc il n'a pas intérêt a mettre trop de moyens dans une attaque par phishing.
D'ailleurs, si vous vous connectez sur votre compte d'après le site officiel, vous pouvez réessayer de cliquer sur votre lien. Normalement, si vous avez laissé votre explorateur ouvert, vous devriez sauter l'étape de connexion et arriver directement à votre compte ! ;)
Si vous voulez en savoir plus sur certaines techniques, jetez un oeil sur les commentaires, il y a des choses intéressantes ! ;)
Tutoriel : La redirection HTTP
Table des matières
La redirection HTTP Introduction à la syntaxe Changement permanent de nom de domaine Déplacement définitif d'un dossier Déplacement définitif d'un fichier Suppression définitive d'un fichier Changer l'extension d'un fichier Redirection temporaire
La redirection HTTP
Vous venez de déménager votre site ? De changer l'URL d'une / de plusieurs page(s) ? D'un dossier ? Mais malheureusement vous avez peur que vos visiteurs s'affolent s'ils ne trouvent plus la / les pages déplacée(s) ? Que les moteurs de recherche soient perdus ?
J'ai la solution : les redirections.
Je dis les et non la redirections, car il existe plusieurs méthodes de redirection :
la redirection HTTP ;
la redirection HTML ;
la redirection PHP ;
la redirection Javascript.
Comme vous vous en doutez, il y en a de meilleures que d'autres, et c'est pour cela que je vais essayer de toutes les aborder en montrant les points positifs et négatifs de chacune d'elles.
Tout cela se fera sur plusieurs tutoriels ; dans celui-ci, je me contenterai de vous expliquer la redirection HTTP qui est à mon avis la meilleure de toutes. En tout cas, c'est sûrement la plus utilisée.
Avant de commencer, il vous faut savoir une chose : cette redirection fonctionne directement avec Apache.
La majeure partie des serveurs tournent sous Apache, l'autre partie (qui ne tourne pas sous Apache) comprend néanmoins les mêmes fichiers que ceux utilisés sur des serveurs Apache : ça ne pose donc pas de problème, généralement.
.htaccess : mais je connais ça, ce n'est pas le fichier dans lequel on configure les erreurs 40x (400, 401, 402, 403, 404... ) ? :euh:
Très bonne remarque ! C'est effectivement dans le même fichier que l'on fait ces deux manipulations. :)
Pour commencer, je vais vous donner un fichier d'exemple qui va vous montrer les possibilités de la chose. ^^
Oullaaaalaaalaaa... c'est quoi, ce truc ? :euh: :euh:
Ça, c'est un fichier .htaccess avec des règles de redirections complexes (les expressions régulières), mais pas de panique : je ne vais rien vous faire faire d'aussi compliqué !
Introduction à la syntaxe
Chaque ligne d'un fichier .htaccess est une instruction.
On peut décomposer les lignes en quatre parties :
Le changement d'adresse est toujours risqué : il a des risques que le site coule suite à un non-suivi des visiteurs et / ou un déréférencement du site.
On peut palier ce problème avec un type de redirection HTTP très précise.
Voilà comment ça se formule :
Redirect permanent / http://nouvelle.adresse.fr/
Prenons l'exemple sur d'un site personnel qui est hébergé chez free (http://monsite.free.fr) : le webmaster décide de s'acheter un nom de domaine et un hébergement : http://www.monsite.sdz. Il copie donc tout le site de l'ancienne vers la nouvelle adresse, mais pour conserver son référencement, il a mis en place une redirection HTTP du type de celui que nous venons de voir.
C'est le même principe que pour changer l'adresse d'un site, sauf que l'on remplace le sélecteur "/" (qui voulait dire "tout") par le chemin du dossier. :p
Ce qui nous donne pour déplacer http://www.monsite.com/dossier1/ vers http://www.monsite.com/dossier2/ :
Lorsque vous renommez un fichier de votre site, il est souvent utile de mettre une redirection à l'ancien emplacement vers le nouvel emplacement. Pour ce faire, on utilise la même directive de redirection que pour déplacer un dossier : Redirect permanent ; mais on cible un fichier au lieu de cibler un dossier.
Cette technique est utilisée pour indiquer aux visiteurs et aux moteurs de recherche que le fichier n'existe plus (et qu'il ne renaîtra pas) ; par conséquent, ils peuvent se mettre à jour. Cela se fait par l'intermédiaire d'une erreur 410 document n'existe plus.
Ici, on utilise qu'une seule adresse : celle du fichier supprimé (ici : /chemin/de_fichier_supprime.html).
Et comme option de directive, gone. Ce qui donne :
Redirect gone /chemin/du_fichier_supprime.html
Changer l'extension d'un fichier
Le changement d'extension de fichier est sûrement la redirection la plus utilisée. Par exemple sur le SdZ, pour toutes les pages ; si vous regardez l'adresse de ce tutoriel : , en réalité cette page n'est pas un fichier HTML, mais un fichier PHP du genre /tuto.php?variable1=3&variable2=4963&variable3=1.
Revenons à nos moutons.
Pourquoi cacher le nom original d'un fichier ?
Pour deux raisons :
le référencement : les moteurs de recherche n'aiment pas trop les noms de fichiers PHP avec des variables, c'est ce qui est fait ici ;
la génération d'image en PHP : si l'on veut intégrer une image générée par PHP dans un post d'un forum, ou dans une page XHTML, il faut qu'elle ait une extension d'image (c'est-à-dire : .jpg, .jpeg, .gif, .png...), et cette technique permet de cacher le nom de l'image.
Prenons pour exemple le deuxième cas : j'ai créé un fichier pseudo.php qui génère un texte en image ; ce texte est contenu dans la variable $texte qui est récupéré via $GET, ce qui donne un fichier pseudo.php?texte=sdz.
Ce fichier-là ne peut être affiché dans les forums car il faut afficher une image .jpg, .jpeg, .gif, .png. Grâce au changement d'extension de fichier, je peux faire croire aux forums que le fichier pseudo.php?texte=SDZ est une image .png (ou autre). Pour ce faire, je crée un fichier .htaccess avec comme instruction :
Si on utilise $get pour récupérer la variable $texte, c'est pour pouvoir changer de texte facilement, non ? Et là, avec cette technique, c'est impossible.
Oui, vous avez raison : si on utilise $get, c'est bien pour pouvoir changer facilement le texte généré. Et en utilisant le code précédent, cela est impossible, c'est pour ça que les expressions régulières existent. Cela permet de faire passer une variable de l'URL cible, à l'URL d'arrivée.
Je vais vous expliquer avec un exemple pratique. Reprenons le code précédent : nous avons donc dans l'URL d'arrivée la variable $texte qui a pour valeur "SDZ" . si je veux changer sa valeur? il suffit de changer le contenu de $texte dans l'URL, par exemple : pseudo.php?texte=prout, ce qui donnerait www.monsite.com/pseudo-texte-prout.png.
Pour arriver à ce résultat, il faut utiliser les expressions régulières. Ce qui donne :
Si vous souhaitez plus d'informations sur les expressions régulières et cette redirection (elle est poussée, il y a des livres entiers à son sujet), je vous conseille, en plus des liens donnés au début de ce tutoriel, le tutoriel écrit à ce sujet pour le CMS SPIP (mais qui convient très bien à une utilisation hors SPIP) : La réécriture des URL "à la volée".
Redirection temporaire
Les plus malins d'entre vous auront remarqué que pour toutes les redirections que j'ai présentées, j'ai utilisé les mots définitif et permanent : cela n'est pas pour faire joli, mais parce qu'il y a des redirections temporaires.
Temporaire ? Pour quoi faire ? :euh:
Prenons un exemple pour expliquer : vous réalisez des travaux dans une partie de votre site, et vous désirez de fermer cette partie au public pour la fignoler. Pour être tranquilles, le mieux est d'utiliser une redirection temporaire.
Mais pourquoi s'embêter à utiliser une redirection temporaire alors que les autres feraient l'affaire ?
Il est vrai que moi aussi je me suis posé la question à ce sujet-là, et j'ai eu la chance d'avoir une réponse très rapide auprès d'amis beaucoup plus compétents que moi :) .
Donc, si vous mettez une redirection permanente et qu'un bot de référencement vient pendant qu'il y a la redirection, il va mettre à jour sa base de données et par conséquent, faire perdre le référencement de cette partie :( ; alors que si vous utilisez une redirection temporaire, le moteur ne mettra pas à jour sa base de données et surtout, vous conservera votre référencement :p .
Maintenant que l'on sait à quoi ça sert, il faudrait savoir comment on s'en sert. :D
C'est toujours aussi simple que les autres : on utilise Redirect comme directive, temp comme option de directive et les adresses (la cible et l'URL d'arrivée) ; dans notre exemple, nous utiliserons /zone_en_finition/ comme cible et /zone_temporaire/ comme URL d'arrivée.
Voilà pour ce qui est de la redirection HTTP : c'est très complet et normalement, avec ça et les expressions régulières, vous devriez pouvoir rediriger un bon nombre de personnes.
Si vous avez un problème, n'hésitez pas à demander de l'aide. ;-)
La redirection HTTP Introduction à la syntaxe Changement permanent de nom de domaine Déplacement définitif d'un dossier Déplacement définitif d'un fichier Suppression définitive d'un fichier Changer l'extension d'un fichier Redirection temporaire
La redirection HTTP
Vous venez de déménager votre site ? De changer l'URL d'une / de plusieurs page(s) ? D'un dossier ? Mais malheureusement vous avez peur que vos visiteurs s'affolent s'ils ne trouvent plus la / les pages déplacée(s) ? Que les moteurs de recherche soient perdus ?
J'ai la solution : les redirections.
Je dis les et non la redirections, car il existe plusieurs méthodes de redirection :
la redirection HTTP ;
la redirection HTML ;
la redirection PHP ;
la redirection Javascript.
Comme vous vous en doutez, il y en a de meilleures que d'autres, et c'est pour cela que je vais essayer de toutes les aborder en montrant les points positifs et négatifs de chacune d'elles.
Tout cela se fera sur plusieurs tutoriels ; dans celui-ci, je me contenterai de vous expliquer la redirection HTTP qui est à mon avis la meilleure de toutes. En tout cas, c'est sûrement la plus utilisée.
Avant de commencer, il vous faut savoir une chose : cette redirection fonctionne directement avec Apache.
La majeure partie des serveurs tournent sous Apache, l'autre partie (qui ne tourne pas sous Apache) comprend néanmoins les mêmes fichiers que ceux utilisés sur des serveurs Apache : ça ne pose donc pas de problème, généralement.
.htaccess : mais je connais ça, ce n'est pas le fichier dans lequel on configure les erreurs 40x (400, 401, 402, 403, 404... ) ? :euh:
Très bonne remarque ! C'est effectivement dans le même fichier que l'on fait ces deux manipulations. :)
Pour commencer, je vais vous donner un fichier d'exemple qui va vous montrer les possibilités de la chose. ^^
Oullaaaalaaalaaa... c'est quoi, ce truc ? :euh: :euh:
Ça, c'est un fichier .htaccess avec des règles de redirections complexes (les expressions régulières), mais pas de panique : je ne vais rien vous faire faire d'aussi compliqué !
Introduction à la syntaxe
Chaque ligne d'un fichier .htaccess est une instruction.
On peut décomposer les lignes en quatre parties :
Le changement d'adresse est toujours risqué : il a des risques que le site coule suite à un non-suivi des visiteurs et / ou un déréférencement du site.
On peut palier ce problème avec un type de redirection HTTP très précise.
Voilà comment ça se formule :
Redirect permanent / http://nouvelle.adresse.fr/
Prenons l'exemple sur d'un site personnel qui est hébergé chez free (http://monsite.free.fr) : le webmaster décide de s'acheter un nom de domaine et un hébergement : http://www.monsite.sdz. Il copie donc tout le site de l'ancienne vers la nouvelle adresse, mais pour conserver son référencement, il a mis en place une redirection HTTP du type de celui que nous venons de voir.
C'est le même principe que pour changer l'adresse d'un site, sauf que l'on remplace le sélecteur "/" (qui voulait dire "tout") par le chemin du dossier. :p
Ce qui nous donne pour déplacer http://www.monsite.com/dossier1/ vers http://www.monsite.com/dossier2/ :
Lorsque vous renommez un fichier de votre site, il est souvent utile de mettre une redirection à l'ancien emplacement vers le nouvel emplacement. Pour ce faire, on utilise la même directive de redirection que pour déplacer un dossier : Redirect permanent ; mais on cible un fichier au lieu de cibler un dossier.
Cette technique est utilisée pour indiquer aux visiteurs et aux moteurs de recherche que le fichier n'existe plus (et qu'il ne renaîtra pas) ; par conséquent, ils peuvent se mettre à jour. Cela se fait par l'intermédiaire d'une erreur 410 document n'existe plus.
Ici, on utilise qu'une seule adresse : celle du fichier supprimé (ici : /chemin/de_fichier_supprime.html).
Et comme option de directive, gone. Ce qui donne :
Redirect gone /chemin/du_fichier_supprime.html
Changer l'extension d'un fichier
Le changement d'extension de fichier est sûrement la redirection la plus utilisée. Par exemple sur le SdZ, pour toutes les pages ; si vous regardez l'adresse de ce tutoriel : , en réalité cette page n'est pas un fichier HTML, mais un fichier PHP du genre /tuto.php?variable1=3&variable2=4963&variable3=1.
Revenons à nos moutons.
Pourquoi cacher le nom original d'un fichier ?
Pour deux raisons :
le référencement : les moteurs de recherche n'aiment pas trop les noms de fichiers PHP avec des variables, c'est ce qui est fait ici ;
la génération d'image en PHP : si l'on veut intégrer une image générée par PHP dans un post d'un forum, ou dans une page XHTML, il faut qu'elle ait une extension d'image (c'est-à-dire : .jpg, .jpeg, .gif, .png...), et cette technique permet de cacher le nom de l'image.
Prenons pour exemple le deuxième cas : j'ai créé un fichier pseudo.php qui génère un texte en image ; ce texte est contenu dans la variable $texte qui est récupéré via $GET, ce qui donne un fichier pseudo.php?texte=sdz.
Ce fichier-là ne peut être affiché dans les forums car il faut afficher une image .jpg, .jpeg, .gif, .png. Grâce au changement d'extension de fichier, je peux faire croire aux forums que le fichier pseudo.php?texte=SDZ est une image .png (ou autre). Pour ce faire, je crée un fichier .htaccess avec comme instruction :
Si on utilise $get pour récupérer la variable $texte, c'est pour pouvoir changer de texte facilement, non ? Et là, avec cette technique, c'est impossible.
Oui, vous avez raison : si on utilise $get, c'est bien pour pouvoir changer facilement le texte généré. Et en utilisant le code précédent, cela est impossible, c'est pour ça que les expressions régulières existent. Cela permet de faire passer une variable de l'URL cible, à l'URL d'arrivée.
Je vais vous expliquer avec un exemple pratique. Reprenons le code précédent : nous avons donc dans l'URL d'arrivée la variable $texte qui a pour valeur "SDZ" . si je veux changer sa valeur? il suffit de changer le contenu de $texte dans l'URL, par exemple : pseudo.php?texte=prout, ce qui donnerait www.monsite.com/pseudo-texte-prout.png.
Pour arriver à ce résultat, il faut utiliser les expressions régulières. Ce qui donne :
Si vous souhaitez plus d'informations sur les expressions régulières et cette redirection (elle est poussée, il y a des livres entiers à son sujet), je vous conseille, en plus des liens donnés au début de ce tutoriel, le tutoriel écrit à ce sujet pour le CMS SPIP (mais qui convient très bien à une utilisation hors SPIP) : La réécriture des URL "à la volée".
Redirection temporaire
Les plus malins d'entre vous auront remarqué que pour toutes les redirections que j'ai présentées, j'ai utilisé les mots définitif et permanent : cela n'est pas pour faire joli, mais parce qu'il y a des redirections temporaires.
Temporaire ? Pour quoi faire ? :euh:
Prenons un exemple pour expliquer : vous réalisez des travaux dans une partie de votre site, et vous désirez de fermer cette partie au public pour la fignoler. Pour être tranquilles, le mieux est d'utiliser une redirection temporaire.
Mais pourquoi s'embêter à utiliser une redirection temporaire alors que les autres feraient l'affaire ?
Il est vrai que moi aussi je me suis posé la question à ce sujet-là, et j'ai eu la chance d'avoir une réponse très rapide auprès d'amis beaucoup plus compétents que moi :) .
Donc, si vous mettez une redirection permanente et qu'un bot de référencement vient pendant qu'il y a la redirection, il va mettre à jour sa base de données et par conséquent, faire perdre le référencement de cette partie :( ; alors que si vous utilisez une redirection temporaire, le moteur ne mettra pas à jour sa base de données et surtout, vous conservera votre référencement :p .
Maintenant que l'on sait à quoi ça sert, il faudrait savoir comment on s'en sert. :D
C'est toujours aussi simple que les autres : on utilise Redirect comme directive, temp comme option de directive et les adresses (la cible et l'URL d'arrivée) ; dans notre exemple, nous utiliserons /zone_en_finition/ comme cible et /zone_temporaire/ comme URL d'arrivée.
Voilà pour ce qui est de la redirection HTTP : c'est très complet et normalement, avec ça et les expressions régulières, vous devriez pouvoir rediriger un bon nombre de personnes.
Si vous avez un problème, n'hésitez pas à demander de l'aide. ;-)
Tutoriel : Comprendre les encodages
Table des matières
Comprendre les encodages Un peu de théorie : le texte en informatique La grande épopée des encodages Unicode, la solution ultime Et aujourd’hui ? En pratique : jongler avec les encodages !
Comprendre les encodages
Aux détours de vos aventures informatiques, vous entendez parler de charset, d’encodage, d’ASCII, d’UTF-8, d’ISO-8859, de latin-1… et vous demandez ce que sont ces drôles de bestioles ?
Ce cours vous est destiné. Tout y sera expliqué depuis le début et après l’avoir lu, promis, vous ne serez plus jamais embêtés par ce genre de désagréments.
Un peu de théorie : le texte en informatique
Autant vous le dire tout de suite : tout ce qui sera dit dans ce cours tournera autour d’une même problématique : la façon dont on stocke du texte dans un ordinateur.
Comme vous le savez peut-être, un ordinateur ne peut stocker que des nombres, ou plus précisément des 0 et des 1 (des « bits ») qu’on regroupe pour former des nombres en binaire. Pour plus d’informations sur le binaire et la représentation en mémoire des nombres, je vous invite à consulter ce tutoriel.
Comment fait-on alors pour écrire du texte ? La réponse est toute bête : on associe à chaque caractère (une lettre, un signe de ponctuation, une espace…) un nombre. Un texte est alors une suite de ces nombres, on parle de chaîne de caractères.
Par exemple, on peut décider ceci :
Caractère
A
B
C
…
Z
0
1
2
…
9
.
,
:
?
!
espace
Nombre associé
0
1
2
…
25
26
27
28
…
35
36
37
38
39
40
41
Avec cet exemple fictif, le texte « SALUT LES ZEROS ! » donnerait ceci en mémoire :
S A L U T L E S Z E R O S !
18 00 11 20 19 41 11 04 18 41 25 04 17 14 18 41 40
Comme vous le voyez, on a donné un nombre unique pour chaque lettre de l’alphabet (de A à Z), pour les dix chiffres (de 0 à 9) et pour les signes de ponctuation, sans oublier l’espace.
Cet exemple nous montre comment les informaticiens inventent une façon de coder un texte en mémoire.
Premièrement, on décide de l’ensemble des caractères dont on a besoin, et on assigne à chacun un identifiant numérique unique appelé code. Cet ensemble est appelé jeu de caractères codés (en anglais charset, abréviation de character set) et peut se résumer dans un tableau de correspondance comme ci-dessus.
Ensuite, il faut déterminer l’encodage (encoding), c’est-à-dire la façon de transcrire un texte grâce aux codes des caractères qui le composent, selon un jeu de caractères donné. Le moyen le plus simple est d’écrire directement chaque code (auquel cas on parle de page de code — charmap) ; le jeu et l’encodage sont alors confondus. On a procédé de cette façon dans l’exemple ci-dessus, mais ce n’est pas toujours satisfaisant. C’est pourquoi il faut bien retenir la différence entre jeu de caractères et encodage.
Ça, c’est pour la théorie. Maintenant, place à la pratique ! L’exemple que je vous ai proposé était simple. Trop simple. La réalité est tout autre pour deux raisons principales :
Il y a bien plus de caractères à gérer.
Il y a des caractères particuliers, dits « de contrôle », qui ne servent pas pour un symbole « imprimable » mais donnent des indications aux programmes qui manipulent les chaînes de caractères. Le plus important est le caractère « fin de chaîne » qui sert à indiquer où s’arrête la chaîne (sinon, le programme n’aurait pas de moyen de le savoir et continuerait à lire ce qui se trouve après, ce qui nous vaudrait de belles erreurs).
De plus, il y a aussi les lettres minuscules, que je n’ai pas mis dans mon exemple. Il faudrait aussi pouvoir gérer les accents, les symboles de monnaie… voire, soyons fous, penser aux langues non latines (les Arabes et les Chinois ayant peut-être envie de parler leur langue).
C’est là que ça devient vraiment problématique, comme nous allons le voir.
Il faut aussi considérer les contraintes matérielles. En effet, comme je vous l’ai dit, un ordinateur ne connaît que le binaire. Les bits sont regroupés par groupes de 8 appelés « octets ». Un octet ne peut stocker que les nombres entiers de 0 à 255 (soit 256 = 28 possibilités, pour les matheux). Si cela ne suffit pas, on peut rassembler les octets par 2, 4 ou plus pour avoir de plus grands nombres.
Dans nos encodages, il faudra tenir compte de ces limites, c’est-à-dire s'arranger pour que les codes de notre jeu tiennent tous sur un ou deux octets par exemple.
La grande épopée des encodages
Pour bien cerner les problèmes causés par les encodages et la situation actuelle, le mieux reste encore de retracer leur histoire. En avant !
Au commencement était l’ASCII
Le premier encodage historique est l’ASCII, soit l’American Standard Code for Information Interchange (en français, le code américain normalisé pour l’échange d'informations). C’est une norme américaine, inventée en 1961, qui avait pour but d'organiser le bazar informatique à l’échelle nationale. Ce n’est pas le premier encodage utilisé mais on peut oublier les précédents.
Le terme « ASCII » est employé de manière incorrecte par beaucoup de monde sans savoir ce qu’il désigne réellement.
Le jeu de caractères ASCII utilise 7 bits (et non 8 !) et dispose donc de 128 (27) caractères uniquement, numérotés de 0 à 127. En effet, il est paru à une époque où des regroupements par 7 au lieu de 8 étaient encore assez fréquents.
Sans plus attendre, voici la table de l’ASCII :
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
00
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
10
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
20
SP
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
30
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
40
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
50
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
60
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
70
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
DEL
Hé, mais j’y comprends rien à ton tableau, moi !
Chaque case correspond à l’un des 128 caractères de l’ASCII rangés dans l'ordre.
Pour retrouver le code associé à un caractère, il faut regarder l’en-tête de sa ligne et celui de sa colonne ; il contiennent des valeurs en hexadécimal (si vous ne connaissez pas l’hexadécimal, allez voir cette partie de tutoriel) qu’il faut additionner. Ainsi le caractère Z a pour code hexadécimal 0x50+0xA = 0x5A (soit 90 en décimal).
Regardons un peu ce qu’il y a dans l’ASCII :
les 26 lettres de l’alphabet latin, en majuscules (0x41 — 0x5A) et en minuscules (0x61 — 0x7A), ainsi que les chiffres de 0 à 9 ;
divers signes de ponctuation, et d’autres symboles tels que les crochets, les accolades, l'arrobase… ;
des « caractères blancs », c'est-à-dire l’espace mais aussi d’autres tels que le retour à la ligne (eh oui, c’est aussi un caractère). Ils sont marqués comme ça, en voici la liste :
SP (0x20) : espace (space) ;
HT (0x09) : tabulation horizontale (horizontal tab), le ' ' des programmeurs ;
VT (0x0B) : tabulation verticale (vertical tab) ;
LF (0x0A) : nouvelle ligne (line feed), le ' ' des programmeurs ;
CR (0x0D) : retour chariot (carriage return), le ' ' des programmeurs ; marque la fin d’une ligne ;
FF (0x0C) : nouvelle page (form feed) ;
Notez que LF et CR remplissent des rôles très proches. Sous Windows on utilise une combinaison des deux (CR LF) à la fin de chaque ligne ; sous Linux et Mac OS X, on ne se sert que de LF ; enfin, sous Mac avant Mac OS X, on ne se servait que de CR. Un joyeux bazar !
des caractères de contrôle non imprimables (0x00 — 0x1F, et 0x7F), marqués comme ça ; en voici quelques-uns :
NUL (0x00) : caractère nul (null), le '\0' des programmeurs ; c’est le caractère servant à marquer la fin d’une chaîne de caractères ;
des caractères servant à la communication entre programmes, périphériques ou machines ;
des caractères correspondant à des actions, comme BS (backspace, retour arrière), ESC (escape, échappement) ou CAN (cancel, annulation) ;
d’autres encore.
Un exemple ? Tout d’suite m’dame !
Citation : Texte à encoder
Et l'ASCII survint.
texte : E t l ' A S C I I s u r v i n t .
valeur en ASCII : 45 74 20 6C 27 41 53 43 49 49 20 73 75 72 76 69 6E 74 2E
Les valeurs sont en hexadécimal.
Les 128 caractères de l’ASCII n’ont pas été placés au hasard. Leurs codes ont été soigneusement étudiés. Ci-dessous, quelques exemples pour votre culture.
À l’époque reculée où a été conçu l’ASCII, on communiquait encore parfois des données à l’ordinateur via des cartes perforées. Chaque emplacement codait un bit : 1 s’il y avait un trou, 0 sinon. La perforation était irréversible. Lorsqu'on n’avait pas encore spécifié de caractère particulier, on laissait tous les emplacements intacts et le caractère valait donc 0 (tous les bits à 0). Ce caractère « non spécifié » se retrouve en ASCII avec NUL, le caractère nul, qui vaut 0. De même, lorsqu’on voulait effacer un caractère on perçait tous les emplacements, ce qui donnait 127 (tous les bits à 1) ; le caractère ASCII DEL (delete) correspond justement à cette suppression.
Les lettres majuscules sont séparées de leurs homologues minuscules par un intervalle de 32. Cela signifie qu’il suffit de modifier un bit (le 6e) pour passer des unes aux autres, ce qui simplifie les traitements.
Comme vous voyez, l’ASCII est simple. Il ne comporte que le strict nécessaire pour l'époque, pour utiliser un ordinateur… en anglais. Que les 26 lettres de l’alphabet latin de base, pas d’accents, etc. Vous vous en doutez certainement, les autres pays ont voulu pouvoir utiliser leur propre langage correctement.
La révolte gronde
C'est pourquoi des extensions de l’ASCII sont apparues.
Certaines gardent la base ASCII et utilisent le 8e bit laissé libre afin d'avoir plus de caractères à disposition (deux fois plus, 256 = 28 au total). Ainsi, les codes de 0 à 127 correspondent encore aux caractères ASCII, tandis que les codes supérieurs (de 128 à 255, c’est-à-dire ceux avec le 8e bit valant 1) servent pour les nouveaux caractères.
D’autres restent sur 7 bits, et modifient carrément les 128 caractères de l’ASCII pour leur propres besoins.
Vous imaginez la pagaille monstrueuse que ça a été, lorsque chaque pays ou groupe linguistique s’est mis à éditer sa propre page de code. Ça fonctionnait bien tant que les documents ne quittaient pas la zone où leur propre encodage était en usage, mais les échanges internationaux étaient sujets à problèmes. Comme un même code signifiait des caractères différents d’un jeu à l'autre, le récepteur ne lisait pas la même chose que le destinateur. Par exemple, le symbole du dollar ($) aux États-Unis devenait celui de la livre (£) au Royaume-Uni : dégâts assurés !
Il y a bien eu des tentatives de stopper la multiplication des pages de code, mais globalement elles ont été insuffisantes.
En 1972, la norme ISO 646 a défini une page de code sur 7 bits dérivant de l’ASCII, avec des caractères fixes (principalement les lettres majuscules et minuscules, les chiffres et la ponctuation principale), les autres caractères étant laissés au choix. Cette norme, qui devait permettre une certaine compatibilité et un semblant d’ordre, a donné naissance à un certain nombre de pages de code nationales, mais elle n’était pas adaptée aux langues autres que latines et ne permettait pas de représenter assez de caractères.
ISO 8859 : 8 bits pour les langues latines
Plus tard, une norme mieux pensée a fait son apparition : la norme ISO 8859. Cette fois, elle utilise 8 bits donc 256 caractères au maximum. Le standard ISO 8859 comporte en fait plusieurs « parties », c’est-à-dire des pages de code indépendantes, nommées ISO 8859-n où n est le numéro de la partie.
ISO 8859 a été pensée afin que les parties soient le plus largement compatibles entre elles. Ainsi, elle englobe l’ASCII (codes 0 à 127) comme base commune, et les codes 128 à 255 devaient accueillir les caractères propres à chaque page de code, en s'arrangeant pour que des caractères identiques ou proches d’une page à l’autre occupent le même code.
Ce standard a principalement servi aux langues latines d’Europe pour mettre au point une page de code commune. À elles seules, elles utilisent finalement 10 parties d’ISO 8859, parfois appelées latin-1, latin-2, etc. ; ces parties correspondent à des évolutions dans la page de code latine de base (latin-1, ou officiellement ISO 8859-1) afin de rajouter certains caractères pour compléter des langues. En voici deux que vous devriez connaître :
ISO 8859-1 (latin-1 ou « Occidental ») est un encodage très courant dans les pays latins et sur la toile. C’est en effet celui qu’utilisent Linux et de nombreux documents et pages web. Les systèmes Windows utilisent également un jeu proche, comme on le verra bientôt. Il a l’avantage de permettre d’écrire grosso modo toutes les langues latines, et ceci avec des caractères d’un octet seulement.
ISO 8859-15 (latin-9 ou « Occidental (euro) »), datant de 1998, introduit le signe de l’euro (€) et complète le support de quelques langues dont le français (avec Œ) en abandonnant des symboles peu utilisés (dont le mystérieux ¤ signifiant « monnaie »). Il est néanmoins peu utilisé par rapport à son grand frère ci-dessus.
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
00
⋮
70
ASCII (sauf les caractères de contrôle, non utilisés)
À nouveau un exemple, avec cette fois des caractères accentués et autres (oui, je suis poète) :
Citation : Texte à encoder
« Ô âme oubliée ! »
texte : « ▒ Ô â m e o u b l i é e ▒ ! ▒ »
valeur en latin-1 : AB A0 D4 20 E2 6D 65 20 6F 75 62 6C 69 E9 65 A0 21 A0 BB
Notez l’emploi d’espaces insécables (symbolisés par ▒ pour qu’on les voit) avant le point d’exclamation et entre les guillemets, conformément aux règles typographiques. :)
Les codes de 0x00 à 0x1F et 0x7F (les caractères de contrôle ASCII) et de 0x80 à 0x9F sont laissés inutilisés par le standard ISO 8859. Pour les communications Internet, l’IANA a créé la norme ISO-8859 (attention, c'est le tiret qui change tout !). Celle-ci reprend toute la norme ISO 8859 et y rajoute des caractères de contrôle aux emplacements libres.
Windows s’est aussi basé sur latin-1 pour mettre au point son nouveau jeu de caractères occidental dans les années 1990. Windows-1252 (ou CP1252, parfois dit ANSI à titre officieux) est maintenant le jeu utilisé dans les systèmes Windows occidentaux (donc probablement chez vous), et remplace les anciennes pages de code (la page de code 437 pour les États-Unis, et la 850 pour l’Europe). Il reprend tous les caractères d’ISO 8859-1 et utilise les codes libres (de 0x80 à 0x9F) pour des caractères supplémentaires.
ISO 8859 a aussi été utilisé pour l’alphabet cyrillique (ISO 8859-5), l’arabe (ISO 8859-6), le grec (7) l’hébreu (8) et même le thaï (11).
Il existe au total 16 parties et il n’y en aura pas plus. En effet, on privilégie désormais le développement de l’Unicode.
ISO 2022 : du multi-octet pour les langues asiatiques
Pendant ce temps-là, en Asie…
Les langues latines s’en sont plutôt bien sorties finalement. Elles ont réussi à ne pas dépasser la limite fatidique de l’octet, ce qui restait quand même le plus pratique pour les traitements (et la consommation mémoire). Mais les langues asiatiques comme le japonais, le coréen ou le chinois disposent de bien trop de caractères pour que tout tienne sur 8 bits. Les encodages mis au point en Asie de l'Est ont donc franchi le saut du multi-octet. Certains utilisaient 2 octets, ce qui permet 65 536 (216) codes différents.
Comme pour les langues latines, un standard a été mis au point pour les organiser, on l’appelle ISO 2022. C’est un concept un peu spécial. Il permet de jongler entre plusieurs pages de code à l’aide de « séquences d’échappement » codées sur 3 octets (parfois 4) et commençant par le caractère ASCII ESC (0x1B) ; celles-ci indiquent aux programmes quelle page de code il faut utiliser pour interpréter ce qui suit. Les différentes pages de codes sont totalement indépendantes et peuvent utiliser un octet ou deux par caractère.
ISO 2022 a été utilisé pour le chinois (ISO 2022-CN), le coréen (ISO 2022-KR) et le japonais (ISO 2022-JP). Ces encodages, surtout le japonais, restent encore très répandus même si l’Unicode se développe.
Unicode, la solution ultime
Avec des normes comme ISO 8859 ou ISO 2022, on commençait à s’en tirer pas trop mal. Les problèmes sont atténués, mais subsistent (et si vous rédigez un document en français mais voulez y insérer de l’arabe ?). Finalement, des illuminés se sont dit : « Et si on créait un jeu de caractères unique pour tout le monde ? » De cette idée toute simple sont nés deux monuments : le standard ISO 10646 et Unicode.
Le Jeu universel de caractères
ISO 10646 voit le jour en 1990. Il s’agit du Jeu universel de caractères ou JUC (en anglais, UCS pour Universal Character Set). Celui-ci a été pensé pour pouvoir accueillir n’importe quel caractère existant de n’importe quelle langue du monde. Un travail titanesque ! Concrètement, c’est un bête jeu de caractères, sauf que celui-ci offre pas moins de 221 = 2 097 152 codes ! À l’origine, il allait même jusqu’à 232 = 4 294 967 296, mais il a rapidement été restreint : c’est déjà bien suffisant.
Actuellement, environ 17% des codes sont déjà attribués à des caractères. Comme vous le voyez, il nous reste encore de la place à revendre. Et pourtant, dans ces 17%, on a tout mis ou presque : les caractères de tous les anciens jeux, tous les alphabets modernes, pléthore de symboles…
Le JUC n’est peut-être pas la solution définitive et éternelle (en informatique, il ne faut jamais dire « jamais »), mais il s’en rapproche suffisamment pour qu’on dorme sur nos deux oreilles pendant le siècle à venir. :)
Devant une telle quantité, les polices d’écriture (qui n’ont rien à voir avec les encodages, il s’agit ici d’affichage des caractères et non de leur codage en mémoire) peinent à suivre. C’est ce qui explique les petits symboles du type
que vous pouvez voir avec un peu de chance sur certaines pages (si vous regardez bien, vous constaterez que dans le carré est inscrit le code hexadécimal du caractère). ;) Généralement, les auteurs de polices se contentent de créer les glyphes des parties qui les intéressent (et éventuellement recopient les glyphes de référence pour le reste) ; si vous avez vraiment besoin de rédiger une partition suivant la notation musicale grecque ancienne avec le JUC, vous utiliserez une police spécialisée.
Bon à savoir : par commodité et souci de compatibilité, le JUC reprend ISO-8859-1 (latin-1 avec les caractères de contrôle) pour ses 256 premiers caractères (donc inclut également l’ASCII).
Ce jeu n’est pas définitif : de nombreux caractères sont régulièrement créés et assignés à des codes encore libres. Rassurez-vous, les caractères déjà en place ne bougent plus.
logo d’Unicode
Unicode
Unicode est une norme développée par le Consortium Unicode publiée pour la première fois en 1991 (en 2011, elle en est à la version 6.1). On peut la voir comme une surcouche (une extension) d’ISO 10646. En fait, les deux normes sont développées parallèlement et synchronisées en permanence. Là où ISO 10646 liste simplement les caractères du jeu et leur assigne un nom et un code, Unicode va plus loin en leur ajoutant des attributs et en décrivant des relations entre eux (donc en leur donnant un sens). C’est un peu complexe et pas forcément intéressant ici, donc je ne m’étendrai pas dessus.
Unicode, c’est cependant plus que cela. Ce standard décrit également des algorithmes de traitement, notamment pour la gestion des différents sens d’écriture, et surtout, ce qui nous intéresse ici, des encodages permettant de transcrire le JUC.
Un jeu, des encodages
Des encodages ? Mais, euh… Je croyais qu’Unicode était un encodage ?
Unicode est basiquement un jeu de caractères (un ensemble de caractères auxquels on attribue à chacun un point de code unique) et non un encodage (façon de représenter ce point de code en mémoire). C’est ici que la distinction prend tout son sens. Auparavant, les deux se confondaient puisque tous les jeux de caractères étaient associés à un encodage simple : vu que leur codes tenaient sur un ou deux octets, on se contentait de les écrire tels quels en mémoire.
Or, les points de codes d’Unicode nécessitent beaucoup plus qu’un octet : il leur en faudrait quatre ! Cela voudrait dire que si l’on continuait à faire comme avant, on utiliserait 4 fois plus de mémoire qu’avec nos jeux précédents tenant sur un octet, comme ISO 8859.
Des petits malins me diront que trois octets suffiraient car on aurait alors 3×8=24 bits disponibles ; c’est vrai maintenant que le jeu a été réduit à 221 codes, mais en informatique, pour des raisons techniques, on préfère des tailles multiples de 2.
Ce serait un gaspillage de mémoire trop important, d’autant plus qu’il paraîtrait inutile. En effet, il y aurait plein d’octets qui vaudraient zéro :
Codes
Encodage selon UTF-32
Caractères disponibles dans cet intervalle
jusqu’à U+00FF (28-1)
00000000 00000000 00000000 bbbbbbbb
langues occidentales (latin-1)
jusqu’à U+FFFF (216-1)
00000000 00000000 bbbbbbbb bbbbbbbb
la plupart des alphabets actuellement
utilisés dans le monde
jusqu’à U+10FFFF (221-1)
00000000 000bbbbb bbbbbbbb bbbbbbbb
n’importe quel caractère
Vous le voyez, il y aurait toujours au moins un octet nul. Le cas extrême est celui d’un Occidental qui gaspille 3 octets par caractère.
UTF-16
Pour faire des économies, on a donc mis au point des encodages plus futés. Tout d’abord, il y a l’UTF-16 (UCS transformation format, 16 bits). Celui-ci code les 216 = 65 536 premiers caractères sur 2 octets, et les codes supérieurs sont représentés sur 4 octets par le biais d’une petite transformation mathématique. Le 16 dans son nom indique le nombre minimal de bits nécessaires pour un caractère.
Les caractères de cet encodage ne font donc pas tous la même taille, ce qui complique un poil les traitements (même s’il est facile de distinguer un caractère sur 2 octets d’un caractère sur 4).
De plus, on a une difficulté technique supplémentaire pour l’UTF-16 (et l’UTF-32) : le boutisme (endianness). Ce terme mystique désigne l’ordre dans lequel sont « rangés » les octets d’un nombre multi-octet. Il en existe deux sortes principales : le gros boutisme (big-endian, BE) et le petit boutisme (little-endian, LE).
Le problème, c’est que le boutisme dépend des machines et que ces deux-là sont très répandus. Or en UTF-16 on lit les données par groupes de 2 octets, donc le boutisme influe sur le résultat : si l’on lit du texte UTF-16 envoyé par quelqu’un utilisant un boutisme différent du sien, c’est l’erreur assurée !
Pour pallier à cela, on utilise parfois un caractère spécial appelé BOM (byte order mask, marque d’ordonnancement des octets). l’IANA a aussi autorisé deux déclinaisons de l’encodage pour les communications Internet qui permettent de préciser le boutisme employé : UTF-16BE et UTF-16LE.
Reprenons le texte d’exemple de tout à l’heure et encodons-le cette fois en UTF-16 :
Remarquez que ce texte en UTF-16 s’encode exactement comme en latin-1, avec des valeurs sur 2 octets au lieu d’un (donc un octet sur deux valant 0). On occupe donc deux fois plus de mémoire.
UTF-8
On a aussi inventé l’UTF-8. La taille des caractères codés est encore plus variable, et l’économie de mémoire plus grande. Comme vous l’avez deviné, le nombre minimal de bits est 8. En fait, il représente les premiers caractères (ceux de l’ASCII) sur un octet, les suivants sur 2 octets, 3 et jusqu’à 4 octets.
En plus, cet encodage est compatible avec l’ASCII : les caractères sont codés exactement de la même manière en UTF-8 et en ASCII. Ajoutez à cela que l’encodage a été conçu afin que certains algorithmes de traitement (comparaison de texte par exemple) soient réutilisables sans modification. Ainsi, de vieux programmes qui n’ont pas été conçus pour un autre encodage que l’ASCII fonctionneront aussi si on leur passe du texte en UTF-8 : magique !
Enfin, contrairement à l’UTF-16, on n’a pas de problème de boutisme puisqu’on lit les données octet par octet. :)
Bref, UTF-8 a de nombreux avantages (économie de mémoire, compatibilité, boutisme, résistance aux erreurs…). Un défaut aussi : la grande variabilité de taille des caractères qui rend les traitements plus compliqués et moins performants. Il n’empêche que ses point forts lui ont assuré un grand succès : il est sans doute l’encodage le plus répandu aujourd’hui. Il est utilisé pour les documents et les communications, et les systèmes d’exploitation (Mac et GNU/Linux) s’y mettent aussi.
Pour ne pas changer, exemple de texte en UTF-8 :
Citation : Texte à encoder
« Ô âme oubliée ! »
texte : «____ ▒____ Ô____ â____ m e o u b l i é____ e ▒____ ! ▒____ »____
valeur en UTF-8 : C2-AB C2-A0 C3-94 20 C3-A2 6D 65 20 6F 75 62 6C 69 C3-A9 65 C2-A0 21 C2-A0 C2-BB
Constat flagrant, la consommation de mémoire est singulièrement réduite par rapport à UTF-16. :D On voit de plus que les caractères de base sont codés exactement comme en ASCII, et les caractères supérieurs s’étendent sur plusieurs octets (ici symbolisés par « __ »). Ici, vu qu’on reste dans les caractères latins, ça ne dépasse jamais deux octets, mais ça peut aller jusqu’à 4.
Et aujourd’hui ?
Hop, notre périple au fil des âges, sur la piste des encodages, nous a ramené au temps présent ! ASCII, ISO 8859, UTF-8… Il est grand temps de dresser le bilan. Que retenir de tout ça ?
Le principe du stockage de texte en informatique : jeux de caractères et encodages (bien retenir la distinction).
Qu’un caractère n’est pas un octet. Ni même un nombre fixe d’octets. Programmeurs, fourrez-vous ça dans le crâne et tenez-le vous pour dit.
Les principaux encodages : ASCII, ISO 8859-1, UTF-8, pour n’en donner que trois.
Leurs usages actuels.
Les encodages actuels
On va tout de suite détailler le dernier point !
Avant l’apparition d’Unicode, les systèmes d’exploitation fonctionnaient avec un système de pages de code régionales, c’est-à-dire qu’on utilisait des variantes d’encodage sur 8 bits en fonction du pays. Depuis, ils ont migré vers Unicode en interne (y compris Windows, depuis XP, même si ça ne se répercute par forcément pour l’utilisateur).
Sous Windows, UTF-16 (little endian) est maintenant utilisé en interne et UTF-8 est également supporté, mais par compatibilité Unicode cohabite avec les pages de code. Ces dernières, incorrectement appelées « ANSI » et proches des ISO 8859, sont encore fréquemment utilisées. Je vous rappelle que celle pour nous autres occidentaux (Europe de l’Ouest et Amérique du Nord) est Windows-1252(« CP1252 ») et dérive de latin-1. Celles-ci ont remplacé les anciennes pages de code dites « OEM » (CP437 et CP850 pour l’Occident), dont l’usage demeure toutefois pour la console.
Sous Mac OS, l’encodage en vigueur en Occident était nommé MacRoman, mais depuis Mac OS X on utilise UTF-8.
Les distributions GNU/Linux utilisaient latin-1 par défaut. Certaines l’utilisent toujours, tandis que les autres adoptent progressivement UTF-8 (maintenant majoritaire).
Il est bien sûr possible, avec les bons outils, d’encoder un fichier de n’importe quelle façon, sous n’importe quel système d’exploitation. L’encodage utilisé par un OS est celui utilisé par défaut dans le fonctionnement des programmes. Les outils intégrés à un OS (la console de Windows, par exemple) ou fournis avec auront donc une préférence pour cet encodage. Cela influe donc sur l’encodage des documents (puisqu’un utilisateur de base ne s’en souciera pas).
De plus, UTF-8 est devenu l’un des encodages les plus utilisés sur la Toile (pour les pages Web), ce qui semble logique puisqu’il s’agit d’un réseau international mettant en contact toutes les langues. L’autre principal encodage sur Internet reste latin-1.
Comme vous voyez, l’ASCII seul n’est plus employé, mais tous les encodages répandus conservent la base ASCII par compatibilité. Les trois principaux, cités ci-dessus, se basent même tous sur latin-1 (même si l’UTF-8 n’est pas compatible avec ce dernier puisqu’un codet de 8 bits sera encodé sur 2 octets).
Détection de l’encodage
Un problème posé par la diversité des encodages existants est la détermination de l’encodage utilisé par un fichier. Les renseignements associés à un fichier particulier (sa date de création par exemple) n’indiquent rien sur son encodage. On doit donc tenter de le « deviner », au moyen d’algorithmes compliqués qui analysent le contenu du fichier. Ces algorithmes sont efficaces la plupart du temps, mais peuvent échouer, et sont compliqués.
C’est ce qui explique les affichages bizarres de certains fichiers ou pages web : le programme n’a pas réussi à déterminer le bon encodage.
Un moyen plus simple serait d’inclure cette indication directement dans le contenu du fichier, au tout début (afin de diminuer les risques de perturbation). On utilise pour cela le fait que tous les encodages actuels soient compatibles avec l’ASCII. C’est ce qu’on verra tout à l’heure pour les pages HTML.
En pratique : jongler avec les encodages !
Vous n’êtes pas lassé de toutes ces connaissances à ingurgiter ? Rassurez-vous, on va s’arrêter là pour pratiquer un peu. :) Il est important de savoir tout ça, mais c’est encore mieux de savoir le mettre à profit !
Manipuler des documents
Lorsqu’on consulte un document, que ce soit un fichier texte (code source par exemple) ou une page web, il faut la lire avec le bon encodage. Sinon, les valeurs seront mal interprétées. Exemple ?
Voici un texte encodé en UTF-8 :
Citation : Texte encodé en UTF-8
Bonjour, amis Zéros !
Si vous le lisez en latin-1, vous obtiendrez ceci :
Citation : Texte encodé en UTF-8 mais interprété comme du latin-1
Le problème se pose même si tous les caractères font la même taille dans les deux encodages, une même valeur pouvant désigner deux caractères différents d’un encodage à l’autre.
Consulter une page web (avec un navigateur)
La plupart du temps, vous n’aurez pas à vous soucier de l’encodage pour lire une page web. Normalement, celui-ci est en effet précisé dans le code source. Il arrive toutefois que ce ne soit pas fait, ou mal fait, et que votre navigateur (Internet Explorer, Firefox…) échoue à le deviner. Par exemple : Exemple de page web lue (avec Firefox) avec un mauvais encodage − exemple bien sûr simulé !
C’est moche. C’est désagréable à lire. Heureusement, vous pouvez y remédier manuellement. Tout navigateur qui se respecte offre un menu permettant de jongler entre les encodages. Vous devriez trouver sans trop de difficultés. Pour Firefox par exemple, il est caché dans le menu « Affichage » : Menu des encodages dans Firefox
Pour l’instant, par défaut, le navigateur est en « détection automatique », ce qui a conduit à l’utilisation incorrecte d’ISO-8859-1 (latin-1). On peut en changer. Ici, la page est probablement en UTF-8 (ça ressemble à l’erreur qu’on a vue en introduction), donc on essaie cet encodage. On choisit l’option correspondante dans le menu, et… Tadaam !
La page s’affiche correctement. Vous avez fait du beau boulot. :)
Travailler sur un fichier (avec un éditeur de texte)
On va maintenant voir comment gérer l’encodage de nos fichiers. Tout éditeur de texte qui mérite d’être appelé ainsi nous permet de le faire de façon précise.
Commençons par un cas d’école : le Bloc-Notes de Windows. Si vous êtes sous Windows, ouvrez le Bloc-Notes, tapez un peu de texte avec des accents, puis enregistrez. Boîte de dialogue d’enregistrement du Bloc-Notes, avec choix de l’encodage
Comme vous voyez, le Bloc-Notes permet au premier enregistrement de choisir l’encodage du fichier. Le choix est assez limité cependant : « ANSI » (Windows-1252, l’encodage par défaut sous Windows, je vous le rappelle), « Unicode » et « Unicode big endian » (qui désignent en fait l’UTF-16 avec les deux boutismes possibles), ou UTF-8.
Comme exercice, vous pouvez vous amuser à vérifier que les tailles des fichiers affichées sur ma capture sont correctes, sachant que mon texte comporte 15 caractères et que le Bloc-Notes rajoute automatiquement une BOM pour tous les encodages Unicode (qui fait 2 octets en UTF-16 et 3 octets en UTF-8).
Le Bloc-Notes est vraiment un éditeur très basique, et ses fonctionnalités sont limitées. Ainsi on ne peut pas choisir le latin-1 par exemple. De plus, rien n’indique l’encodage du fichier sur lequel on travaille, et on ne peut pas en changer après coup.
Si vous faites de la programmation ou autre, vous utilisez certainement un éditeur plus avancé (je l’espère pour vous). Comme les navigateurs web, la plupart incluent un menu pour passer d’un encodage à un autre. Toujours sous Windows, voici l’exemple de Notepad++ (ici j’ai rouvert les fichiers que je viens de créer avec le Bloc-Notes) : Le menu des encodages dans Notepad++
Déjà, première remarque, Notepad++ détecte automatiquement l’encodage du fichier ouvert et l’indique dans la barre de statut (en bas, encadré en bleu). C’est tout de suite mieux. :)
Au passage, remarquez la mention « Dos\Windows » à gauche de cette indication. Elle indique le style utilisé pour les fins de ligne. Souvenez-vous, on avait vu qu’il existait plusieurs façon de coder une fin de ligne, selon les OS. Cette mention indique que notre fichier utilise le style Windows, c’est-à-dire CR LF.
Ensuite, comme vous voyez, le menu « Encodage » permet de changer en direct l’encodage utilisé. les options « Encoder en xxx » ont le même effet que pour les navigateurs web (elles changent l’interprétation des octets déjà existants) ; elles influent en plus sur l’écriture (l’encodage des nouveaux caractères qu’on écrit).
Pour modifier l’encodage d’un fichier, il ne faut pas cliquer sur « Encoder en xxx », car cela ne convertit pas le contenu existant pour l’adapter au nouvel encodage. Pour ça, il faut faire « Convertir en xxx ». ;)
Enfin, vous constatez qu’on a quand même un choix d’encodages plus vaste que dans le Bloc-Notes !
Après cet aperçu, faites un tour dans la configuration de votre éditeur. Il y a certainement des options qui nous intéressent. Fenêtre de configuration de Notepad++ (paramètres relatifs à l’encodage)
Ici, j’ai encadré la partie intéressante en vert. Je peux choisir l’encodage qui sera utilisé par défaut lors de la création d’un nouveau fichier (ainsi que le format des fins de ligne, ce dont je vous parlais tout à l’heure).
Avec ou sans BOM ?
Remarquez qu’il y a deux encodages UTF-8. o_O L’une porte la mention « (sans BOM) », ce qui signifie que l’autre est un « UTF-8 avec BOM ». Si vous vous rappelez bien, la BOM est un caractère Unicode spécial qui permet d’indiquer le boutisme d’un fichier. Elle se place au tout début de ce fichier. Cette technique est utilisée pour l’UTF-16 (et l’UTF-32). En revanche, elle est inutile en UTF-8 puisqu’on n’a pas de problème de boutisme. Pire, elle peut rendre des fichiers invalides lorsqu’ils sont lus par certains programmes. C’est par exemple le cas des pages web, comme on verra plus tard.
Pourtant, certains éditeurs dont le fameux Bloc-Notes la rajoutent automatiquement même en UTF-8, car ça les aide à détecter l’encodage du fichier. C’est une pratique déconseillée. Dans votre éditeur favori, choisissez toujours la version sans BOM si vous avez le choix.
Ici, je vais nettoyer mon fichier de cette hérésie avec Notepad++. Pour ça, je fais simplement « Convertir en UTF-8 (sans BOM) » et j’enregistre. Dans les paramètres de mon éditeur (cf. ci-dessus), je choisis aussi l’UTF-8 sans BOM par défaut.
Écrire des documents (HTML, LaTeX, etc.)
Lorsque vous codez certains documents destinés à être lus et interprétés par un programme (page web HTML, document LaTeX…), il vous faut en plus préciser à ce programme l’encodage du fichier.
HTML (pages web) et XML
Pour les pages HTML, il existe un champ dans l’en-tête HTTP fourni par le serveur :
Content-Type: text/html; charset=‹ENCODAGE›
Vous voyez d’ailleurs que cet en-tête fournit aussi le type MIME du document (page HTML, fichier CSS, script JavaScript…).
Cette technique est toutefois peu utilisée, car elle nécessite un serveur (ce qui n’est pas le cas si vous consultez un document local), et rend compliqué le fait de fournir sur le même serveur des fichiers avec des encodages différents (par exemple un serveur mutualisé où chacun est libre de choisir son encodage). À la place, on renseigne donc l’encodage… directement dans le fichier HTML. Ça semble bizarre vu que justement, en théorie, on ne peut pas encore lire le fichier. Mais la base ASCII vient à notre secours : quel que soit l’encodage, si on n’utilise que les caractères de l’ASCII, on pourra lire sans problème. :)
L’information à fournir est sous la forme d’une balise <meta http-equiv /> (dans le <head/>) qui est l’équivalent de l’en-tête HTTP.
Vous devez la placer en toute première dans le <head/> afin de ne pas perturber la détection, et parce que le navigateur recommence depuis le début dès qu’il l’a lue. De plus, ne mettez rien de plus que nécessaire au-dessus, pas même un commentaire. Seuls des caractères ASCII doivent précéder cette ligne (et gardez à l’esprit que l’UTF-8 doit être utilisé sans BOM !).
Mauvais exemple (il y a des caractères non-ASCII dans le commentaire) :
<html>
<head>
<!-- Ligne nécessaire pour spécifier l’encodage : -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
…
Vous pouvez trouver ici la liste des noms d’encodage que vous pouvez mettre à la place de ‹ENCODAGE› (insensibles à la casse). Les plus intéressants pour vous sont « ISO-8859-1 » (ou « latin-1 ») et « UTF-8 ». Simple !
Pendant qu’on y est, notez qu’il existe sur le SdZ un tutoriel complet pour migrer son site web de latin-1 vers UTF-8. ;)
Dans les langages de type XML en général (dont HTML), il est possible de spécifier l’encodage autrement. Il peut être renseigné dans le prologue XML, une sorte de « balise » spéciale optionnelle (vous savez, c’est celle qui fait <?xml … ?>), qui doit être placée sur la toute première ligne du fichier.
<?xml version="1.0" encoding="‹ENCODAGE›" ?>
LaTeX (documents mis en forme)
L’encodage est très important avec LaTeX. Comme en HTML, il faut déclarer avec quel encodage est enregistré le fichier en le précisant en paramètre du package inputenc :
\usepackage[‹ENCODAGE›]{inputenc}
(« latin1 » ou « utf8 » pour les plus courants). Les fichiers éventuellement inclus avec la commande \input doivent être enregistrés avec le même encodage, mais il n’y a pas besoin de le déclarer à nouveau.
Programmer
Lorsque vous créez un programme, il faut bien sûr faire attention à toutes ces histoires d’encodages pour que le programme fonctionne bien en fonction de ce qu’on lui passe comme texte.
Bas niveau : le langage C
Commençons par le « maître langage », le C. Le C est bas niveau, et ne nous cache donc rien de toutes ces questions. En C, on manipule directement les bytes, avec le type char. Il y a également le type wchar_t permettant d’après la norme de stocker tout caractère du jeu dit « étendu ».
La gestion des encodages en C de façon portable est excessivement compliquée si l’on se contente de la bibliothèque standard. En effet, la norme met à disposition des fonctions de conversion entre char et wchar_t, mais laisse à l’implémentation le choix des encodages utilisés pour ces deux types…
Cette difficulté s’explique par le fait que le C est un vieux langage, inventé dans les années 70, lorsqu’on n’utilisait encore que des encodages sur un byte (l’ASCII, ou à la rigueur des pages de code). Tout était plus simple. Avec le développement de jeux plus complexes, il a fallu adapter la norme pour supporter les caractères « multibyte ». Le résultat tient presque de la bidouille et est difficilement exploitable, ou en tout cas fastidieux. On obtient une soupe de « locales », de « caractères larges » (wide characters, le type wchar_t), de « caractères multibyte » (le type char) et d’« états de conversion », le tout dépendant de l’implémentation…
Cette complexité supplémentaire alliée à l’ignorance des programmeurs n’aide pas à changer les habitudes ; beaucoup continuent à croire qu’« un char égale un caractère », ce qui est faux, archifaux.
En plus, non content de faire attention au fonctionnement interne du programme, il faut aussi se préoccuper du format du texte que le programme reçoit en entrée et de celui qu’il produit en sortie. Sans parler de l’affichage en console… :diable:
Bref, pour avoir le même résultat sous tous les OS et éviter de nombreuses prises de tête, il peut être avisé d’utiliser une bibliothèque tierce (ou vous en coder une basique, ce qui fait un bon exercice). Je vous recommande la bibliothèque ICU qui est extrêmement complète et prend en charge toutes les fonctionnalités Unicode. ;)
Je ne m’étendrai pas plus sur le sujet, qui nécessiterait un cours entier. Si vous êtes intéressés, renseignez-vous sur les notions évoquées ci-dessus.
Haut niveau
Les langages de haut niveau, c’est bien connu, cachent au programmeur les détails vilement matériels qui n’intéressent personne. Certains gèrent donc tout seul le bazar, pour notre plus grand bonheur. Tout ce qu’on a à faire, c’est lire et écrire du texte, sans se soucier du nombre d’octets qu’occupe un caractère, de l’encodage utilisé…
Par exemple, la classe String de Java utilise l’UTF-16. De plus, des fonctionnalités supplémentaires pour contrôler plus finement l’Unicode sont fournies par le packageJava.text.
Ouf !
Alors ? Toujours en vie ? Ça fait un gros pavé à lire mais ce n’est pas bien sorcier, et surtout… qu’est-ce que c’est bien une fois qu’on sait tout ça ! On comprend enfin ce qui se passe de l’autre côté de l’écran et les « caractères spéciaux » ne font plus si peur, hein, avouez ? :p
Ce que vous venez d’apprendre est super-méga-important dès que vous commencez à bidouiller un peu sur votre PC. Comme le dit Joel (cf. plus bas), c’est « ce que tout programmeur doit savoir ». Malheureusement, tout programmeur ne le sait pas, et les ignorants sont même nombreux. C’est ce qui explique de nombreux messages de demande d’aide sur les forums du SdZ, et ce qui a motivé l’écriture de ce cours, dans l’espoir qu’il fera progresser les choses dans le bon sens.
Liens
Vous voulez encore de la lecture ? Vous allez en avoir !
Tout d’abord, quelques cours intéressants sur le sujet :
Ensuite, Wikipédia sait tout et voit tout. Elle est très bien fournie sur ce thème (et n’hésitez pas à aller voir les articles anglais qui sont souvent plus complets). Vous pouvez par exemple consulter l’article « Codage de caractères », ou un comparatif des encodages Unicode (en anglais). Si vous avez besoin de connaître la valeur d’un caractère dans un encodage particulier, elle fournit toutes les tables intéressantes de façon claire (quelques exemples : ASCII, CP850, latin-1).
Et même le JUC y est détaillé de façon systématique et bien organisée (pas sur une seule page, évidemment). ;)
Comprendre les encodages Un peu de théorie : le texte en informatique La grande épopée des encodages Unicode, la solution ultime Et aujourd’hui ? En pratique : jongler avec les encodages !
Comprendre les encodages
Aux détours de vos aventures informatiques, vous entendez parler de charset, d’encodage, d’ASCII, d’UTF-8, d’ISO-8859, de latin-1… et vous demandez ce que sont ces drôles de bestioles ?
Ce cours vous est destiné. Tout y sera expliqué depuis le début et après l’avoir lu, promis, vous ne serez plus jamais embêtés par ce genre de désagréments.
Un peu de théorie : le texte en informatique
Autant vous le dire tout de suite : tout ce qui sera dit dans ce cours tournera autour d’une même problématique : la façon dont on stocke du texte dans un ordinateur.
Comme vous le savez peut-être, un ordinateur ne peut stocker que des nombres, ou plus précisément des 0 et des 1 (des « bits ») qu’on regroupe pour former des nombres en binaire. Pour plus d’informations sur le binaire et la représentation en mémoire des nombres, je vous invite à consulter ce tutoriel.
Comment fait-on alors pour écrire du texte ? La réponse est toute bête : on associe à chaque caractère (une lettre, un signe de ponctuation, une espace…) un nombre. Un texte est alors une suite de ces nombres, on parle de chaîne de caractères.
Par exemple, on peut décider ceci :
Caractère
A
B
C
…
Z
0
1
2
…
9
.
,
:
?
!
espace
Nombre associé
0
1
2
…
25
26
27
28
…
35
36
37
38
39
40
41
Avec cet exemple fictif, le texte « SALUT LES ZEROS ! » donnerait ceci en mémoire :
S A L U T L E S Z E R O S !
18 00 11 20 19 41 11 04 18 41 25 04 17 14 18 41 40
Comme vous le voyez, on a donné un nombre unique pour chaque lettre de l’alphabet (de A à Z), pour les dix chiffres (de 0 à 9) et pour les signes de ponctuation, sans oublier l’espace.
Cet exemple nous montre comment les informaticiens inventent une façon de coder un texte en mémoire.
Premièrement, on décide de l’ensemble des caractères dont on a besoin, et on assigne à chacun un identifiant numérique unique appelé code. Cet ensemble est appelé jeu de caractères codés (en anglais charset, abréviation de character set) et peut se résumer dans un tableau de correspondance comme ci-dessus.
Ensuite, il faut déterminer l’encodage (encoding), c’est-à-dire la façon de transcrire un texte grâce aux codes des caractères qui le composent, selon un jeu de caractères donné. Le moyen le plus simple est d’écrire directement chaque code (auquel cas on parle de page de code — charmap) ; le jeu et l’encodage sont alors confondus. On a procédé de cette façon dans l’exemple ci-dessus, mais ce n’est pas toujours satisfaisant. C’est pourquoi il faut bien retenir la différence entre jeu de caractères et encodage.
Ça, c’est pour la théorie. Maintenant, place à la pratique ! L’exemple que je vous ai proposé était simple. Trop simple. La réalité est tout autre pour deux raisons principales :
Il y a bien plus de caractères à gérer.
Il y a des caractères particuliers, dits « de contrôle », qui ne servent pas pour un symbole « imprimable » mais donnent des indications aux programmes qui manipulent les chaînes de caractères. Le plus important est le caractère « fin de chaîne » qui sert à indiquer où s’arrête la chaîne (sinon, le programme n’aurait pas de moyen de le savoir et continuerait à lire ce qui se trouve après, ce qui nous vaudrait de belles erreurs).
De plus, il y a aussi les lettres minuscules, que je n’ai pas mis dans mon exemple. Il faudrait aussi pouvoir gérer les accents, les symboles de monnaie… voire, soyons fous, penser aux langues non latines (les Arabes et les Chinois ayant peut-être envie de parler leur langue).
C’est là que ça devient vraiment problématique, comme nous allons le voir.
Il faut aussi considérer les contraintes matérielles. En effet, comme je vous l’ai dit, un ordinateur ne connaît que le binaire. Les bits sont regroupés par groupes de 8 appelés « octets ». Un octet ne peut stocker que les nombres entiers de 0 à 255 (soit 256 = 28 possibilités, pour les matheux). Si cela ne suffit pas, on peut rassembler les octets par 2, 4 ou plus pour avoir de plus grands nombres.
Dans nos encodages, il faudra tenir compte de ces limites, c’est-à-dire s'arranger pour que les codes de notre jeu tiennent tous sur un ou deux octets par exemple.
La grande épopée des encodages
Pour bien cerner les problèmes causés par les encodages et la situation actuelle, le mieux reste encore de retracer leur histoire. En avant !
Au commencement était l’ASCII
Le premier encodage historique est l’ASCII, soit l’American Standard Code for Information Interchange (en français, le code américain normalisé pour l’échange d'informations). C’est une norme américaine, inventée en 1961, qui avait pour but d'organiser le bazar informatique à l’échelle nationale. Ce n’est pas le premier encodage utilisé mais on peut oublier les précédents.
Le terme « ASCII » est employé de manière incorrecte par beaucoup de monde sans savoir ce qu’il désigne réellement.
Le jeu de caractères ASCII utilise 7 bits (et non 8 !) et dispose donc de 128 (27) caractères uniquement, numérotés de 0 à 127. En effet, il est paru à une époque où des regroupements par 7 au lieu de 8 étaient encore assez fréquents.
Sans plus attendre, voici la table de l’ASCII :
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
00
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
10
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
20
SP
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
30
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
40
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
50
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
60
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
70
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
DEL
Hé, mais j’y comprends rien à ton tableau, moi !
Chaque case correspond à l’un des 128 caractères de l’ASCII rangés dans l'ordre.
Pour retrouver le code associé à un caractère, il faut regarder l’en-tête de sa ligne et celui de sa colonne ; il contiennent des valeurs en hexadécimal (si vous ne connaissez pas l’hexadécimal, allez voir cette partie de tutoriel) qu’il faut additionner. Ainsi le caractère Z a pour code hexadécimal 0x50+0xA = 0x5A (soit 90 en décimal).
Regardons un peu ce qu’il y a dans l’ASCII :
les 26 lettres de l’alphabet latin, en majuscules (0x41 — 0x5A) et en minuscules (0x61 — 0x7A), ainsi que les chiffres de 0 à 9 ;
divers signes de ponctuation, et d’autres symboles tels que les crochets, les accolades, l'arrobase… ;
des « caractères blancs », c'est-à-dire l’espace mais aussi d’autres tels que le retour à la ligne (eh oui, c’est aussi un caractère). Ils sont marqués comme ça, en voici la liste :
SP (0x20) : espace (space) ;
HT (0x09) : tabulation horizontale (horizontal tab), le ' ' des programmeurs ;
VT (0x0B) : tabulation verticale (vertical tab) ;
LF (0x0A) : nouvelle ligne (line feed), le ' ' des programmeurs ;
CR (0x0D) : retour chariot (carriage return), le ' ' des programmeurs ; marque la fin d’une ligne ;
FF (0x0C) : nouvelle page (form feed) ;
Notez que LF et CR remplissent des rôles très proches. Sous Windows on utilise une combinaison des deux (CR LF) à la fin de chaque ligne ; sous Linux et Mac OS X, on ne se sert que de LF ; enfin, sous Mac avant Mac OS X, on ne se servait que de CR. Un joyeux bazar !
des caractères de contrôle non imprimables (0x00 — 0x1F, et 0x7F), marqués comme ça ; en voici quelques-uns :
NUL (0x00) : caractère nul (null), le '\0' des programmeurs ; c’est le caractère servant à marquer la fin d’une chaîne de caractères ;
des caractères servant à la communication entre programmes, périphériques ou machines ;
des caractères correspondant à des actions, comme BS (backspace, retour arrière), ESC (escape, échappement) ou CAN (cancel, annulation) ;
d’autres encore.
Un exemple ? Tout d’suite m’dame !
Citation : Texte à encoder
Et l'ASCII survint.
texte : E t l ' A S C I I s u r v i n t .
valeur en ASCII : 45 74 20 6C 27 41 53 43 49 49 20 73 75 72 76 69 6E 74 2E
Les valeurs sont en hexadécimal.
Les 128 caractères de l’ASCII n’ont pas été placés au hasard. Leurs codes ont été soigneusement étudiés. Ci-dessous, quelques exemples pour votre culture.
À l’époque reculée où a été conçu l’ASCII, on communiquait encore parfois des données à l’ordinateur via des cartes perforées. Chaque emplacement codait un bit : 1 s’il y avait un trou, 0 sinon. La perforation était irréversible. Lorsqu'on n’avait pas encore spécifié de caractère particulier, on laissait tous les emplacements intacts et le caractère valait donc 0 (tous les bits à 0). Ce caractère « non spécifié » se retrouve en ASCII avec NUL, le caractère nul, qui vaut 0. De même, lorsqu’on voulait effacer un caractère on perçait tous les emplacements, ce qui donnait 127 (tous les bits à 1) ; le caractère ASCII DEL (delete) correspond justement à cette suppression.
Les lettres majuscules sont séparées de leurs homologues minuscules par un intervalle de 32. Cela signifie qu’il suffit de modifier un bit (le 6e) pour passer des unes aux autres, ce qui simplifie les traitements.
Comme vous voyez, l’ASCII est simple. Il ne comporte que le strict nécessaire pour l'époque, pour utiliser un ordinateur… en anglais. Que les 26 lettres de l’alphabet latin de base, pas d’accents, etc. Vous vous en doutez certainement, les autres pays ont voulu pouvoir utiliser leur propre langage correctement.
La révolte gronde
C'est pourquoi des extensions de l’ASCII sont apparues.
Certaines gardent la base ASCII et utilisent le 8e bit laissé libre afin d'avoir plus de caractères à disposition (deux fois plus, 256 = 28 au total). Ainsi, les codes de 0 à 127 correspondent encore aux caractères ASCII, tandis que les codes supérieurs (de 128 à 255, c’est-à-dire ceux avec le 8e bit valant 1) servent pour les nouveaux caractères.
D’autres restent sur 7 bits, et modifient carrément les 128 caractères de l’ASCII pour leur propres besoins.
Vous imaginez la pagaille monstrueuse que ça a été, lorsque chaque pays ou groupe linguistique s’est mis à éditer sa propre page de code. Ça fonctionnait bien tant que les documents ne quittaient pas la zone où leur propre encodage était en usage, mais les échanges internationaux étaient sujets à problèmes. Comme un même code signifiait des caractères différents d’un jeu à l'autre, le récepteur ne lisait pas la même chose que le destinateur. Par exemple, le symbole du dollar ($) aux États-Unis devenait celui de la livre (£) au Royaume-Uni : dégâts assurés !
Il y a bien eu des tentatives de stopper la multiplication des pages de code, mais globalement elles ont été insuffisantes.
En 1972, la norme ISO 646 a défini une page de code sur 7 bits dérivant de l’ASCII, avec des caractères fixes (principalement les lettres majuscules et minuscules, les chiffres et la ponctuation principale), les autres caractères étant laissés au choix. Cette norme, qui devait permettre une certaine compatibilité et un semblant d’ordre, a donné naissance à un certain nombre de pages de code nationales, mais elle n’était pas adaptée aux langues autres que latines et ne permettait pas de représenter assez de caractères.
ISO 8859 : 8 bits pour les langues latines
Plus tard, une norme mieux pensée a fait son apparition : la norme ISO 8859. Cette fois, elle utilise 8 bits donc 256 caractères au maximum. Le standard ISO 8859 comporte en fait plusieurs « parties », c’est-à-dire des pages de code indépendantes, nommées ISO 8859-n où n est le numéro de la partie.
ISO 8859 a été pensée afin que les parties soient le plus largement compatibles entre elles. Ainsi, elle englobe l’ASCII (codes 0 à 127) comme base commune, et les codes 128 à 255 devaient accueillir les caractères propres à chaque page de code, en s'arrangeant pour que des caractères identiques ou proches d’une page à l’autre occupent le même code.
Ce standard a principalement servi aux langues latines d’Europe pour mettre au point une page de code commune. À elles seules, elles utilisent finalement 10 parties d’ISO 8859, parfois appelées latin-1, latin-2, etc. ; ces parties correspondent à des évolutions dans la page de code latine de base (latin-1, ou officiellement ISO 8859-1) afin de rajouter certains caractères pour compléter des langues. En voici deux que vous devriez connaître :
ISO 8859-1 (latin-1 ou « Occidental ») est un encodage très courant dans les pays latins et sur la toile. C’est en effet celui qu’utilisent Linux et de nombreux documents et pages web. Les systèmes Windows utilisent également un jeu proche, comme on le verra bientôt. Il a l’avantage de permettre d’écrire grosso modo toutes les langues latines, et ceci avec des caractères d’un octet seulement.
ISO 8859-15 (latin-9 ou « Occidental (euro) »), datant de 1998, introduit le signe de l’euro (€) et complète le support de quelques langues dont le français (avec Œ) en abandonnant des symboles peu utilisés (dont le mystérieux ¤ signifiant « monnaie »). Il est néanmoins peu utilisé par rapport à son grand frère ci-dessus.
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
00
⋮
70
ASCII (sauf les caractères de contrôle, non utilisés)
À nouveau un exemple, avec cette fois des caractères accentués et autres (oui, je suis poète) :
Citation : Texte à encoder
« Ô âme oubliée ! »
texte : « ▒ Ô â m e o u b l i é e ▒ ! ▒ »
valeur en latin-1 : AB A0 D4 20 E2 6D 65 20 6F 75 62 6C 69 E9 65 A0 21 A0 BB
Notez l’emploi d’espaces insécables (symbolisés par ▒ pour qu’on les voit) avant le point d’exclamation et entre les guillemets, conformément aux règles typographiques. :)
Les codes de 0x00 à 0x1F et 0x7F (les caractères de contrôle ASCII) et de 0x80 à 0x9F sont laissés inutilisés par le standard ISO 8859. Pour les communications Internet, l’IANA a créé la norme ISO-8859 (attention, c'est le tiret qui change tout !). Celle-ci reprend toute la norme ISO 8859 et y rajoute des caractères de contrôle aux emplacements libres.
Windows s’est aussi basé sur latin-1 pour mettre au point son nouveau jeu de caractères occidental dans les années 1990. Windows-1252 (ou CP1252, parfois dit ANSI à titre officieux) est maintenant le jeu utilisé dans les systèmes Windows occidentaux (donc probablement chez vous), et remplace les anciennes pages de code (la page de code 437 pour les États-Unis, et la 850 pour l’Europe). Il reprend tous les caractères d’ISO 8859-1 et utilise les codes libres (de 0x80 à 0x9F) pour des caractères supplémentaires.
ISO 8859 a aussi été utilisé pour l’alphabet cyrillique (ISO 8859-5), l’arabe (ISO 8859-6), le grec (7) l’hébreu (8) et même le thaï (11).
Il existe au total 16 parties et il n’y en aura pas plus. En effet, on privilégie désormais le développement de l’Unicode.
ISO 2022 : du multi-octet pour les langues asiatiques
Pendant ce temps-là, en Asie…
Les langues latines s’en sont plutôt bien sorties finalement. Elles ont réussi à ne pas dépasser la limite fatidique de l’octet, ce qui restait quand même le plus pratique pour les traitements (et la consommation mémoire). Mais les langues asiatiques comme le japonais, le coréen ou le chinois disposent de bien trop de caractères pour que tout tienne sur 8 bits. Les encodages mis au point en Asie de l'Est ont donc franchi le saut du multi-octet. Certains utilisaient 2 octets, ce qui permet 65 536 (216) codes différents.
Comme pour les langues latines, un standard a été mis au point pour les organiser, on l’appelle ISO 2022. C’est un concept un peu spécial. Il permet de jongler entre plusieurs pages de code à l’aide de « séquences d’échappement » codées sur 3 octets (parfois 4) et commençant par le caractère ASCII ESC (0x1B) ; celles-ci indiquent aux programmes quelle page de code il faut utiliser pour interpréter ce qui suit. Les différentes pages de codes sont totalement indépendantes et peuvent utiliser un octet ou deux par caractère.
ISO 2022 a été utilisé pour le chinois (ISO 2022-CN), le coréen (ISO 2022-KR) et le japonais (ISO 2022-JP). Ces encodages, surtout le japonais, restent encore très répandus même si l’Unicode se développe.
Unicode, la solution ultime
Avec des normes comme ISO 8859 ou ISO 2022, on commençait à s’en tirer pas trop mal. Les problèmes sont atténués, mais subsistent (et si vous rédigez un document en français mais voulez y insérer de l’arabe ?). Finalement, des illuminés se sont dit : « Et si on créait un jeu de caractères unique pour tout le monde ? » De cette idée toute simple sont nés deux monuments : le standard ISO 10646 et Unicode.
Le Jeu universel de caractères
ISO 10646 voit le jour en 1990. Il s’agit du Jeu universel de caractères ou JUC (en anglais, UCS pour Universal Character Set). Celui-ci a été pensé pour pouvoir accueillir n’importe quel caractère existant de n’importe quelle langue du monde. Un travail titanesque ! Concrètement, c’est un bête jeu de caractères, sauf que celui-ci offre pas moins de 221 = 2 097 152 codes ! À l’origine, il allait même jusqu’à 232 = 4 294 967 296, mais il a rapidement été restreint : c’est déjà bien suffisant.
Actuellement, environ 17% des codes sont déjà attribués à des caractères. Comme vous le voyez, il nous reste encore de la place à revendre. Et pourtant, dans ces 17%, on a tout mis ou presque : les caractères de tous les anciens jeux, tous les alphabets modernes, pléthore de symboles…
Le JUC n’est peut-être pas la solution définitive et éternelle (en informatique, il ne faut jamais dire « jamais »), mais il s’en rapproche suffisamment pour qu’on dorme sur nos deux oreilles pendant le siècle à venir. :)
Devant une telle quantité, les polices d’écriture (qui n’ont rien à voir avec les encodages, il s’agit ici d’affichage des caractères et non de leur codage en mémoire) peinent à suivre. C’est ce qui explique les petits symboles du type
que vous pouvez voir avec un peu de chance sur certaines pages (si vous regardez bien, vous constaterez que dans le carré est inscrit le code hexadécimal du caractère). ;) Généralement, les auteurs de polices se contentent de créer les glyphes des parties qui les intéressent (et éventuellement recopient les glyphes de référence pour le reste) ; si vous avez vraiment besoin de rédiger une partition suivant la notation musicale grecque ancienne avec le JUC, vous utiliserez une police spécialisée.
Bon à savoir : par commodité et souci de compatibilité, le JUC reprend ISO-8859-1 (latin-1 avec les caractères de contrôle) pour ses 256 premiers caractères (donc inclut également l’ASCII).
Ce jeu n’est pas définitif : de nombreux caractères sont régulièrement créés et assignés à des codes encore libres. Rassurez-vous, les caractères déjà en place ne bougent plus.
logo d’Unicode
Unicode
Unicode est une norme développée par le Consortium Unicode publiée pour la première fois en 1991 (en 2011, elle en est à la version 6.1). On peut la voir comme une surcouche (une extension) d’ISO 10646. En fait, les deux normes sont développées parallèlement et synchronisées en permanence. Là où ISO 10646 liste simplement les caractères du jeu et leur assigne un nom et un code, Unicode va plus loin en leur ajoutant des attributs et en décrivant des relations entre eux (donc en leur donnant un sens). C’est un peu complexe et pas forcément intéressant ici, donc je ne m’étendrai pas dessus.
Unicode, c’est cependant plus que cela. Ce standard décrit également des algorithmes de traitement, notamment pour la gestion des différents sens d’écriture, et surtout, ce qui nous intéresse ici, des encodages permettant de transcrire le JUC.
Un jeu, des encodages
Des encodages ? Mais, euh… Je croyais qu’Unicode était un encodage ?
Unicode est basiquement un jeu de caractères (un ensemble de caractères auxquels on attribue à chacun un point de code unique) et non un encodage (façon de représenter ce point de code en mémoire). C’est ici que la distinction prend tout son sens. Auparavant, les deux se confondaient puisque tous les jeux de caractères étaient associés à un encodage simple : vu que leur codes tenaient sur un ou deux octets, on se contentait de les écrire tels quels en mémoire.
Or, les points de codes d’Unicode nécessitent beaucoup plus qu’un octet : il leur en faudrait quatre ! Cela voudrait dire que si l’on continuait à faire comme avant, on utiliserait 4 fois plus de mémoire qu’avec nos jeux précédents tenant sur un octet, comme ISO 8859.
Des petits malins me diront que trois octets suffiraient car on aurait alors 3×8=24 bits disponibles ; c’est vrai maintenant que le jeu a été réduit à 221 codes, mais en informatique, pour des raisons techniques, on préfère des tailles multiples de 2.
Ce serait un gaspillage de mémoire trop important, d’autant plus qu’il paraîtrait inutile. En effet, il y aurait plein d’octets qui vaudraient zéro :
Codes
Encodage selon UTF-32
Caractères disponibles dans cet intervalle
jusqu’à U+00FF (28-1)
00000000 00000000 00000000 bbbbbbbb
langues occidentales (latin-1)
jusqu’à U+FFFF (216-1)
00000000 00000000 bbbbbbbb bbbbbbbb
la plupart des alphabets actuellement
utilisés dans le monde
jusqu’à U+10FFFF (221-1)
00000000 000bbbbb bbbbbbbb bbbbbbbb
n’importe quel caractère
Vous le voyez, il y aurait toujours au moins un octet nul. Le cas extrême est celui d’un Occidental qui gaspille 3 octets par caractère.
UTF-16
Pour faire des économies, on a donc mis au point des encodages plus futés. Tout d’abord, il y a l’UTF-16 (UCS transformation format, 16 bits). Celui-ci code les 216 = 65 536 premiers caractères sur 2 octets, et les codes supérieurs sont représentés sur 4 octets par le biais d’une petite transformation mathématique. Le 16 dans son nom indique le nombre minimal de bits nécessaires pour un caractère.
Les caractères de cet encodage ne font donc pas tous la même taille, ce qui complique un poil les traitements (même s’il est facile de distinguer un caractère sur 2 octets d’un caractère sur 4).
De plus, on a une difficulté technique supplémentaire pour l’UTF-16 (et l’UTF-32) : le boutisme (endianness). Ce terme mystique désigne l’ordre dans lequel sont « rangés » les octets d’un nombre multi-octet. Il en existe deux sortes principales : le gros boutisme (big-endian, BE) et le petit boutisme (little-endian, LE).
Le problème, c’est que le boutisme dépend des machines et que ces deux-là sont très répandus. Or en UTF-16 on lit les données par groupes de 2 octets, donc le boutisme influe sur le résultat : si l’on lit du texte UTF-16 envoyé par quelqu’un utilisant un boutisme différent du sien, c’est l’erreur assurée !
Pour pallier à cela, on utilise parfois un caractère spécial appelé BOM (byte order mask, marque d’ordonnancement des octets). l’IANA a aussi autorisé deux déclinaisons de l’encodage pour les communications Internet qui permettent de préciser le boutisme employé : UTF-16BE et UTF-16LE.
Reprenons le texte d’exemple de tout à l’heure et encodons-le cette fois en UTF-16 :
Remarquez que ce texte en UTF-16 s’encode exactement comme en latin-1, avec des valeurs sur 2 octets au lieu d’un (donc un octet sur deux valant 0). On occupe donc deux fois plus de mémoire.
UTF-8
On a aussi inventé l’UTF-8. La taille des caractères codés est encore plus variable, et l’économie de mémoire plus grande. Comme vous l’avez deviné, le nombre minimal de bits est 8. En fait, il représente les premiers caractères (ceux de l’ASCII) sur un octet, les suivants sur 2 octets, 3 et jusqu’à 4 octets.
En plus, cet encodage est compatible avec l’ASCII : les caractères sont codés exactement de la même manière en UTF-8 et en ASCII. Ajoutez à cela que l’encodage a été conçu afin que certains algorithmes de traitement (comparaison de texte par exemple) soient réutilisables sans modification. Ainsi, de vieux programmes qui n’ont pas été conçus pour un autre encodage que l’ASCII fonctionneront aussi si on leur passe du texte en UTF-8 : magique !
Enfin, contrairement à l’UTF-16, on n’a pas de problème de boutisme puisqu’on lit les données octet par octet. :)
Bref, UTF-8 a de nombreux avantages (économie de mémoire, compatibilité, boutisme, résistance aux erreurs…). Un défaut aussi : la grande variabilité de taille des caractères qui rend les traitements plus compliqués et moins performants. Il n’empêche que ses point forts lui ont assuré un grand succès : il est sans doute l’encodage le plus répandu aujourd’hui. Il est utilisé pour les documents et les communications, et les systèmes d’exploitation (Mac et GNU/Linux) s’y mettent aussi.
Pour ne pas changer, exemple de texte en UTF-8 :
Citation : Texte à encoder
« Ô âme oubliée ! »
texte : «____ ▒____ Ô____ â____ m e o u b l i é____ e ▒____ ! ▒____ »____
valeur en UTF-8 : C2-AB C2-A0 C3-94 20 C3-A2 6D 65 20 6F 75 62 6C 69 C3-A9 65 C2-A0 21 C2-A0 C2-BB
Constat flagrant, la consommation de mémoire est singulièrement réduite par rapport à UTF-16. :D On voit de plus que les caractères de base sont codés exactement comme en ASCII, et les caractères supérieurs s’étendent sur plusieurs octets (ici symbolisés par « __ »). Ici, vu qu’on reste dans les caractères latins, ça ne dépasse jamais deux octets, mais ça peut aller jusqu’à 4.
Et aujourd’hui ?
Hop, notre périple au fil des âges, sur la piste des encodages, nous a ramené au temps présent ! ASCII, ISO 8859, UTF-8… Il est grand temps de dresser le bilan. Que retenir de tout ça ?
Le principe du stockage de texte en informatique : jeux de caractères et encodages (bien retenir la distinction).
Qu’un caractère n’est pas un octet. Ni même un nombre fixe d’octets. Programmeurs, fourrez-vous ça dans le crâne et tenez-le vous pour dit.
Les principaux encodages : ASCII, ISO 8859-1, UTF-8, pour n’en donner que trois.
Leurs usages actuels.
Les encodages actuels
On va tout de suite détailler le dernier point !
Avant l’apparition d’Unicode, les systèmes d’exploitation fonctionnaient avec un système de pages de code régionales, c’est-à-dire qu’on utilisait des variantes d’encodage sur 8 bits en fonction du pays. Depuis, ils ont migré vers Unicode en interne (y compris Windows, depuis XP, même si ça ne se répercute par forcément pour l’utilisateur).
Sous Windows, UTF-16 (little endian) est maintenant utilisé en interne et UTF-8 est également supporté, mais par compatibilité Unicode cohabite avec les pages de code. Ces dernières, incorrectement appelées « ANSI » et proches des ISO 8859, sont encore fréquemment utilisées. Je vous rappelle que celle pour nous autres occidentaux (Europe de l’Ouest et Amérique du Nord) est Windows-1252(« CP1252 ») et dérive de latin-1. Celles-ci ont remplacé les anciennes pages de code dites « OEM » (CP437 et CP850 pour l’Occident), dont l’usage demeure toutefois pour la console.
Sous Mac OS, l’encodage en vigueur en Occident était nommé MacRoman, mais depuis Mac OS X on utilise UTF-8.
Les distributions GNU/Linux utilisaient latin-1 par défaut. Certaines l’utilisent toujours, tandis que les autres adoptent progressivement UTF-8 (maintenant majoritaire).
Il est bien sûr possible, avec les bons outils, d’encoder un fichier de n’importe quelle façon, sous n’importe quel système d’exploitation. L’encodage utilisé par un OS est celui utilisé par défaut dans le fonctionnement des programmes. Les outils intégrés à un OS (la console de Windows, par exemple) ou fournis avec auront donc une préférence pour cet encodage. Cela influe donc sur l’encodage des documents (puisqu’un utilisateur de base ne s’en souciera pas).
De plus, UTF-8 est devenu l’un des encodages les plus utilisés sur la Toile (pour les pages Web), ce qui semble logique puisqu’il s’agit d’un réseau international mettant en contact toutes les langues. L’autre principal encodage sur Internet reste latin-1.
Comme vous voyez, l’ASCII seul n’est plus employé, mais tous les encodages répandus conservent la base ASCII par compatibilité. Les trois principaux, cités ci-dessus, se basent même tous sur latin-1 (même si l’UTF-8 n’est pas compatible avec ce dernier puisqu’un codet de 8 bits sera encodé sur 2 octets).
Détection de l’encodage
Un problème posé par la diversité des encodages existants est la détermination de l’encodage utilisé par un fichier. Les renseignements associés à un fichier particulier (sa date de création par exemple) n’indiquent rien sur son encodage. On doit donc tenter de le « deviner », au moyen d’algorithmes compliqués qui analysent le contenu du fichier. Ces algorithmes sont efficaces la plupart du temps, mais peuvent échouer, et sont compliqués.
C’est ce qui explique les affichages bizarres de certains fichiers ou pages web : le programme n’a pas réussi à déterminer le bon encodage.
Un moyen plus simple serait d’inclure cette indication directement dans le contenu du fichier, au tout début (afin de diminuer les risques de perturbation). On utilise pour cela le fait que tous les encodages actuels soient compatibles avec l’ASCII. C’est ce qu’on verra tout à l’heure pour les pages HTML.
En pratique : jongler avec les encodages !
Vous n’êtes pas lassé de toutes ces connaissances à ingurgiter ? Rassurez-vous, on va s’arrêter là pour pratiquer un peu. :) Il est important de savoir tout ça, mais c’est encore mieux de savoir le mettre à profit !
Manipuler des documents
Lorsqu’on consulte un document, que ce soit un fichier texte (code source par exemple) ou une page web, il faut la lire avec le bon encodage. Sinon, les valeurs seront mal interprétées. Exemple ?
Voici un texte encodé en UTF-8 :
Citation : Texte encodé en UTF-8
Bonjour, amis Zéros !
Si vous le lisez en latin-1, vous obtiendrez ceci :
Citation : Texte encodé en UTF-8 mais interprété comme du latin-1
Le problème se pose même si tous les caractères font la même taille dans les deux encodages, une même valeur pouvant désigner deux caractères différents d’un encodage à l’autre.
Consulter une page web (avec un navigateur)
La plupart du temps, vous n’aurez pas à vous soucier de l’encodage pour lire une page web. Normalement, celui-ci est en effet précisé dans le code source. Il arrive toutefois que ce ne soit pas fait, ou mal fait, et que votre navigateur (Internet Explorer, Firefox…) échoue à le deviner. Par exemple : Exemple de page web lue (avec Firefox) avec un mauvais encodage − exemple bien sûr simulé !
C’est moche. C’est désagréable à lire. Heureusement, vous pouvez y remédier manuellement. Tout navigateur qui se respecte offre un menu permettant de jongler entre les encodages. Vous devriez trouver sans trop de difficultés. Pour Firefox par exemple, il est caché dans le menu « Affichage » : Menu des encodages dans Firefox
Pour l’instant, par défaut, le navigateur est en « détection automatique », ce qui a conduit à l’utilisation incorrecte d’ISO-8859-1 (latin-1). On peut en changer. Ici, la page est probablement en UTF-8 (ça ressemble à l’erreur qu’on a vue en introduction), donc on essaie cet encodage. On choisit l’option correspondante dans le menu, et… Tadaam !
La page s’affiche correctement. Vous avez fait du beau boulot. :)
Travailler sur un fichier (avec un éditeur de texte)
On va maintenant voir comment gérer l’encodage de nos fichiers. Tout éditeur de texte qui mérite d’être appelé ainsi nous permet de le faire de façon précise.
Commençons par un cas d’école : le Bloc-Notes de Windows. Si vous êtes sous Windows, ouvrez le Bloc-Notes, tapez un peu de texte avec des accents, puis enregistrez. Boîte de dialogue d’enregistrement du Bloc-Notes, avec choix de l’encodage
Comme vous voyez, le Bloc-Notes permet au premier enregistrement de choisir l’encodage du fichier. Le choix est assez limité cependant : « ANSI » (Windows-1252, l’encodage par défaut sous Windows, je vous le rappelle), « Unicode » et « Unicode big endian » (qui désignent en fait l’UTF-16 avec les deux boutismes possibles), ou UTF-8.
Comme exercice, vous pouvez vous amuser à vérifier que les tailles des fichiers affichées sur ma capture sont correctes, sachant que mon texte comporte 15 caractères et que le Bloc-Notes rajoute automatiquement une BOM pour tous les encodages Unicode (qui fait 2 octets en UTF-16 et 3 octets en UTF-8).
Le Bloc-Notes est vraiment un éditeur très basique, et ses fonctionnalités sont limitées. Ainsi on ne peut pas choisir le latin-1 par exemple. De plus, rien n’indique l’encodage du fichier sur lequel on travaille, et on ne peut pas en changer après coup.
Si vous faites de la programmation ou autre, vous utilisez certainement un éditeur plus avancé (je l’espère pour vous). Comme les navigateurs web, la plupart incluent un menu pour passer d’un encodage à un autre. Toujours sous Windows, voici l’exemple de Notepad++ (ici j’ai rouvert les fichiers que je viens de créer avec le Bloc-Notes) : Le menu des encodages dans Notepad++
Déjà, première remarque, Notepad++ détecte automatiquement l’encodage du fichier ouvert et l’indique dans la barre de statut (en bas, encadré en bleu). C’est tout de suite mieux. :)
Au passage, remarquez la mention « Dos\Windows » à gauche de cette indication. Elle indique le style utilisé pour les fins de ligne. Souvenez-vous, on avait vu qu’il existait plusieurs façon de coder une fin de ligne, selon les OS. Cette mention indique que notre fichier utilise le style Windows, c’est-à-dire CR LF.
Ensuite, comme vous voyez, le menu « Encodage » permet de changer en direct l’encodage utilisé. les options « Encoder en xxx » ont le même effet que pour les navigateurs web (elles changent l’interprétation des octets déjà existants) ; elles influent en plus sur l’écriture (l’encodage des nouveaux caractères qu’on écrit).
Pour modifier l’encodage d’un fichier, il ne faut pas cliquer sur « Encoder en xxx », car cela ne convertit pas le contenu existant pour l’adapter au nouvel encodage. Pour ça, il faut faire « Convertir en xxx ». ;)
Enfin, vous constatez qu’on a quand même un choix d’encodages plus vaste que dans le Bloc-Notes !
Après cet aperçu, faites un tour dans la configuration de votre éditeur. Il y a certainement des options qui nous intéressent. Fenêtre de configuration de Notepad++ (paramètres relatifs à l’encodage)
Ici, j’ai encadré la partie intéressante en vert. Je peux choisir l’encodage qui sera utilisé par défaut lors de la création d’un nouveau fichier (ainsi que le format des fins de ligne, ce dont je vous parlais tout à l’heure).
Avec ou sans BOM ?
Remarquez qu’il y a deux encodages UTF-8. o_O L’une porte la mention « (sans BOM) », ce qui signifie que l’autre est un « UTF-8 avec BOM ». Si vous vous rappelez bien, la BOM est un caractère Unicode spécial qui permet d’indiquer le boutisme d’un fichier. Elle se place au tout début de ce fichier. Cette technique est utilisée pour l’UTF-16 (et l’UTF-32). En revanche, elle est inutile en UTF-8 puisqu’on n’a pas de problème de boutisme. Pire, elle peut rendre des fichiers invalides lorsqu’ils sont lus par certains programmes. C’est par exemple le cas des pages web, comme on verra plus tard.
Pourtant, certains éditeurs dont le fameux Bloc-Notes la rajoutent automatiquement même en UTF-8, car ça les aide à détecter l’encodage du fichier. C’est une pratique déconseillée. Dans votre éditeur favori, choisissez toujours la version sans BOM si vous avez le choix.
Ici, je vais nettoyer mon fichier de cette hérésie avec Notepad++. Pour ça, je fais simplement « Convertir en UTF-8 (sans BOM) » et j’enregistre. Dans les paramètres de mon éditeur (cf. ci-dessus), je choisis aussi l’UTF-8 sans BOM par défaut.
Écrire des documents (HTML, LaTeX, etc.)
Lorsque vous codez certains documents destinés à être lus et interprétés par un programme (page web HTML, document LaTeX…), il vous faut en plus préciser à ce programme l’encodage du fichier.
HTML (pages web) et XML
Pour les pages HTML, il existe un champ dans l’en-tête HTTP fourni par le serveur :
Content-Type: text/html; charset=‹ENCODAGE›
Vous voyez d’ailleurs que cet en-tête fournit aussi le type MIME du document (page HTML, fichier CSS, script JavaScript…).
Cette technique est toutefois peu utilisée, car elle nécessite un serveur (ce qui n’est pas le cas si vous consultez un document local), et rend compliqué le fait de fournir sur le même serveur des fichiers avec des encodages différents (par exemple un serveur mutualisé où chacun est libre de choisir son encodage). À la place, on renseigne donc l’encodage… directement dans le fichier HTML. Ça semble bizarre vu que justement, en théorie, on ne peut pas encore lire le fichier. Mais la base ASCII vient à notre secours : quel que soit l’encodage, si on n’utilise que les caractères de l’ASCII, on pourra lire sans problème. :)
L’information à fournir est sous la forme d’une balise <meta http-equiv /> (dans le <head/>) qui est l’équivalent de l’en-tête HTTP.
Vous devez la placer en toute première dans le <head/> afin de ne pas perturber la détection, et parce que le navigateur recommence depuis le début dès qu’il l’a lue. De plus, ne mettez rien de plus que nécessaire au-dessus, pas même un commentaire. Seuls des caractères ASCII doivent précéder cette ligne (et gardez à l’esprit que l’UTF-8 doit être utilisé sans BOM !).
Mauvais exemple (il y a des caractères non-ASCII dans le commentaire) :
<html>
<head>
<!-- Ligne nécessaire pour spécifier l’encodage : -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
…
Vous pouvez trouver ici la liste des noms d’encodage que vous pouvez mettre à la place de ‹ENCODAGE› (insensibles à la casse). Les plus intéressants pour vous sont « ISO-8859-1 » (ou « latin-1 ») et « UTF-8 ». Simple !
Pendant qu’on y est, notez qu’il existe sur le SdZ un tutoriel complet pour migrer son site web de latin-1 vers UTF-8. ;)
Dans les langages de type XML en général (dont HTML), il est possible de spécifier l’encodage autrement. Il peut être renseigné dans le prologue XML, une sorte de « balise » spéciale optionnelle (vous savez, c’est celle qui fait <?xml … ?>), qui doit être placée sur la toute première ligne du fichier.
<?xml version="1.0" encoding="‹ENCODAGE›" ?>
LaTeX (documents mis en forme)
L’encodage est très important avec LaTeX. Comme en HTML, il faut déclarer avec quel encodage est enregistré le fichier en le précisant en paramètre du package inputenc :
\usepackage[‹ENCODAGE›]{inputenc}
(« latin1 » ou « utf8 » pour les plus courants). Les fichiers éventuellement inclus avec la commande \input doivent être enregistrés avec le même encodage, mais il n’y a pas besoin de le déclarer à nouveau.
Programmer
Lorsque vous créez un programme, il faut bien sûr faire attention à toutes ces histoires d’encodages pour que le programme fonctionne bien en fonction de ce qu’on lui passe comme texte.
Bas niveau : le langage C
Commençons par le « maître langage », le C. Le C est bas niveau, et ne nous cache donc rien de toutes ces questions. En C, on manipule directement les bytes, avec le type char. Il y a également le type wchar_t permettant d’après la norme de stocker tout caractère du jeu dit « étendu ».
La gestion des encodages en C de façon portable est excessivement compliquée si l’on se contente de la bibliothèque standard. En effet, la norme met à disposition des fonctions de conversion entre char et wchar_t, mais laisse à l’implémentation le choix des encodages utilisés pour ces deux types…
Cette difficulté s’explique par le fait que le C est un vieux langage, inventé dans les années 70, lorsqu’on n’utilisait encore que des encodages sur un byte (l’ASCII, ou à la rigueur des pages de code). Tout était plus simple. Avec le développement de jeux plus complexes, il a fallu adapter la norme pour supporter les caractères « multibyte ». Le résultat tient presque de la bidouille et est difficilement exploitable, ou en tout cas fastidieux. On obtient une soupe de « locales », de « caractères larges » (wide characters, le type wchar_t), de « caractères multibyte » (le type char) et d’« états de conversion », le tout dépendant de l’implémentation…
Cette complexité supplémentaire alliée à l’ignorance des programmeurs n’aide pas à changer les habitudes ; beaucoup continuent à croire qu’« un char égale un caractère », ce qui est faux, archifaux.
En plus, non content de faire attention au fonctionnement interne du programme, il faut aussi se préoccuper du format du texte que le programme reçoit en entrée et de celui qu’il produit en sortie. Sans parler de l’affichage en console… :diable:
Bref, pour avoir le même résultat sous tous les OS et éviter de nombreuses prises de tête, il peut être avisé d’utiliser une bibliothèque tierce (ou vous en coder une basique, ce qui fait un bon exercice). Je vous recommande la bibliothèque ICU qui est extrêmement complète et prend en charge toutes les fonctionnalités Unicode. ;)
Je ne m’étendrai pas plus sur le sujet, qui nécessiterait un cours entier. Si vous êtes intéressés, renseignez-vous sur les notions évoquées ci-dessus.
Haut niveau
Les langages de haut niveau, c’est bien connu, cachent au programmeur les détails vilement matériels qui n’intéressent personne. Certains gèrent donc tout seul le bazar, pour notre plus grand bonheur. Tout ce qu’on a à faire, c’est lire et écrire du texte, sans se soucier du nombre d’octets qu’occupe un caractère, de l’encodage utilisé…
Par exemple, la classe String de Java utilise l’UTF-16. De plus, des fonctionnalités supplémentaires pour contrôler plus finement l’Unicode sont fournies par le packageJava.text.
Ouf !
Alors ? Toujours en vie ? Ça fait un gros pavé à lire mais ce n’est pas bien sorcier, et surtout… qu’est-ce que c’est bien une fois qu’on sait tout ça ! On comprend enfin ce qui se passe de l’autre côté de l’écran et les « caractères spéciaux » ne font plus si peur, hein, avouez ? :p
Ce que vous venez d’apprendre est super-méga-important dès que vous commencez à bidouiller un peu sur votre PC. Comme le dit Joel (cf. plus bas), c’est « ce que tout programmeur doit savoir ». Malheureusement, tout programmeur ne le sait pas, et les ignorants sont même nombreux. C’est ce qui explique de nombreux messages de demande d’aide sur les forums du SdZ, et ce qui a motivé l’écriture de ce cours, dans l’espoir qu’il fera progresser les choses dans le bon sens.
Liens
Vous voulez encore de la lecture ? Vous allez en avoir !
Tout d’abord, quelques cours intéressants sur le sujet :
Ensuite, Wikipédia sait tout et voit tout. Elle est très bien fournie sur ce thème (et n’hésitez pas à aller voir les articles anglais qui sont souvent plus complets). Vous pouvez par exemple consulter l’article « Codage de caractères », ou un comparatif des encodages Unicode (en anglais). Si vous avez besoin de connaître la valeur d’un caractère dans un encodage particulier, elle fournit toutes les tables intéressantes de façon claire (quelques exemples : ASCII, CP850, latin-1).
Et même le JUC y est détaillé de façon systématique et bien organisée (pas sur une seule page, évidemment). ;)