4. Syntaxe des séquences d'octets UTF-8
Pour la commodité des implémenteurs utilisant ABNF, une définition d'UTF-8 en syntaxe ABNF est donnée ici.
Définition d'une chaîne UTF-8
Une chaîne UTF-8 est une séquence d'octets représentant une séquence de caractères UCS. Une séquence d'octets constitue de l'UTF-8 valide uniquement si elle correspond à la syntaxe suivante, laquelle découle des règles de codage d'UTF-8 et est exprimée dans l'ABNF du [RFC2234].
Syntaxe ABNF
UTF8-octets = *( UTF8-char )
UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
UTF8-1 = %x00-7F
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
%xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
%xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
Explication de la syntaxe
UTF8-1 : séquences d'un octet
%x00-7F
- Plage : 0x00 à 0x7F (0-127)
- Codage : plage ASCII complète
- Motif :
0xxxxxxx
UTF8-2 : séquences de deux octets
%xC2-DF UTF8-tail
- Premier octet : 0xC2 à 0xDF (194-223)
- Octet de continuation : 0x80 à 0xBF (128-191)
- Motif :
110xxxxx 10xxxxxx - Remarque : le premier octet ne peut pas être 0xC0 ou 0xC1 (cela produirait un codage trop long)
UTF8-3 : séquences de trois octets
Quatre cas :
Cas 1 : %xE0 %xA0-BF UTF8-tail
- Premier octet : 0xE0
- Deuxième octet : 0xA0 à 0xBF
- Troisième octet : 0x80 à 0xBF
- Plage codée : U+0800 à U+0FFF
Cas 2 : %xE1-EC 2( UTF8-tail )
- Premier octet : 0xE1 à 0xEC
- Octets suivants : deux UTF8-tail (0x80-0xBF)
- Plage codée : U+1000 à U+CFFF
Cas 3 : %xED %x80-9F UTF8-tail
- Premier octet : 0xED
- Deuxième octet : 0x80 à 0x9F
- Troisième octet : 0x80 à 0xBF
- Plage codée : U+D000 à U+D7FF
- Remarque : évite la plage des paires de substitution (U+D800-U+DFFF)
Cas 4 : %xEE-EF 2( UTF8-tail )
- Premier octet : 0xEE à 0xEF
- Octets suivants : deux UTF8-tail
- Plage codée : U+E000 à U+FFFF
UTF8-4 : séquences de quatre octets
Trois cas :
Cas 1 : %xF0 %x90-BF 2( UTF8-tail )
- Premier octet : 0xF0
- Deuxième octet : 0x90 à 0xBF
- Octets suivants : deux UTF8-tail
- Plage codée : U+10000 à U+3FFFF
Cas 2 : %xF1-F3 3( UTF8-tail )
- Premier octet : 0xF1 à 0xF3
- Octets suivants : trois UTF8-tail
- Plage codée : U+40000 à U+FFFFF
Cas 3 : %xF4 %x80-8F 2( UTF8-tail )
- Premier octet : 0xF4
- Deuxième octet : 0x80 à 0x8F
- Octets suivants : deux UTF8-tail
- Plage codée : U+100000 à U+10FFFF
Valeurs d'octets invalides
Les valeurs d'octets suivantes n'apparaissent jamais dans des séquences UTF-8 valides :
Prohibited byte values:
- 0xC0, 0xC1 (would produce overlong 2-byte sequences)
- 0xF5 - 0xFF (beyond Unicode range)
Récapitulatif complet des plages d'octets
| Plage de valeurs d'octets | Signification | Validité |
|---|---|---|
| 0x00-0x7F | Caractère d'un octet (ASCII) | ✅ Valide |
| 0x80-0xBF | Octet de continuation | ✅ Valide uniquement en position de continuation |
| 0xC0-0xC1 | Interdit | ❌ Invalide |
| 0xC2-0xDF | Premier octet d'une séquence de 2 octets | ✅ Valide |
| 0xE0-0xEF | Premier octet d'une séquence de 3 octets | ✅ Valide |
| 0xF0-0xF4 | Premier octet d'une séquence de 4 octets | ✅ Valide |
| 0xF5-0xFF | Interdit | ❌ Invalide |
Exemples de validation
Séquences valides
Example 1: 0x41
Check: 0x41 in [0x00-0x7F] → UTF8-1 → ✅ Valid
Character: 'A'
Example 2: 0xC2 0xA9
Check: 0xC2 in [0xC2-0xDF], 0xA9 in [0x80-0xBF] → UTF8-2 → ✅ Valid
Character: '©'
Example 3: 0xE4 0xBD 0xA0
Check: 0xE4 in [0xE1-0xEC], next two bytes in [0x80-0xBF] → UTF8-3 → ✅ Valid
Character: '你'
Example 4: 0xF0 0x9F 0x98 0x80
Check: 0xF0 followed by 0x9F in [0x90-0xBF], next two bytes in [0x80-0xBF] → UTF8-4 → ✅ Valid
Character: '😀'
Séquences invalides
Example 1: 0xC0 0x80
Problem: 0xC0 is prohibited → ❌ Invalid (overlong encoding)
Example 2: 0xED 0xA0 0x80
Problem: 0xED followed by 0xA0 not in [0x80-0x9F] → ❌ Invalid (surrogate pair range)
Example 3: 0xF5 0x80 0x80 0x80
Problem: 0xF5 is prohibited → ❌ Invalid (beyond Unicode range)
Example 4: 0xE4 0xBD
Problem: 3-byte sequence incomplete → ❌ Invalid (truncated)
⚠️ Remarque importante
NOTE -- La définition faisant autorité d'UTF-8 se trouve dans [UNICODE]. Cette grammaire est réputée décrire la même chose qu'Unicode, mais ne prétend pas faire autorité. Les implémenteurs sont invités à se fonder sur la source faisant autorité plutôt que sur le présent ABNF.
Conseil d'implémentation
Pseudo-code de l'algorithme de validation
def is_valid_utf8(bytes):
i = 0
while i < len(bytes):
b = bytes[i]
if b <= 0x7F: # UTF8-1
i += 1
elif 0xC2 <= b <= 0xDF: # UTF8-2
if i + 1 >= len(bytes) or not (0x80 <= bytes[i+1] <= 0xBF):
return False
i += 2
elif b == 0xE0: # UTF8-3 case 1
if i + 2 >= len(bytes):
return False
if not (0xA0 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif 0xE1 <= b <= 0xEC: # UTF8-3 case 2
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif b == 0xED: # UTF8-3 case 3
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0x9F and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif 0xEE <= b <= 0xEF: # UTF8-3 case 4
if i + 2 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and 0x80 <= bytes[i+2] <= 0xBF):
return False
i += 3
elif b == 0xF0: # UTF8-4 case 1
if i + 3 >= len(bytes):
return False
if not (0x90 <= bytes[i+1] <= 0xBF and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
elif 0xF1 <= b <= 0xF3: # UTF8-4 case 2
if i + 3 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0xBF and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
elif b == 0xF4: # UTF8-4 case 3
if i + 3 >= len(bytes):
return False
if not (0x80 <= bytes[i+1] <= 0x8F and
0x80 <= bytes[i+2] <= 0xBF and
0x80 <= bytes[i+3] <= 0xBF):
return False
i += 4
else:
return False # Invalid byte
return True
Liens connexes
- Précédent : 3. Définition d'UTF-8
- Retour à l'accueil RFC 3629
- Suivant : 5. Versions des normes