Fonctionnement des codages

Mise à jour : novembre 2007

En interne, le .NET Framework stocke le texte au format Unicode UTF-16. Un encodeur transforme ces données texte en séquence d'octets. Un décodeur transforme une séquence d'octets en format interne. Un codage décrit les règles qui gouvernent le comportement d'un encodeur ou d'un décodeur. Par exemple, la classe UTF8Encoding décrit les règles qui s'appliquent au codage et au décodage d'une séquence d'octets représentant du texte au format Unicode UTF-8. Le codage et le décodage peuvent également inclure certaines étapes de validation. Par exemple, la classe UnicodeEncoding contrôle tous les substituts afin de vérifier qu'ils constituent des paires de substitution valides. Toutes ces classes héritent de la classe Encoding.

La norme Unicode assigne un point de code (nombre) à chaque caractère de chaque script pris en charge. Le format UTF (Unicode Transformation Format) permet de coder ce point de code. Pour plus d'informations sur les UTF pris en charge par les classes dans System.Text, consultez Utiliser Unicode Encoding dans Unicode dans le .NET Framework.

La classe Encoding est très générale. Les classes prises en charge qui héritent de Encoding permettent aux applications .NET d'utiliser les codages communs qu'elles peuvent rencontrer dans les applications héritées, et les développeurs .NET peuvent implémenter des codages supplémentaires. Toutefois, lorsque vous avez la possibilité de choisir un codage, il est fortement recommandé d'utiliser un codage Unicode, en général UTF8Encoding ou UnicodeEncoding (UTF32Encoding est également pris en charge). En particulier, le UTF8Encoding est préféré à ASCIIEncoding. Si le contenu est ASCII, les deux codages sont identiques, mais le UTF8Encoding peut également représenter tout caractère Unicode, alors que le ASCIIEncoding prend uniquement en charge les valeurs de caractère Unicode comprises entre U+0000 et U+007F. Dans la mesure où le ASCIIEncoding ne fournit pas la détection d'erreurs, le UTF8Encoding est également plus approprié en termes de sécurité.

Le UTF8Encoding a été réglé pour être aussi rapide que possible et doit être plus rapide que tout autre codage. Même pour le contenu qui est entièrement ASCII, les opérations exécutées avec le UTF8Encoding sont plus rapides que les opérations exécutées avec le ASCIIEncoding. Les développeurs doivent utiliser le ASCIIEncoding uniquement pour certaines applications héritées. Toutefois, même dans ce cas, le UTF8Encoding peut encore s'avérer un meilleur choix. Avec les paramètres par défaut, les scénarios suivants peuvent se produire :

  • Si votre application possède du contenu interne qui n'est pas strictement ASCII et que vous le codez avec le ASCIIEncoding, chaque caractère non ASCII sera codé comme un point d'interrogation (« ? »g). Si l'application décode ensuite ces données, les informations sont perdues.

  • Si l'application possède un contenu qui n'est pas strictement ASCII et le code avec UTF8Encoding, le résultat paraît inintelligible s'il est interprété comme ASCII. Toutefois, si l'application décode ensuite ces données, les données exécutent la boucle avec succès.

Choix d'une stratégie de secours

Lorsqu'une application essaie de coder ou décoder un caractère mais aucun mappage n'existe, elle doit implémenter une stratégie de secours, qui est un mécanisme de gestion des défaillances. Il existe deux types de stratégies de secours :

  1. Secours d'ajustement

    Lorsque des caractères n'ont pas de correspondance exacte dans le codage/décodage cible, l'application peut essayer de les mapper ou non à un caractère semblable.

  2. Secours de chaîne de remplacement

    S'il n'y a aucun caractère approprié, l'application peut spécifier une chaîne de remplacement.

Par exemple, une application peut appeler GetEncoding(1252, 0, 0) (consultez GetEncoding). Cet appel spécifie la page de code 1252 (page de codes Windows pour les langues d'Europe de l'Ouest) avec les paramètres encoderFallback et decoderFallback qui ont une valeur égale à zéro. Le comportement par défaut est un mappage ajusté pour certains caractères Unicode. Par exemple, la LETTRE MAJUSCULE LATINE CERCLÉE S (U+24C8) est remplacée par la LETTRE MAJUSCULE LATINE S (U+0053) avant d'être codée ; L'EXPOSANT CINQ (U+2075) est remplacé par le CHIFFRE CINQ (U+0035). Si l'application décode ensuite en arrière de Code Page 1252 à Unicode, le cercle autour de la lettre est perdu et 25 deviennent 25. D'autres conversions peuvent donner des résultats encore plus catastrophiques. Par exemple, le symbole d'INFINITÉ Unicode (U+221E) peut être mappé à CHIFFRE HUIT (U+0038).

Les stratégies d'ajustement varient pour les différentes pages de codes et ne sont pas documentées en détail. Par exemple, pour certaines pages de codes, les caractères latins à pleine chasse sont mappés aux caractères latins à demi-chasse les plus communs. Pour d'autres pages de codes, ce mappage n'est pas fait.

Même avec une stratégie d'ajustement agressive, il n'y a pas d'ajustement possible pour certains caractères dans certains codages. Par exemple, un idéogramme chinois n'a aucun mappage raisonnable dans la page de codes 1252. Dans ce cas, une chaîne de remplacement est utilisée. Par défaut, cette chaîne correspond à un simple POINT D'INTERROGATION (U+003F).

Le mappage ajusté est le comportement par défaut de Encoding, qui code les données Unicode en données de page de codes, et des applications héritées comptent sur ce comportement. Toutefois, la plupart des nouvelles applications doivent éviter le comportement ajusté pour des raisons de sécurité. Par exemple, les applications ne doivent pas appliquer un codage ajusté à un nom de domaine.

Vos applications doivent utiliser les alternatives suivantes pour effectuer au mieux le mappage :

  • Utilisez uniquement les codages Unicode (UTF8Encoding, UnicodeEncoding et UTF32Encoding) pour éviter les problèmes de secours.

    Attention :

    Bien que techniquement, le UTF7Encoding soit un codage Unicode, il est moins fiable et sécurisé que les autres codages. Dans certains cas, la modification d'un bit peut radicalement altérer l'interprétation d'une chaîne UTF-7 entière. Dans d'autres cas, des chaînes UTF-7 relativement différentes peuvent coder le même texte. Par conséquent, lorsque vous avez le choix, n'utilisez pas le codage UTF-7. Le codage UTF-8 est préféré au codage UTF-7.

  • Utilisez EncoderExceptionFallback et DecoderExceptionFallback, qui lèvent une exception (EncoderFallbackException et DecoderFallbackException, respectivement) si un caractère ne correspond pas exactement.

  • Utilisez toujours EncoderReplacementFallback et DecoderReplacementFallback pour substituer une chaîne de remplacement si un caractère ne correspond pas exactement. Il s'agit du comportement par défaut pour ASCIIEncoding. Par défaut, cette chaîne correspond à un point d'interrogation, mais des méthodes permettant à une application de choisir une chaîne différente sont fournies. Bien qu'il s'agisse généralement d'un caractère unique, ce n'est pas une obligation. Pour DecoderReplacementFallback, qui est utilisé lors de la transformation du texte en Unicode, un caractère communément utilisé est le CARACTÈRE DE REMPLACEMENT (U+FFFD).

  • Utilisez un EncoderFallback personnalisé et/ou DecoderFallback pour implémenter une stratégie par défaut. Consultez Application de codage de secours, exemple.

Deux remarques supplémentaires à propos des stratégies de secours du codage (ou décodage) ajustées :

  • L'ajustement est principalement un problème de codage et non de décodage. Très peu de pages de codes contiennent des caractères qui ne peuvent pas être mappés au format Unicode. Puisque ces caractères ne sont pas utilisés communément, ils ont été omis d'Unicode.

  • Il n'y a pas d'objets nommés pris en charge qui correspondent aux meilleurs secours. Le meilleur secours pour chaque page de codes est distinct. Si l’application a besoin de naviguer entre le secours ajusté et d'autres secours pour un objet Encoding unique, elle doit faire une copie de l'objet ajusté d'origine dans une variable avant d'assigner tout autre objet de secours. L'application peut ensuite récupérer le secours ajusté en assignant de nouveau cette valeur à Encoding.EncoderFallback ou Encoding.DecoderFallback.

Ajouts de la communauté

Afficher: