UTF-EBCDIC
UTF-EBCDIC est un codage de caractères utilisé pour représenter les caractères Unicode. Il est conçu pour être compatible avec l’EBCDIC, de sorte que les applications EBCDIC existantes sur les mainframes puissent accepter et traiter les caractères sans grosse difficulté. Ses avantages pour les systèmes existants basés sur l’EBCDIC sont similaires à ceux de l’UTF-8 pour les systèmes basés sur l’ASCII. Les détails sur la transformation UTF-EBCDIC sont définis dans le Rapport technique Unicode n°16 (UTR #16).
Transformation d'un point de code Unicode en séquence UTF-EBCDIC
Transformation intermédiaire UTF-8-Mod
Pour produire la version encodée en UTF-EBCDIC d'une suite de points de code Unicode, une première transformation intermédiaire, similaire à l’UTF-8 (désignée dans les spécifications comme UTF-8-Mod), est d'abord appliquée ; la principale différence entre cette transformation intermédiaire et l’UTF-8 est qu’elle permet de représenter les points de code 0+0080 à U+009F (les caractères de contrôle C1) sur un seul octet, et de continuer à les utiliser en tant que codes de contrôle EBCDIC.
Pour y parvenir, le motif binaire 101xxxxx (présenté dans les tables ci-dessous dans les cellules en fond bleu) a été utilisé au lieu de 10xxxxxx pour représenter les octets finals d’une séquence multi-octet représentant un seul point de code. Puisque cela ne laisse que 5 bits significatifs au lieu de 6 pour les octets finals, l’UTF-EBCDIC produira souvent un résultat un peu plus long que celui obtenu avec l’UTF-8, pour les mêmes données d’entrée. La transformation ne nécessite que des opérations binaires de décalage et de masquage bit à bit, et aucune opération arithmétique (contrairement à ce qui est nécessaire pour le codage UTF-16), elle est donc facilement inversible.
La transformation intermédiaire ne peut produire aucune suite de plus de 6 octets de valeur hexadécimale entre A0 et BF et ceux-ci doivent être immédiatement précédés par un unique octet prenant une valeur hexadécimale entre C4 et FF qui marque le début et la longueur d'une séquence représentant un point de code sur plusieurs octets. Les octets de valeur hexadécimale entre 00 et 9F sont tous inchangés par la transformation et représentent chacun un seul caractère Unicode entre U+0000 et U+009F. Pour la conversion des points de codes standards des normes Unicode et ISO/IEC 10646:2003 actuelles, les séquences produites sont limitées à 1 octet de tête de valeur hexadécimale entre 00 et FA, suivi d'au maximum 4 octets de valeur hexadécimale entre A0 et BF.
Cette transformation ne produit aucune séquence contenant des octets de valeur hexadécimale C0 à C3 ou E0. Des restrictions supplémentaires existent sur les octets de valeur hexadécimale entre A0 et A7 qui ne peuvent pas tous apparaître lorsqu'ils sont produits en seconde position après un octet initial de valeur hexadécimale entre F0 et FC (voir la table ci-dessous). Enfin les octets de valeur hexadécimale entre FB à FF ne sont également pas utilisés pour la transformation des points de code standards des normes Unicode et ISO/IEC 10646:2003 actuelles, mais seulement pour la transformation des anciens points de code du jeu UCS-4 obsolète qui était défini dans l'ancienne norme ISO 10646:2000.
Caractères codés | Représentation binaire UTF-8-Mod | Séquences d'octets valides (en hexadécimal) |
Signification | ||||||
---|---|---|---|---|---|---|---|---|---|
1er | 2e | 3e | 4e | 5e | 6e | 7e | |||
U+0000 à U+001F |
0xxxxxxx | 00 à 1F | — | 1 octet, codant 1 bit nul et 7 bits variables (inclut les caractères de contrôle C0 et le jeu graphique latin de base invariant de l'ISO 646 et la version américaine (ASCII) du jeu graphique latin de base de l'ASCII (commun également à l'ISO 8859-1). Note : parmi les 95 caractères du jeu graphique de l'ISO 646 (codés avec la même valeur scalaire hexadécimale de 20 à 7E dans les normes ISO 10646 et Unicode), l'un d'eux (U+0022) est invariant dans l'ISO 646 (mais varie seulement dans la page de code turque de l'EBCDIC), 13 autres caractères ne font pas partie du jeu invariant de l'ISO 646 (ils correspondent ici au jeu américain ASCII et non à un autre jeu d'une version nationale de l'ISO 646) et varient également dans les pages de code EBCDIC. | |||||
U+0020 à U+007E |
20 à 7E | ||||||||
U+007F | 7F | ||||||||
U+0080 à U+009F |
100xxxxx | 80 à 9F | 1 octet, codant 3 bits fixes et 5 bits variables (inclut les caractères de contrôle C1, plus couramment utilisés sur les systèmes utilisant nativement l'EBCDIC). | ||||||
U+00A0 à U+03FF |
110yyyyy 101xxxxx | C4 à DF | A0 à BF | — | 2 octets, codant 1 bit nul et 10 bits variables (inclut les caractères latins étendus et ponctuations ou symboles les plus courants, les signes diacritiques avec ou sans chasse, ainsi que les caractères grecs et coptes les plus courants). Note : Le premier octet de la séquence intermédiaire produite par la transformation UTF-8-Mod ne peut pas prendre une des valeurs hexadécimales C0 à C3 car le motif binaire yyyyy ne doit pas être inférieur à 00101 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | ||||
U+0400 à U+3FFF |
1110zzzz 101yyyyy 101xxxxx | E1 à EF | A0 à BF | — | 3 octets, codant 1 bit nul et 14 bits variables (inclut les autres caractères du premier quart du plan multilingue de base, dont les autres alphabets, abjads, abugidas ou syllabaires modernes les plus courants, ainsi que des symboles et signes monétaires, des caractères latins et grecs étendus moins fréquents et des extensions phonétiques). Note : le 1er octet de la séquence intermédiaire produite par la transformation UTF-8-Mod ne peut pas prendre la valeur hexadécimale E0 car le motif binaire zzzz ne doit pas être inférieur à 0001 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | ||||
U+4000 à U+3FFFF |
11110www 101zzzzz 101yyyyy 101xxxxx | F0 | A1 à BF | A0 à BF | — | 4 octets, codant 1 bit nul et 18 bits variables (inclut le reste du plan multilingue de base et les 3 premiers plans supplémentaires, dont le plan multilingue supplémentaire et le plan idéographique supplémentaire). Note : lorsque le 1er octet de la séquence intermédiaire produite par la transformation UTF-8-Mod prend la valeur hexadécimale F0, le 2e octet de la séquence ne peut pas prendre la valeur hexadécimale A0 car le motif binaire www zzzzz ne doit pas être inférieur à 000 10000 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | |||
F1 à F7 | A0 à BF | ||||||||
U+40000 à U+10FFFF |
111110rr 101wwwww 101zzzzz 101yyyyy 101xxxxx | F8 | A8 à BF | A0 à BF | — | 5 octets, codant 1 bit nul et 22 bits variables (inclut les 13 derniers plans supplémentaires standards, y compris les 2 derniers plans d'usage privé, ainsi que les 47 premiers plans étendus absents des normes actuelles ISO/CEI 10646:2003 et Unicode mais définis dans le jeu UCS-4 de l'ancienne norme ISO 10646:2000). Note : lorsque le 1er octet de la séquence intermédiaire produite par la transformation UTF-8-Mod prend la valeur hexadécimale F8, le 2e octet de la séquence ne peut pas prendre une des valeurs hexadécimales A0 à A7 car le motif binaire rr wwwww ne doit pas être inférieur à 00 01000 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | |||
F9 | A0 à BF | ||||||||
U-11FFFF à U-3FFFFF |
(FA) à (FB) | A0 à BF | |||||||
U-400000 à U-3FFFFFF |
1111110s 101rrrrr 101wwwww 101zzzzz 101yyyyy 101xxxxx | (FC) | A4 à BF | A0 à BF | — | 6 octets, codant 1 bit nul et 26 bits variables (inclut 1 007 autres plans étendus absents des normes actuelles ISO/CEI 10646:2003 et Unicode mais définis dans le jeu UCS-4 de l'ancienne norme ISO 10646:2000). Note : lorsque le 1er octet de la séquence intermédiaire produite par la transformation UTF-8-Mod prend la valeur hexadécimale FC, le 2e octet de la séquence ne peut pas prendre une des valeurs hexadécimales A0 à A3 car le motif binaire s rrrrr ne doit pas être inférieur à 0 00100 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | |||
(FD) | A0 à BF | ||||||||
U-4000000 à U-7FFFFFFF |
1111111t 101sssss 101rrrrr 101wwwww 101zzzzz 101yyyyy 101xxxxx | (FE) | A2 à BF | A0 à BF | 7 octets, codant 31 bits variables (inclut les 31 744 derniers plans étendus absents des normes actuelles ISO/CEI 10646:2003 et Unicode mais définis dans le jeu UCS-4 de l'ancienne norme ISO 10646:2000). Note : lorsque le 1er octet de la séquence intermédiaire produite par la transformation UTF-8-Mod prend la valeur hexadécimale FE, le 2e octet de la séquence ne peut pas prendre une des valeurs hexadécimales A0 à A1 car le motif binaire t sssss ne doit pas être inférieur à 0 00010 (les points de code correspondants doivent être transformés en séquences plus courtes ci-dessus). | ||||
(FF) | A0 à BF |
Le rapport technique n°16 stipule que le résultat de cette première transformation UTF-8-Mod ne doit pas être utilisé pour les communications entre systèmes. Cette utilisation est interdite du fait aussi qu’elle fait l’objet d’un brevet nécessitant une licence auprès d’IBM (ce qui n’est pas nécessaire en appliquant la seconde transformation ci-dessous qui, en dépit que cette combinaison est également couverte par ce brevet, permet une utilisation libre sans nécessiter de licence préalable car IBM en a accordé les droits d’utilisation).
Permutation finale, compatible avec celle pour la conversion des jeux ISO-8859 vers un jeu compatible avec le jeu EBCDIC invariant
La transformation intermédiaire laisse les données dans un format basé sur l’ISO 8859 (donc aussi compatible avec ISO 646 dont l’ASCII, et avec MIME), aussi une transformation réversible de permutation des valeurs d’octets est opérée sur les séquences d’octets intermédiaires, afin de les rendre aussi proches que possible de l’EBCDIC au moyen de la table de correspondance suivante (la même table qui permet de transformer de façon réversible les codages ISO 8859 en codages compatibles avec toutes les positions invariantes des codages basés sur l’EBCDIC).
Toutefois cela n’est possible que pour les positions invariantes de l’EBCDIC, la table de permutation étant basée directement sur la transformation réversible de la version américaine de l’ISO 646 (communément appelée ASCII) en la version américaine de l’EBCDIC, et la transformation standard des caractères de contrôle C0 (communs entre ASCII, ISO8859 et EBCDIC) et C1 (communs entre ISO 8859 et EBCDIC) : l’UTF-EBCDIC ne définit ni n’utilise aucune autre table de transformation pour les autres versions nationales de l’ISO 646 et de l’EBCDIC (les cases variantes en jaune ci-dessous, ainsi que les cases orange correspondant au caractère "
qui est codé 0x5A dans la plupart des variantes de l’EBCDIC mais varie dans la variante turque, bien qu’il soit invariant et codé en position 0x21 dans toutes les variantes standards de l’ISO 646), ni non plus pour la partie haute des jeux ISO 8859 et la partie étendue de l’EBCDIC, dont tous les caractères varient dans chacun des deux standards (les cases vertes ci-dessous, qui sont mises en correspondance en maintenant seulement l’ordre relatif des codets dans chacun des deux types de jeux de caractères, afin de compléter les permutation manquantes).
Quartet haut |
Quartet bas (toutes les valeurs sont en hexadécimal) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
...0 | ...1 | ...2 | ...3 | ...4 | ...5 | ...6 | ...7 | ...8 | ...9 | ...A | ...B | ...C | ...D | ...E | ...F | |
0... | 00 | 01 | 02 | 03 | 37 | 2D | 2E | 2F | 16 | 05 | 15 | 0B | 0C | 0D | 0E | 0F |
1... | 10 | 11 | 12 | 13 | 3C | 3D | 32 | 26 | 18 | 19 | 3F | 27 | 1C | 1D | 1E | 1F |
2... | 40 | 5A | 7F | 7B | 5B | 6C | 50 | 7D | 4D | 5D | 5C | 4E | 6B | 60 | 4B | 61 |
3... | F0 | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | 7A | 5E | 4C | 7E | 6E | 6F |
4... | 7C | C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9 | D1 | D2 | D3 | D4 | D5 | D6 |
5... | D7 | D8 | D9 | E2 | E3 | E4 | E5 | E6 | E7 | E8 | E9 | AD | E0 | BD | 5F | 6D |
6... | 79 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 |
7... | 97 | 98 | 99 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | C0 | 4F | D0 | A1 | 07 |
8... | 20 | 21 | 22 | 23 | 24 | 25 | 06 | 17 | 28 | 29 | 2A | 2B | 2C | 09 | 0A | 1B |
9... | 30 | 31 | 1A | 33 | 34 | 35 | 36 | 08 | 38 | 39 | 3A | 3B | 04 | 14 | 3E | FF |
A... | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 4A | 51 | 52 | 53 | 54 | 55 | 56 |
B... | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 6A | 70 | 71 | 72 | 73 |
C... | (74) | (75) | (76) | (77) | (78) | 80 | 8A | 8B | 8C | 8D | 8E | 8F | 90 | 9A | 9B | 9C |
D... | 9D | 9E | 9F | A0 | AA | AB | AC | AE | AF | B0 | B1 | B2 | B3 | B4 | B5 | B6 |
E... | (B7) | B8 | B9 | BA | BB | BC | BE | BF | CA | CB | CC | CD | CE | CF | DA | DB |
F... | DC | DD | DE | DF | E1 | EA | EB | EC | ED | EE | (EF) | (FA) | (FB) | (FC) | (FD) | (FE) |
Notes :
La table montre en italique et petits caractères entre parenthèses (sur un fond vert assombri) les entrées correspondantes, non conformes aux normes ISO 10646 et Unicode actuelles et donc non interopérables. |
Transformation inverse de l’UTF-EBCDIC vers un point de code Unicode
Ces deux étapes précédentes peuvent être facilement inversées pour retrouver les points de code Unicode.
- La seconde étape sera d’abord inversée par l'utilisation d’une seconde table de permutation inverse (ci-dessous), pour produire des séquences d’octets transformées en UTF-8-Mod : cette table est en fait une table de permutation des 256 valeurs possibles d’octets, et est l’exacte inverse de la table de la section précédente.
- Puis la première étape sera inversée algorithmiquement.
Quartet haut |
Quartet bas (toutes les valeurs sont en hexadécimal) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
...0 | ...1 | ...2 | ...3 | ...4 | ...5 | ...6 | ...7 | ...8 | ...9 | ...A | ...B | ...C | ...D | ...E | ...F | |
0... | 00 | 01 | 02 | 03 | 9C | 09 | 86 | 7F | 97 | 8D | 8E | 0B | 0C | 0D | 0E | 0F |
1... | 10 | 11 | 12 | 13 | 9D | 0A | 08 | 87 | 18 | 19 | 92 | 8F | 1C | 1D | 1E | 1F |
2... | 80 | 81 | 82 | 83 | 84 | 85 | 17 | 1B | 88 | 89 | 8A | 8B | 8C | 05 | 06 | 07 |
3... | 90 | 91 | 16 | 93 | 94 | 95 | 96 | 04 | 98 | 99 | 9A | 9B | 14 | 15 | 9E | 1A |
4... | 20 | A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | 2E | 3C | 28 | 2B | 7C |
5... | 26 | AA | AB | AC | AD | AE | AF | B0 | B1 | B2 | 21 | 24 | 2A | 29 | 3B | 5E |
6... | 2D | 2F | B3 | B4 | B5 | B6 | B7 | B8 | B9 | BA | BB | 2C | 25 | 5F | 3E | 3F |
7... | BC | BD | BE | BF | (C0) | (C1) | (C2) | (C3) | (C4) | 60 | 3A | 23 | 40 | 27 | 3D | 22 |
8... | C5 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | C6 | C7 | C8 | C9 | CA | CB |
9... | CC | 6A | 6B | 6C | 6D | 6E | 6F | 70 | 71 | 72 | CD | CE | CF | D0 | D1 | D2 |
A... | D3 | 7E | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 7A | D4 | D5 | D6 | 5B | D7 | D8 |
B... | D9 | DA | DB | DC | DD | DE | DF | (E0) | E1 | E2 | E3 | E4 | E5 | 5D | E6 | E7 |
C... | 7B | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | E8 | E9 | EA | EB | EC | ED |
D... | 7D | 4A | 4B | 4C | 4D | 4E | 4F | 50 | 51 | 52 | EE | EF | F0 | F1 | F2 | F3 |
E... | 5C | F4 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 5A | F5 | F6 | F7 | F8 | F9 | (FA) |
F... | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | (FB) | (FC) | (FD) | (FE) | (FF) | 9F |
Notes :
|
Détection des octets de tête dans les textes contenant des séquences UTF-EBCDIC
Quartet haut |
Quartet bas (toutes les valeurs sont en hexadécimal) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
...0 | ...1 | ...2 | ...3 | ...4 | ...5 | ...6 | ...7 | ...8 | ...9 | ...A | ...B | ...C | ...D | ...E | ...F | |
0... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4... | 1 | • | • | • | • | • | • | • | • | • | • | 1 | 1 | 1 | 1 | 1 |
5... | 1 | • | • | • | • | • | • | • | • | • | 1 | 1 | 1 | 1 | 1 | 1 |
6... | 1 | 1 | • | • | • | • | • | • | • | • | • | 1 | 1 | 1 | 1 | 1 |
7... | • | • | • | • | (2) | (2) | (2) | (2) | (2) | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
8... | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 |
9... | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 |
A... | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 1 | 2 | 2 |
B... | 2 | 2 | 2 | 2 | 2 | 2 | 2 | (3) | 3 | 3 | 3 | 3 | 3 | 1 | 3 | 3 |
C... | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 3 | 3 | 3 | 3 | 3 | 3 |
D... | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 3 | 3 | 4 | 4 | 4 | 4 |
E... | 1 | 4 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 4 | 4 | 4 | 5 | 5 | (5) |
F... | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | (5) | (6) | (6) | (7) | (7) | 0 |
Légende | ||||||||||||||||
0 | Caractère de contrôle C0 représenté sur 1 octet | |||||||||||||||
0 | Caractère de contrôle C1 représenté sur 1 octet | |||||||||||||||
1 | Caractère graphique variant dans l’ISO 646 ou EBCDIC représenté sur 1 octet | |||||||||||||||
1 | Caractère graphique invariant dans l’ISO 646 mais variant dans l’EBCDIC représenté sur 1 octet | |||||||||||||||
1 | Caractère graphique invariant de l’ISO 646 et EBCDIC représenté sur 1 octet | |||||||||||||||
(2) | Premier octet d’une séquence non standard codée sur 2 octets pouvant représenter une valeur prise dans un ensemble comptant jusqu’à 160 éléments (voir la note 1) | |||||||||||||||
2 | Premier octet d’une séquence UTF-EBCDIC codée sur 2 octets qui représente un point de code de U+00A0 à U+03FF | |||||||||||||||
(3) | Premier octet d’une séquence non standard codée sur 3 octets pouvant représenter une valeur prise dans un ensemble comptant jusqu’à 1024 éléments (voir la note 1) | |||||||||||||||
3 | Premier octet d’une séquence UTF-EBCDIC codée sur 3 octets qui représente un point de code de U+400 à U+3FFF | |||||||||||||||
4 | Premier octet d’une séquence UTF-EBCDIC codée sur 4 octets qui représente un point de code de U+4000 à U+3FFFF (ces points de code incluent ceux du plan multilingue de base et ceux des trois premiers plans supplémentaires communs aux normes Unicode et ISO 10646) | |||||||||||||||
5 | Premier octet d’une séquence UTF-EBCDIC codée sur 5 octets qui représente un point de code de U+40000 à U+10FFFF (ces points de code incluent ceux des treize autres plans supplémentaires communs à la norme Unicode et à la version actuelle de la norme ISO 10646) | |||||||||||||||
(5) | Premier octet d’une séquence UTF-EBCDIC codée sur 5 octets qui représente un point de code étendu de l’ancienne norme ISO 10646:2000 (voir la note 2) | |||||||||||||||
(6) | Premier octet d’une séquence UTF-EBCDIC codée sur 6 octets qui représente un point de code étendu de l’ancienne norme ISO 10646:2000 (voir la note 2) | |||||||||||||||
(7) | Premier octet d’une séquence UTF-EBCDIC codée sur 7 octets qui représente un point de code étendu de l’ancienne norme ISO 10646:2000 (voir la note 2) | |||||||||||||||
• | Octet de queue d’un caractère codé sur plusieurs octets dont chacun représente un groupe de 5 bits (en les codant dans l’ordre des bits de poids décroissant jusqu’au bit le plus faible) dans la valeur scalaire du point de code | |||||||||||||||
Notes :
La table montre en italique et petits caractères entre parenthèses — (2), (3) et de (5) à (9) sur un fond vert assombri — les entrées correspondantes qui ne sont pas conformes aux normes ISO 10646 et Unicode actuelles, donc non interopérable : leur utilisation ne peut être que locale et privée, et de telles séquences contenant ces octets ne doivent pas être échangés avec d’autres systèmes où ils seront couramment considérés comme non valides. La table de drapeaux effective (utilisant une définition strictement conforme aux normes interopérables actuelles) peut donc contenir un nombre plus réduit de valeurs (entre 0 et 5 dans la table ci-dessus pour les drapeaux des octets de tête standards, ainsi qu’une valeur notée par une puce • dans la table ci-dessus, mais qui peut être remplacée par 6 pour indiquer les octets de queue, la valeur 7 restant également utilisable pour indiquer toutes les positions non conformes aux normes actuelles, ce qui permet de coder les entrées de la table de drapeaux sur 3 bits). |
Un défaut de l’UTF-EBCDIC est qu’il n’est pas simple de détecter, dans un texte codé en UTF-EBCDIC, quels octets délimitent chaque séquence.
En effet, ils sont dispersés parmi les 256 valeurs possibles (voir les 32 positions marquées en bleu dans les tables ci-dessus pour coder les octets de queue qui suivent un des 32 différents octets aux positions marquées en vert qui indiquent le début et la longueur d'une séquence UTF-EBCDIC), et la technique courante nécessite une table de correspondance permettant de savoir si un octet isolé représente un caractère (sauf pour les codes de contrôle C0 et C1 groupés entre 0x00 et 0x3F ou le caractère d’oblitération (DEL) codé 0xFF dans toutes les versions de l’EBCDIC), ou si c'est un octet de queue ou un octet de tête indiquant la longueur effective de la séquence.
Cette table de correspondance est décrite dans le Rapport technique n°16 et contient des drapeaux (shadow flags) pour chaque valeur d’octet possible. Son coût algorithmique et en termes de performance est non négligeable, et finalement similaire à celui de la table de permutation utilisée dans la deuxième étape de transformation depuis l’UTF-EBCDIC. Son intérêt reste très limité en termes de performance, puisqu’il faut encore traiter spécialement les octets finals (tous identifiés par le même drapeau car on ne peut connaître leur position relative dans la séquence uniquement depuis leur seule valeur d’octet) et procéder à des boucles supplémentaires de lecture et de test pour trouver le premier octet de la séquence.
Aussi, de nombreuses implémentations de l’UTF-EBCDIC se contentent uniquement de la table de permutation inverse des octets UTF-EBCDIC vers UTF-8-Mod (présentée dans la section précédente), et se passent de la table de drapeaux. Ils effectuent alors un simple test de valeur sur la valeur d’octet intermédiaire UTF-8-Mod retournée par cette table de permutation inverse, sachant que dans UTF-8-Mod, les octets de queue obéissent tous à la condition très simple à tester (écrite ici en syntaxe des langages C, C++, Java ou C#) :
- (octet & 0xE0) == 0xA0
- Si cet octet vérifie cette condition mais s’il n'y a pas d'autre octet codé avant lui, la séquence n’est pas valide.
- Si cet octet vérifie cette condition et qu’il y a un autre octet codé juste avant lui, c’est un octet de queue qu'on doit compter : la séquence n’est pas valide s’il on a alors déjà compté jusqu’à 5 octets de queue (ou jusqu’à 7, si on autorise comme valides les caractères du jeu UCS-4 obsolète), sinon on doit boucler le test en se plaçant sur l’octet codé juste avant.
- Si cet octet ne vérifie pas cette condition, c’est alors un octet de tête, dont l’intervalle de valeur détermine sa validité ainsi que celle des 1 à 4 octets de queue (ou jusqu’à 6, si on autorise comme valides les caractères du jeu UCS-4 obsolète) qui doivent nécessairement le suivre (d’après la première table qui montre les seules séquences valides) et qui doivent chacun être vérifiés.
Utilisation de l’UTF-EBCDIC
Généralement, cet encodage est rarement utilisé, même sur les mainframes basé sur l’EBCDIC et pour lesquels cet encodage a été conçu. Les systèmes de mainframes IBM basés sur l’EBCDIC, comme z/OS ou MVS, utilisent aujourd’hui généralement l’UTF-16 pour un support complet d’Unicode : par exemple, DB2 UDB, COBOL, PL/I, Java et la boîte d’outils IBM pour XML supportent tous l’UTF-16 sur les systèmes IBM.
Extension sur 32 bits à usage interne
La transformation UTF-EBCDIC peut être parfois étendue pour faciliter les traitements internes, en considérant que les séquences UTF-EBCDIC limitées à 4 octets peuvent coder tout point de code jusqu’à la fin du plan supplémentaire n°3 (c'est-à-dire jusqu’à U+3FFFF). Ainsi, il est possible de représenter (de façon interne uniquement) tous les points de code du plan multilingue de base sous une forme comparable à l’UTF-16, en représentant aussi les codes de demi-zone (surrogates) de l’UTF-16. On obtient alors facilement un codet sur 32 bits, qui reste compatible avec l’EBCDIC pour chaque point de code du BMP, et deux codets de 32 bits chacun pour représenter les points de code des plans supplémentaires.
Cette représentation alternative ne doit pas être utilisée dans les échanges entre systèmes, mais uniquement pour faciliter et optimiser les interfaces de programmation interne où les caractères EBCDIC sont échangés dans des codets (en mémoire) de 32 bits, ce qui limite alors le nombre de tests de valeurs et évite le recours systématique aux tables de permutation pour tester les étendues de caractères lors de traitements complexes ou volumineux de textes (l’utilisation systématique des tables de permutation est une opération coûteuse en termes de performance, si on la compare à un simple test basé sur les intervalles de valeurs des codets de 32 bits).
Actuellement cette représentation interne n’a aucune dénomination officielle bien définie, même si certains l’appellent UTF-16-Mod ou UTF-16-EBCDIC (dénominations impropres car cette transformation crée des codets de 32 bits représentant chacun un codet de 16 bits de l’UCS-2).
Son intérêt par rapport à la représentation intermédiaire UTF-8-Mod est qu’il devient possible d’éviter l’utilisation de toute table pour savoir si un codet est le premier d’une séquence ou l’un des codets finals. En effet, les codets des demi-zones de l’UTF-16 (qui permettent de savoir si un codet est le premier ou le second d’une séquence) sont représentés aussi dans des intervalles contigus de codets sur 32 bits dans cette représentation, ce qui facilite leur détection par un test arithmétique uniquement et qui permet de savoir si un codet 32-bit est le premier ou le second représentant un point de code supplémentaire, ou si le codet de 32 bits est isolé et représente un point de code du BMP. D’autre part, cette représentation interne préserve aussi les valeurs de tous les caractères EBCDIC invariants.
Toutefois la transformation d’une séquence UTF-EBCDIC dans cette représentation interne sur 32 bits nécessite de savoir quels octets délimitent une séquence UTF-EBCDIC, ce qui nécessite une table de drapeaux (appelée show flags) pour interpréter correctement l’UTF-EBCDIC. Mais l’inverse est immédiat et ne nécessite aucune table (la transformation inverse se faisant par simple décalages binaires et tests des valeurs nulles pour savoir si un ou plusieurs octets doivent être émis dans l’UTF-EBCDIC.
Si le stockage n’est pas important et ne concerne que des quantités limitées de caractères, cette représentation sera plus rapide (par exemple comme étape intermédiaire pour transformer un texte UTF-EBCDIC en majuscules quand on dispose de tables ou d'algorithmes basées sur l’EBCDIC, ou comme étape intermédiaire du calcul de clés de collation basées sur l’EBCDIC ou l’UTF-EBCDIC, ou en interne dans des analyseurs lexicaux traitant des textes codés en EBCDIC ou UTF-EBCDIC).
Par contre, son principal défaut est évidemment sa taille, double de l’UTF-16 (c’est pourquoi les bases de données préfèrent indexer ou stocker les textes et clés de recherche en utilisant l’UTF-16 plus compact).