Consulte também Como um arquivo com caracteres chineses sabe quantos bytes usar por caractere? - sem dúvida, há outras perguntas do SO que também ajudariam.
Em UTF-8, você obtém os seguintes tipos de bytes:
Binary Hex Comments
0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding
10xxxxxx 0x80..0xBF Continuation bytes (1-3 continuation bytes)
110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding
1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding
11110xxx 0xF0..0xF4 First byte of a 4-byte character encoding
(A última linha parece que deveria ser 0xF0..0xF7; no entanto, o intervalo de 21 bits do Unicode (U + 0000 - U + 10FFFF) significa que o valor máximo válido é 0xF4; os valores 0xF5..0xF7 não podem ocorrer em UTF-8 válido.)
Verificar se uma determinada sequência de bytes é UTF-8 válida significa que você precisa pensar sobre:
- Bytes de continuação aparecendo onde não eram esperados
- Byte de não continuação aparecendo onde um byte de continuação é esperado
- Caracteres incompletos no final da string (variação de 'byte de continuação esperado')
- Sequências não mínimas
- UTF-16 substitutos
Em UTF-8 válido, os bytes 0xF5..0xFF não podem ocorrer.
Sequências não mínimas
Existem várias representações possíveis para alguns personagens. Por exemplo, o caractere Unicode U + 0000 (ASCII NUL) pode ser representado por:
0x00
0xC0 0x80
0xE0 0x80 0x80
0xF0 0x80 0x80 0x80
No entanto, o padrão Unicode afirma claramente que as três últimas alternativas não são aceitáveis porque não são mínimas. Acontece que os bytes 0xC0 e 0xC1 nunca podem aparecer em UTF-8 válido porque os únicos caracteres que poderiam ser codificados por eles são minimamente codificados como caracteres de byte único no intervalo 0x00..0x7F.
UTF-16 Surrogates
Dentro do plano multilingue básico (BMP), os valores Unicode U + D800 - U + DFFF são reservados para substitutos UTF-16 e não podem aparecer codificados em UTF-8 válido. Se fossem válidos em UTF-8 (o que, enfatizo, não são), os substitutos seriam codificados:
- U + D800 - 0xED 0xA0 0x80 (menor substituto alto)
- U + DBFF - 0xED 0xAF 0xBF (maior substituto alto)
- U + DC00 - 0xED 0xB0 0x80 (menor substituto baixo)
- U + DFFF - 0xED 0xBF 0xBF (maior substituto baixo)
Dados ruins
Portanto, seus dados BAD devem conter amostras que violem essas várias prescrições.
- Byte de continuação não precedido por um dos valores de byte iniciais
- Bytes iniciais de vários caracteres não seguidos por bytes de continuação suficientes
- Caracteres multibyte não mínimos
- UTF-16 substitutos
- Bytes inválidos (0xC0, 0xC1, 0xF5..0xFF).
Observe que uma marca de ordem de byte (BOM) U + FEFF, também conhecida como espaço no-break de largura zero (ZWNBSP), não pode aparecer sem codificação em UTF-8 - os bytes 0xFF e 0xFE não são permitidos em UTF-8 válido. Um ZWNBSP codificado pode aparecer em um arquivo UTF-8 como 0xEF 0xBB 0xBF, mas o BOM é completamente supérfluo em UTF-8.
Existem também alguns não caracteres em Unicode. U + FFFE e U + FFFF são dois desses não-caracteres (e os últimos dois pontos de código em cada plano, U + 1FFFE, U + 1FFFF, U + 2FFFE, U + 2FFFF, ... U + 10FFFE, U + 10FFFF são outros ) Normalmente, eles não devem aparecer em dados Unicode para troca de dados, mas podem aparecer em uso privado. Veja o link de FAQ do Unicode para muitos detalhes sórdidos, incluindo a história bastante complexa de não caracteres em Unicode. ( Corrigenda nº 9: Esclarecimento sobre não caracteres , lançada em janeiro de 2013, faz o que o título sugere - esclarece o significado dos não caracteres.)