De acordo com o artigo da Wikipedia , UTF-8 tem este formato:
Primeiro código Último código Bytes Byte 1 Byte 2 Byte 3 Byte 4 point point Usado U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 07FF 2 110xxxxx 10xxxxxx U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx x significa que este bit é usado para selecionar o ponto de código.
Isso desperdiça dois bits em cada byte de continuação e um bit no primeiro byte. Por que o UTF-8 não é codificado da seguinte maneira?
Primeiro código Último código Bytes Byte 1 Byte 2 Byte 3 point point Usado U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx U + 0800 U + 1FFFFF 3 110xxxxx xxxxxxxx xxxxxxxx
Ele economizaria um byte quando o ponto de código estiver fora do plano multilíngue básico ou se o ponto de código estiver no intervalo [U + 800, U + 3FFF].
Por que o UTF-8 não é codificado de maneira mais eficiente?
Respostas:
Isso é feito para que você possa detectar quando está no meio de uma sequência de vários bytes. Ao analisar dados UTF-8, você sabe que, se vir
10xxxxxx
, está no meio de um caractere multibyte e deve fazer backup no fluxo até ver um0xxxxxx
ou outro11xxxxxx
. Usando seu esquema, os bytes 2 ou 3 podem acabar facilmente com padrões como um0xxxxxxx
ou outro11xxxxxx
Lembre-se também de que a quantidade economizada varia inteiramente de acordo com o tipo de dados que você está codificando. Para a maioria dos textos, mesmo os asiáticos, você raramente vê caracteres de quatro bytes com texto normal. Além disso, as estimativas ingênuas das pessoas sobre a aparência do texto geralmente estão erradas. Eu tenho um texto localizado para UTF-8 que inclui seqüências de caracteres japonesas, chinesas e coreanas, mas é realmente o russo que ocupa mais espaço. (Como nossas seqüências de caracteres asiáticas geralmente têm caracteres romanos intercalados por nomes próprios, pontuação e outros, e porque a palavra média chinesa é de 1 a 3 caracteres, enquanto a palavra média russa é muito, muito mais.)
fonte
A maneira oficial permite que o decodificador saiba quando está no meio da tupla e sabe pular bytes (ou retroceder) até que o byte comece com
0
ou11
; isso evita valores de lixo quando um único byte é corrompido.fonte
Resposta curta, sua proposta não diferencia entre o primeiro byte e os bytes de continuação.
O padrão de bits na extremidade superior do primeiro byte informa com quantos bytes o caractere real é criado. Esses padrões também fornecem algum reconhecimento de erro ao analisar uma string. Se você está lendo o (aparentemente) primeiro byte de um personagem e obtém 10xxxxxx, sabe que está fora de sincronia.
fonte
O que não foi mencionado é que, se você possui uma sequência correta de pontos de código e um ponteiro que é garantido para apontar para o primeiro byte de um ponto de código, com UTF-8, é possível encontrar facilmente o ponteiro para o primeiro byte do ponto de código anterior (pule todos os bytes que começam com 01xx xxxx). Com sua codificação, é impossível sem examinar potencialmente todos os bytes até o início da string.
Considere as seqüências de (2n + 2) bytes
e
Se você tiver um ponteiro para o primeiro byte do primeiro ponto de código após esta sequência, deverá examinar todos os bytes para descobrir se o último ponto de código é 0xxxxxxx ou (10xxxxxx, 0xxxxxxx).
Na verdade, existem esquemas de codificação mais eficientes, nos quais o acesso ao ponto de código anterior pode ser feito em tempo constante e os ponteiros para o meio de um ponto de código podem ser corrigidos. Permita os seguintes códigos:
Se um dos três bytes anteriores for ≥ 236, será o início de uma sequência de 3 bytes, porque não pode haver dois bytes dentro de qualquer sequência válida de 3 bytes. Caso contrário, se um dos dois bytes anteriores for ≥ 128, será o início de uma sequência de dois bytes. Caso contrário, o byte anterior é um byte único <128.
Procurar uma substring se torna um pouco mais difícil. Você pode excluir zero bytes para que uma string contenha apenas um byte zero se contiver um ponto de código zero.
fonte