Passa al contenuto principale

4. Sintassi delle sequenze di byte UTF-8

Per comodità degli implementatori che utilizzano ABNF, viene qui fornita una definizione di UTF-8 in sintassi ABNF.

Definizione di stringa UTF-8

Una stringa UTF-8 è una sequenza di ottetti che rappresenta una sequenza di caratteri UCS. Una sequenza di ottetti è UTF-8 valido solo se corrisponde alla sintassi seguente, che deriva dalle regole di codifica di UTF-8 ed è espressa nell'ABNF di [RFC2234].

Sintassi 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

Spiegazione della sintassi

UTF8-1: sequenze di un byte

%x00-7F
  • Intervallo: da 0x00 a 0x7F (0-127)
  • Codifica: intero intervallo ASCII
  • Schema: 0xxxxxxx

UTF8-2: sequenze di due byte

%xC2-DF UTF8-tail
  • Primo byte: da 0xC2 a 0xDF (194-223)
  • Byte di coda: da 0x80 a 0xBF (128-191)
  • Schema: 110xxxxx 10xxxxxx
  • Nota: il primo byte non può essere 0xC0 o 0xC1 (produrrebbe una codifica troppo lunga)

UTF8-3: sequenze di tre byte

Quattro casi:

Caso 1: %xE0 %xA0-BF UTF8-tail

  • Primo byte: 0xE0
  • Secondo byte: da 0xA0 a 0xBF
  • Terzo byte: da 0x80 a 0xBF
  • Intervallo di codifica: da U+0800 a U+0FFF

Caso 2: %xE1-EC 2( UTF8-tail )

  • Primo byte: da 0xE1 a 0xEC
  • Byte successivi: due UTF8-tail (0x80-0xBF)
  • Intervallo di codifica: da U+1000 a U+CFFF

Caso 3: %xED %x80-9F UTF8-tail

  • Primo byte: 0xED
  • Secondo byte: da 0x80 a 0x9F
  • Terzo byte: da 0x80 a 0xBF
  • Intervallo di codifica: da U+D000 a U+D7FF
  • Nota: evita l'intervallo delle coppie surrogate (U+D800-U+DFFF)

Caso 4: %xEE-EF 2( UTF8-tail )

  • Primo byte: da 0xEE a 0xEF
  • Byte successivi: due UTF8-tail
  • Intervallo di codifica: da U+E000 a U+FFFF

UTF8-4: sequenze di quattro byte

Tre casi:

Caso 1: %xF0 %x90-BF 2( UTF8-tail )

  • Primo byte: 0xF0
  • Secondo byte: da 0x90 a 0xBF
  • Byte successivi: due UTF8-tail
  • Intervallo di codifica: da U+10000 a U+3FFFF

Caso 2: %xF1-F3 3( UTF8-tail )

  • Primo byte: da 0xF1 a 0xF3
  • Byte successivi: tre UTF8-tail
  • Intervallo di codifica: da U+40000 a U+FFFFF

Caso 3: %xF4 %x80-8F 2( UTF8-tail )

  • Primo byte: 0xF4
  • Secondo byte: da 0x80 a 0x8F
  • Byte successivi: due UTF8-tail
  • Intervallo di codifica: da U+100000 a U+10FFFF

Valori di byte non validi

I seguenti valori di byte non compaiono mai in sequenze UTF-8 valide:

Prohibited byte values:
- 0xC0, 0xC1 (would produce overlong 2-byte sequences)
- 0xF5 - 0xFF (beyond Unicode range)

Riepilogo completo degli intervalli di byte

Intervallo di valori di byteSignificatoValidità
0x00-0x7FCarattere di un byte (ASCII)✅ Valido
0x80-0xBFByte di continuazione✅ Valido solo come coda
0xC0-0xC1Vietato❌ Non valido
0xC2-0xDFPrimo byte di una sequenza di 2 byte✅ Valido
0xE0-0xEFPrimo byte di una sequenza di 3 byte✅ Valido
0xF0-0xF4Primo byte di una sequenza di 4 byte✅ Valido
0xF5-0xFFVietato❌ Non valido

Esempi di validazione

Sequenze valide

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: '😀'

Sequenze non valide

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)

⚠️ Nota importante

NOTE -- La definizione autorevole di UTF-8 si trova in [UNICODE]. Si ritiene che questa grammatica descriva la stessa cosa descritta da Unicode, ma non pretende di essere autorevole. Si esorta gli implementatori a fare affidamento sulla fonte autorevole anziché su questo ABNF.

Suggerimento di implementazione

Pseudocodice dell'algoritmo di validazione

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

Collegamenti correlati