Norme UTF-16LE
Windows utilise l’encodage UTF-16LE comme encodage naturel du texte Unicode. Développé dans les premiers jours de l’Unicode, et avant l’invention de l’UTF-8, le support UTF-8 de Windows est complètement déficient. C’est même gênant d’en parler en 2017. En effet, ce schéma de nommage erroné est devenu une partie de l’interface utilisateur de Windows. Un éditeur de texte qui utilise le support de codage de Windows pour fournir une gamme d’encodages décrira automatiquement et de manière inappropriée UTF-16LE comme « Unicode » (et UTF-16BE comme « Unicode big-endian »). Noter que certaines applications natives de Windows qui développe leurs propres encodages, comme Notepad ++, n’ont pas ce problème.
NOTE : Le légendaire éditeur pour programmeur UltraEdit a finalement sorti en février 2017 une version dite « pleinement native Unicode » qui supporte le symbole des pages AMP Project « ⚡ »!
Le codage des caractères n’a rien de sorcier, il suffit de s’entendre et d’avoir l’infrastructure capable de le supporter!
ASCII et jeu de caractères
Microsoft, comme la plupart des outils conçus en anglais, a misé sur l’Unicode dès sa sortie pour régler son problème de caractères ASCII étendus (c’est à dire sur 8-bit versus le 7-bit ou 1 byte suffisant pour l’anglais) et ses nombreux jeux de caractères comme le Latin-I ou ISO 8859-1, toujours très présent en 2017! À la différence de spécifier un « charset » différent pour chaque langage, dans un contexte de plus en plus international avec l’arrivé du web, il n’y en aurait plus qu’un seul : l’Unicode.
NOTE : Le « byte » ou « multiplet » en français!, est la plus petite unité adressable d’un ordinateur. Aujourd’hui, les bytes de 8 bits se sont généralisés en informatique, mais jusque dans les années 1970, il existait des processeurs avec des bytes de 6 à 9 bits. En revanche, un octet, comme son nom l’indique, contient exactement 8 bits (en anglais eight-bit byte). - Wikipédia.
.Exemple de code ASCII de IBM :
A = 65, B = 66, C = 67...
Exemple de jeu de caractères Windows
Windows-1252: Anglais, Français, Espagnol, Allemand, Italien, Espagnol Windows-1251: Russe, Bulgare, Serbe, Ukrainien Windows-1253: Grec Windows-1256: Arabe
Je n’ai absolument rien contre l’anglais (à part les paradis fiscaux ; -), au contraire. Et même si la documentation est essentiellement anglophone, j’ai fini par m’en formaliser. Mais l’anglais, qui n’a absolument aucun caractères étendu, est la sémantique tout comme la culture derrière l’informatique, ses normes et sa programmation. Et force est de constater que la réflexion s’arrête souvent là, au détriment des autres langues.
Unicode
En fait, l’Unicode n’est pas un encodage. L’idée consiste à doter chaque caractère au monde, de chaque langage, ancien ou moderne, d’un unique « Code Unicode ». Tous les jeux de caractères en une seule liste (incomplète au demeurant). Et l’Unicode à le dos large, s’il compte (en 2017) 128 000 caractères, il a la possibilité d’en gérer 1 million! Windows, qui n’y va pas de main morte, encode ensuite les chaines Unicode avec la norme UTF-16LE. C’est donc quadrupler du coup l’espace nécessaire pour stocker un simple caractère ASCII! Et dans les années 90, le mot « tera » n’existait pas encore! ;-)
Avec un fichier texte de 100Mo qui passe à 400Mo juste pour lui permettre d’ajouter le caractère « copyright » en bas d’une page! Ce n’est pas la peine de vous dire combien cette technique fut carrément ignorée par la langue de Shakespeare pour ne pas dire utilisée comme bouche-trou pour avoir bonne conscience!
Parallèlement aux chaines ANSI, Windows implante donc l’Unicode dans tous ces systèmes pour gérer les textes Unicode. Créé avant l’invention de l’UTF-8, c’est pour cette raison que Windows supporte mal encore aujourd’hui le UTF-8. En fait, il n’est pas rare de trouver, en 2017, des applications, des composantes, des compilateurs ou de simple script qui prétendent supporter l’UTF-8 à tort. Du système FSO de IIS à une application comme UltraEdit en passant par un simple DLL installé sur le serveur ou carrément le serveur lui-même. C’est systémique sous Windows, mais aussi sur d’autres plateformes, le JavaScript par exemple, a aussi ses défauts même sous Linux! D’ailleurs le PHP a pris son temps, il n’est pas rare encore aujourd’hui de trouvé des discussions autour de cette question avec des réponses plus farfelues les unes que les autres. Plusieurs conseil même d’utiliser l’encodage MIME toujours en 7 bits. Comme le Quoted-Printable qui utilise le vieil ASCII 7 bits avec une patch pour ajouter le huitième bit! Et la grande porte de sortie de l’encodage Base64, avec une petite conversion, cet encodage MIME est utilisé pour transmettre du binaire, comme les images, mais aussi par extension tous caractère étendu du 8 bits. Personnellement je l’utilise beaucoup le Base64, mais pas comme panacée au problème d’encodage, pour crypter des données et des images!
Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Ceci est un message encod=C3=A9 en UTF-8, puis transform=C3=A9 en ASCII par la m=C3=A9thode "Quoted-Printable".
Norme RFC 1342
Faut dire que contrairement à une page Web, la norme RFC 1342 conseil d’utiliser exclusivement le code ACSII dans l’entête d’un courriel! C’est dire que même en spécifiant l’UTF-8 dans le « body », Content-Type: text/plain; charset=utf-8
, le sujet, le nom font partie de l’entête qui doit contenir uniquement des caractères ASCII. Le RFC 1342 est donc est une recommandation qui permet de représenter les caractères non ASCII dans les entêtes de messagerie électronique sans faire planter les serveurs de messagerie et surtout sans utiliser l’UTF-8.
Exemple :
=?charset?encoding?encoded-text?= Résultat =?utf-8?Q?Allo?=
L’encodage doit être soit B (base 64) soit Q (quoted-printable). Voilà l’exemple d’un courriel envoyé en PHP avec un corps UTF-8 et un sujet base64 :
$to = 'example@example.com'; $subject = 'Sujet non ASCII with non ASCII ó¿¡á'; $message = 'Message non ASCII ó¿¡á'; $headers = 'From: example@example.com'."\r\n" .'Content-Type: text/plain; charset=utf-8'."\r\n"; mail($to, '=?utf-8?B?'.base64_encode($subject).'?=', $message, $headers);
Méconnaissance de l’UTF-8 dans un monde toujours ASCII des années 60!
Tellement que même Google (Gmail) fait la conversion systématique de tous les courriels en UTF-8 considérant que le support n’est pas adéquation! Si l’UTF-8 a effectivement limité les dégâts (et il est seulement deux fois plus lourd!), on a plutôt choisi la simplicité en se contentant bêtement d’utiliser les entités HTML! Au point que même les francophones l’utilisent encore. Comme tout ou presque utilise aujourd’hui un navigateur, parfois intégré à même l’application, l’affichage se fait de plus en plus en HTML, avec raison. Le HTML est aujourd’hui le médium par excellence!
Il est donc très facile de convertir chaque caractère en entité HTML. Et des centaines de sites spécialisés anglophone conseil toujours d’utiliser les entités HTML!! On les connait même par cœur, & copy;
(©) par exemple? Au lieu de doubler le poids d’un fichier en UTF-8 pour un symbole, on ajoute 4 petits caractères ni vu ni connu. Et le tour est joué. J’ai discuté avec des concepteurs de logiciel qui jurait que leur application était UTF-8 alors qu’ils utilisaient simplement les entités HTML que je dois convertir manuellement en UTF-8! Imaginez, j’utilise mes propres scripts de conversion de caractères tellement le support est inefficace. Le FSO du ASP est un bel exemple, basé Unicode, il est incapable de gérer l’UTF-8. Et c’est pourquoi un francophone n’a d’autre choix que d’utiliser l’ADODB.Stream! Combien de scripts (ironiquement utilisés pour encoder et crypter des chaines de caractères) utilisent le binaire et des instructions natives absolument incompatibles avec l’UTF-8! On est pas loin du ASCII! Même chose avec certaines fonctionnalités du JavaScript, comme l’utilisation de « localeCompare »!
Certes, le HTML, et plus spécifiquement les navigateurs, offre un véritable support UTF-8 depuis le temps, pourvu de bien l’indiquer dans le document! Mais quand est il pour la feuille de style? Un JavaScript? Ouvert par une page HTML, tout va pour le mieux, mais essayer directement un fichier .css ou .js dans le navigateur, si le serveur le permet. Bonjour les caractères étendus!
UTF-8 HTML 5 <meta charset="utf-8"/> UTF-8 HTML 4 (XHTML) <meta http-equiv="content-type" content="text/html; charset=utf-8" /> Jeu de caractères HTML (Latin I) <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
Dans la feuille de style CSS et fichier JavaScript (pratiquement aucun support)
UTF-8 CSS @charset "UTF-8"; UTF-8 JavaScript <script type="text/javascript" src="/js/javascript.js" charset="UTF-8"> UTF-8 Action Script (Flash) system.useCodepage = 1;
Directement dans l’entête HTTP
UTF-8 ASP <%@ CodePage=65001 Language="VBScript"%> UTF-8 ASP.NET <%@ Page RequestEncoding="utf-8" ResponseEncoding="utf-8" %> Fichier web.config <configuration> <system.web> <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="ca-FR" uiCulture="ca-FR" /> </system.web> </configuration> UTF-8 PHP <?php header('Content-type: text/plain; charset=utf-8'); ?> Dans le fichier .htaccess (Apache) AddCharset utf-8 .js
J’utilise personnellement l’UTF-8 par obligation depuis les années 2000, en ajoutant un caractère caché au début du fichier, le BOM (byte order mark). Le validateur de la W3C boguait sur le caractère tout comme les moteur PHP! Il a fini par l’avaler mais il faut attendre 2006 pour que le UTF-8, pourtant vieux comme le Web, soit une solution envisageable sans BOM.
Encore aujourd’hui, 10 ans plus tard (2016), l’UTF-8 est utilisé par 87.6% mais ce chiffre ne représente qu’un potentiel. L’usage des entités HTML, de l’encodage MIME ou Base64 et les nombreux trompe-l’œil reflètent une tout autre réalité... Wikipédia confirme d’ailleurs ma perception. En fouillant un peu lors de l’écriture de ce tutoriel, je tombe sur cette citation :
« Même si l’UTF-8 dépassant les principaux autres codages de caractères de texte sur le Web depuis 2010, la prévalence d’UTF-8 était de l’ordre de 50%. Cette prévalence est estimée à partir du texte et non pas à partir de l’étiquette contenue dans l’entête et le jeu de caractère le plus simple était sélectionné. De ce fait, du texte ASCII, mais avec un entête UTF-8 ou ISO-8859-1 est identifié comme étant de l’ASCII. »
Conclusion en apostrophe!
En conclusion, rien n’est encore réglé en matière de langage. C’est un aspect critique tant pour la culture que pour l’efficacité énergétique dans un monde ou 7 bits suffiraient à synthétiser UNE pensée humaine. J’avais écrit un très gros tutoriel au début des années 2000 sur le sujet, un long voyage épique. Mais il était tellement hypothétique, voire idéaliste, que je ne l’ai jamais publié! Bon, le francophone a une part de responsabilité. J’avais aussi écrit à l’Académie française à cette époque pour leur suggérer une apostrophe numérique francophone en insistant fortement sur sa compatibilité avec la programmation (avantage que l’apostrophe anglaise n’a pas !!!) (celui que j’utilise encore aujourd’hui sur les Trucsweb et pour convertir des millions de textes en français) (et celui qui n’est toujours pas sur nos claviers!!) sans succès. Je me souviens que leur propre site utilisait plus de 3 types d’apostrophes, du leurre à l’apostrophe anglaise. Et à me fier à mon propre travail, c’est évident que toute autre culture utilise sa propre couche de sédiment sur cette fondation précaire! La solution existe depuis des lustres, mais sa méconnaissance pour ne pas dire son mépris entraine un traitement pitoyable de nos communications.
Du coup, comment googler quand plusieurs caractères représentent le seul apostrophe?
Pour ceux qui ne se contentent pas des discours d’apparat Le caractère « ' » est systématique remplacé par le « ’ » par tous mes scripts serveur depuis 2004! C’est à dire l’année de mon courriel à Académie française...
Donc, même si en 2017 j’entrevoie la lueur au bout du tunnel (business as usual), qui n’a pas de problèmes d’accent? Encore hier, un collègue se butait sur l’apostrophe dans le nom d’un dossier (répertoire). Il y a quelques jour, un achat sur Amazone transforme les accents du nom en caractère chinois le plus souvent remplacé à son tout par un point d’interrogation. Signe évident d’un passage l’UTF-16 quelque part dans l’historique de ses multiples transmutations ; -)
Désolé pour mon « français québécois »!
Références
- Codage des caractères
- Qu’est ce qu’Unicode?
- Wikipedia UTF-8
- Wikipedia UTF-16
- Much ADO About Text Files
- List of Unicode characters
- The difference between UTF-8 and Unicode?
- The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) par Joel Spolsky