Encodage et UTF-8 Dernière Modification le : 2024-02-19 Le ZIP des Ressources A lire absoluement https://www.invivoo.com/resoudre-vos-problemes-dencodage-unicode/ https://www.invivoo.com/en/how-to-solve-unicode-encoding-issues/ On butte sur un os... Quelques exemples... utf8-debug est une page Web qui visualise les différentes substitutions d'encodage : Lire → (les autres pages sont dans l'archive) Microsoft fournit une liste de référence des encodages Lire → Cette page Web vous permet de tester différentes chaînes de caractères ou des fichiers et d'afficher leur représentation dans différents jeux de caractères et encodages, y compris UTF-8, ISO-8859-1, Windows-1252... freeformatter.com → Dans le ZIP de ressources, j'ai mis un jeu de six fichiers texte qui représentent cinq codages de caractères différents et six langues différentes. Les encodages de caractères représentés dans ce jeu de données sont ISO-8859-1 (également connu sous le nom de Latin 1), ASCII, Windows 1251, UTF-16 qui a été converti avec succès en UTF-8 et BIG-5. De plus amples informations sur les fichiers sont disponibles dans le fichier file_guide.csv. Plusieurs Codes Pages pour le prix d'un! Il y a en fait plusieurs codes pages qui s'appliquent parfois à de vieux utilitaires. Le code page utilisé par la console (CMD) est 'CHANGE', CHCP Page de Codes OEM (OEMCP) : age de codes utilisée par les applications console qui ne prennent pas en charge Unicode Page de Codes ANSI (ACP) : La page de codes ANSI est utilisée par les applications Windows non Unicode. Page de Codes Macintosh (MACCP) : était plus pertinente pour l'interaction entre Windows et Macintosh. Page de Codes EBCDIC (EBCDICCP) : principalement dans les systèmes mainframe et pas couramment en Windows moderne Sur les PC 'Desktop' c'est UTF-8, pour tous. Cependant, pour le serveur, c'est ... Un script peur donc avoir un comportement different selon qu'on est en desk ou sur le serveur ! CodePage Serveur DeskTop CHCP 850 65001 (=UTF-8) ACP 1252 65001 (=UTF-8) OEMCP 850 65001 (=UTF-8) MACCPEBCDICCP 10000 65001 (=UTF-8) On a le probleme avec ZIP (Windows) si on veut envoyer un dossier compressé sur un système Occidental ou moderne vers un Windows Asiatique un peu ancien... ou même avec 7-Zip (7-Zip ne permet pas explicitement de choisir un encodage autre qu'UTF-8 via la ligne de commande) FSO FileSystemObject et tristate L'option finale a 3 valeurs possibles (tristate...). La valeur 0 encode en ASCII, quel que soit le PC. FSO Serveur DeskTop -1 Unicode donc UTF-16 LE Unicode donc UTF-16 LE -2 CP850 65001 (=UTF-8) Donc si on veut UFT-8 sur le serveur, il faut utiliser ADODB.STREAM à la place de FSO Détection de l'encodage L'outil populaire pour le faire à la main est NotePad++. LibreOffice, aussi... Sur le serveur, on peut parfois utiliser ICONV. Mais peut-être pas toujours... "C:\...\iconv.exe" -f ascii -t Windows-1252 "C:\...\yan_BIG-5.txt" 1> NUL répond iconv: C:\...\yan_BIG-5.txt: ne peut convertir Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("input.txt", 1) If objFile.AtEndOfStream Then WScript.Echo "Le fichier est vide." Else strLine = objFile.ReadLine If IsNull(strLine) Then WScript.Echo "Le fichier est binaire et ne peut pas être lu en texte." Else strEncoding = "Inconnu" If objFile.CodePage = 1252 Then strEncoding = "Windows-1252 (ANSI)" ElseIf objFile.CodePage = 65001 Then strEncoding = "UTF-8" End If WScript.Echo "L'encodage du fichier est : " & strEncoding End If End If objFile.Close Set objFile = Nothing Set objFSO = Nothing Le Tables de conversion https://stackoverflow.com/questions/42250575/iconv-translit-table-of-characters The table is defined in the file translit.def. You may find it inside the libiconv. The library might be download at: https://ftp.gnu.org/gnu/libiconv/. I've extracted the first few lines of the table, which are displayed bellow: conversion de MS-DOS (= CP850, c'est le CodePage de mon serveur) à UTF-8 Lire → Conversion par script avec ICONV Quand on convertit avec ICONV, il faut capturer la sortie avec 1>, qui utilise l'encodage par défaut de la cession CMD. Il peut être nécessaire de forcer CMD à écrire dans l'encodage souhaité en ajoutant CHCP xxx en première ligne. C'est peut être utile voire nécessaire pour s'assurer qu'un fichier .CSV est bien au bon encodage avant d'utiliser BCP. C'est le cas sur mon serveur, vraiment vieillot!, qui est en CHCP 850 (MS-DOS Latin1), La conversion est toujours partiellement possible. Les chiffres 'arabes' sont universels et ne posent pas de problèmes. Là où il y a potentiellement problème, il faut définir une stratégie a priori. Substituer à 'notre mode' avec un script Bloquer la conversion (avec... Rien, c'est à dire, par défaut) Substituer à la mode 'ICONV' avec //TRANSLIT Ignorer avec //IGNORE GNUwin32 décrit les flags de son ICONV Lire → La liste de translitération est accessible selon l'explication ici → . J'en mets une copie (.txt encodé en UTF-8) dans les ressources et en HTML (charset=utf-8 et balise pre): Lire →. Chez moi, //TRANSLIT//IGNORE n'est pas supportée... On peut éventuellement instruire de faire des conversions à la demande, ce que, en pratique, je n'utilise pas. Détecter la présence de caractères de substitution Lors de la lecture ou écriture d'un Fichier UTF-8 (ou pas) avec ré-écriture qu'on pourrait penser satisfaisante, si vous avez une erreur de programmation ou de gestion d'encodage, des caractères de substitution peuvent apparaitre soit sous la forme de ? ou losange noir... En pratique, en UTF-8, le seul et unique "caractère de substitution" est la séquence de caractères hexadécimaux EF BF BD (�). Il existe d'autres séquences importantes dans l'encodage UTF-8, notamment celles utilisées pour encoder des caractères spécifiques : Byte Order Mark (BOM) : la séquence EF BB BF est utilisée comme marqueur d'ordre des octets (BOM) en UTF-8. Elle est optionnelle et généralement non recommandée pour les fichiers UTF-8, car l'ordre des octets n'est pas pertinent dans cet encodage. Caractères de Contrôle : Il existe plusieurs séquences qui représentent des caractères de contrôle dans l'UTF-8. Par exemple, 00 représente le caractère NULL, et 0A représente le saut de ligne (LF). Caractères Non-ASCII : UTF-8 est conçu pour être rétrocompatible avec ASCII. Les caractères ASCII (de 00 à 7F) sont représentés par un seul octet en UTF-8, identique à leur représentation ASCII. Les caractères au-delà de la plage ASCII utilisent des séquences de 2 à 4 octets. Par exemple, le caractère 'é' (é accent aigu) est représenté par C3 A9 en UTF-8. Caractères Surrogates : Dans le système de codage UTF-16, certains caractères sont représentés par des paires de surrogates. En UTF-8, ces caractères sont représentés par des séquences de 3 ou 4 octets. Par exemple, les caractères emoji sont souvent représentés par des séquences de 4 octets en UTF-8. Caractères Illégaux : Certaines séquences d'octets ne sont pas autorisées en UTF-8, car elles ne correspondent à aucun caractère valide ou sont utilisées pour coder des caractères d'une manière non conforme à la norme UTF-8. Lorsqu'un logiciel rencontre de telles séquences, il peut les remplacer par le caractère de substitution EF BF BD. Voici un code qui lit et détecte la présence de la séquence de substitution: EF BF BD Function BinaryToHex(binary) ' // Dim i, hexa hexa = "" For i = 1 To LenB(binary) hexa = hexa & Right("0" & Hex(AscB(MidB(binary, i, 1))), 2) Next BinaryToHex = hexa End Function Function ContainsEFBFBD(filePath) Dim stream, binaryData, hexData Set stream = CreateObject("ADODB.Stream") stream.Type = 1 ' Binary stream.Open stream.LoadFromFile(filePath) binaryData = stream.Read stream.Close hexData = BinaryToHex(binaryData) If InStr(hexData, "EFBFBD") > 0 Then ContainsEFBFBD = True Else ContainsEFBFBD = False End If End Function ' Exemple d'utilisation 'Dim filePath 'filePath = "chemin_du_fichier" 'If ContainsEFBFBD(filePath) Then ' WScript.Echo "Le fichier contient la séquence EFBFBD." 'Else ' WScript.Echo "La séquence EFBFBD n'est pas présente dans le fichier." 'End If Da Function CountEFBFBD(filePath) Dim stream, binaryData Set stream = CreateObject("ADODB.Stream") stream.Type = 1 ' Binary stream.Open stream.LoadFromFile(filePath) binaryData = stream.Read stream.Close ' Compter les occurrences de la séquence EFBFBD Dim i, count count = 0 For i = 1 To LenB(binaryData) - 2 If AscB(MidB(binaryData, i, 1)) = &HEF And _ AscB(MidB(binaryData, i + 1, 1)) = &HBF And _ AscB(MidB(binaryData, i + 2, 1)) = &HBD Then count = count + 1 End If Next CountEFBFBD = count End Function ' Exemple d'utilisation Dim filePath filePath = "chemin_du_fichier" Dim occurrences occurrences = CountEFBFBD(filePath) WScript.Echo "Nombre d'occurrences de la séquence EFBFBD : " & occurrences L'objet ADODB.Stream ne fournit pas directement une option pour ignorer la BOM (Byte Order Mark) lors de la lecture de fichiers. Toutefois, vous pouvez contourner ce problème en lisant d'abord les premiers octets du fichier pour vérifier la présence de la BOM, puis en continuant la lecture du reste du fichier si nécessaire. Voici un exemple général de la façon dont vous pourriez procéder : Ouvrir le fichier en mode binaire : Commencez par ouvrir le fichier en mode binaire pour lire les premiers octets. Lire les premiers octets : Lisez les premiers octets du fichier pour déterminer s'ils correspondent à la BOM UTF-8 (EF BB BF). Repositionner le pointeur de flux : Si la BOM est présente, positionnez le pointeur de flux juste après la BOM. Si la BOM n'est pas présente, repositionnez le pointeur au début du fichier. Lire le reste du fichier : Changez le mode en texte (avec l'encodage UTF-8 si nécessaire) et lisez le reste du fichier. Voici un exemple de code en VBScript illustrant cette approche : Dim objStream Set objStream = CreateObject("ADODB.Stream") objStream.Type = 1 ' Binary objStream.Open objStream.LoadFromFile("chemin_du_fichier") ' Lire les premiers 3 octets Dim bom bom = objStream.Read(3) ' Vérifier la BOM pour UTF-8 (EF BB BF) If bom <> ChrB(&HEF) & ChrB(&HBB) & ChrB(&HBF) Then ' Pas de BOM, remettre le pointeur au début objStream.Position = 0 End If ' Changer le type en texte et définir l'encodage objStream.Type = 2 ' Text objStream.CharSet = "utf-8" Dim text text = objStream.ReadText ' Traiter le texte... ' ... objStream.Close Bug d'encodage : des octets UTF-8 vu en Windows-1252 ou ISO-8859-1 Au lieu d'un caractère attendu, une séquence de caractères latins est affichée, commençant généralement par à ou Â. Par exemple, au lieu de "è", ces caractères apparaissent : "è". Explication : les caractères encodés en UTF-8 ont leurs octets individuels interprétés en ISO-8859-1 ou Windows-1252. Par exemple, sur une page web est codée en caractères UTF-8, si le serveur ou le navigateur déclare, par erreur, que le jeu de caractères est ISO-8859-1, le navigateur affichera alors chacun des octets UTF-8 de la page web comme des caractères latins-1. Un caractère tel que è (e-Grave, U+00E8) se compose de deux octets en UTF-8 : 0xC3 et 0xA8. Si chacun de ces octets est traité comme un point de code ISO-8859-1 ou Windows-1252, les caractères affichés seront à et ¨. Précedent Suivant