it-swarm.dev

UTF-8, UTF-16 e UTF-32

Quais são as diferenças entre UTF-8, UTF-16 e UTF-32?

Eu entendo que todos eles irão armazenar Unicode, e que cada um usa um número diferente de bytes para representar um caractere. Existe uma vantagem em escolher um sobre o outro?

437
Joe

O UTF-8 tem uma vantagem no caso em que ASCII caracteres representam a maioria dos caracteres em um bloco de texto, porque o UTF-8 codifica todos os caracteres em 8 bits (como o ASCII). Também é vantajoso que um arquivo UTF-8 contendo apenas caracteres ASCII tenha a mesma codificação que um arquivo ASCII.

UTF-16 é melhor onde ASCII não é predominante, já que usa principalmente 2 bytes por caractere. O UTF-8 começará a usar 3 ou mais bytes para os caracteres de ordem mais alta, nos quais o UTF-16 permanece com apenas 2 bytes para a maioria dos caracteres.

O UTF-32 cobrirá todos os caracteres possíveis em 4 bytes. Isso torna bastante inchado. Não consigo pensar em nenhuma vantagem em usá-lo.

330
AnthonyWJones

Em resumo:

  • UTF-8: Codificação de largura variável, compatível com versões anteriores do ASCII. ASCII caracteres (U + 0000 a U + 007F) pegue 1 byte, os pontos de código U + 0080 para U + 07FF pegue 2 bytes, os pontos de código U + 0800 para U + FFFF tome 3 bytes, codifique os pontos U +10000 a U + 10FFFF demora 4 bytes. Bom para texto em inglês, não tão bom para texto asiático.
  • UTF-16: codificação de largura variável. Os pontos de código U + 0000 a U + FFFF levam 2 bytes, os pontos de código U + 10000 a U + 10FFFF tomam 4 bytes. Ruim para texto em inglês, bom para texto asiático.
  • UTF-32: Codificação de largura fixa. Todos os pontos de código levam quatro bytes. Um enorme porco da memória, mas rápido para operar. Raramente usado.

Em tempo: veja Wikipedia: TF-8 , TF-16 e TF-32 .

290
Adam Rosenfield
  • UTF-8 é variável 1 a 4 bytes.

  • UTF-16 é variável 2 ou 4 = bytes.

  • UTF-32 é fixo 4 = bytes.

108
Quassnoi

Unicode define um único conjunto de caracteres enorme, atribuindo um valor inteiro único a cada símbolo gráfico (que é uma grande simplificação, e não é verdade, mas está perto o suficiente para os propósitos desta questão). UTF-8/16/32 são maneiras diferentes de codificar isso.

Em resumo, o UTF-32 usa valores de 32 bits para cada caractere. Isso permite que eles usem um código de largura fixa para cada caractere.

O UTF-16 usa 16 bits por padrão, mas isso só lhe dá 65k caracteres possíveis, o que está longe de ser suficiente para o conjunto Unicode completo. Portanto, alguns caracteres usam pares de valores de 16 bits.

E o UTF-8 usa valores de 8 bits por padrão, o que significa que os primeiros 127 valores são caracteres de byte único de largura fixa (o bit mais significativo é usado para significar que este é o início de uma sequência de múltiplos bytes, deixando 7 bits para o valor real do caractere). Todos os outros caracteres são codificados como seqüências de até 4 bytes (se a memória for exibida).

E isso nos leva às vantagens. Qualquer caractere ASCII é diretamente compatível com UTF-8, portanto, para atualizar aplicativos legados, o UTF-8 é uma escolha comum e óbvia. Em quase todos os casos, também usará menos memória. Por outro lado, você não pode garantir a largura de um personagem. Pode ter 1, 2, 3 ou 4 caracteres de largura, o que dificulta a manipulação de strings.

O UTF-32 é o oposto, ele usa a maior parte da memória (cada caractere tem 4 bytes de largura), mas, por outro lado, você sabe que cada caractere tem esse tamanho exato, então a manipulação de strings mais simples. Você pode calcular o número de caracteres em uma string simplesmente a partir do comprimento em bytes da string. Você não pode fazer isso com o UTF-8.

O UTF-16 é um compromisso. Ele permite que a maioria caracteres se encaixem em um valor de 16 bits de largura fixa. Portanto, contanto que você não tenha símbolos chineses, notas musicais ou outros, você pode assumir que cada caractere tem 16 bits de largura. Ele usa menos memória que o UTF-32. Mas é, de certa forma, "o pior dos dois mundos". Quase sempre usa mais memória que UTF-8, e ainda não evita o problema que assola UTF-8 (caracteres de comprimento variável).

Por fim, geralmente é útil apenas acompanhar o que a plataforma suporta. O Windows usa o UTF-16 internamente, portanto, no Windows, essa é a escolha óbvia.

O Linux varia um pouco, mas eles geralmente usam o UTF-8 para tudo que é compatível com Unicode.

Resposta tão curta: Todas as três codificações podem codificar o mesmo conjunto de caracteres, mas elas representam cada caractere como seqüências de bytes diferentes.

74
jalf

Unicode é um padrão e sobre UTF-x você pode pensar como um implementação técnica para alguns fins práticos:

  • TF-8 - "tamanho otimizado": mais adequado para dados baseados em caracteres latinos (ou ASCII), leva apenas 1 byte por caractere, mas o tamanho cresce conforme a variedade de símbolos ( e, no pior dos casos, pode crescer até 6 bytes por caractere)
  • TF-16 - "balance": leva no mínimo 2 bytes por caractere o que é suficiente para o conjunto existente de idiomas mainstream com tamanho fixo para facilitar o manuseio de caracteres ( mas o tamanho ainda é variável e pode crescer até 4 bytes por caractere)
  • TF-32 - "performance": permite o uso de algoritmos simples como resultado de caracteres de tamanho fixo (4 bytes), mas com desvantagem de memória
40
rook

Eu tentei dar uma explicação simples no meu blogpost .

UTF-32

requer 32 bits (4 bytes) para codificar qualquer caractere . Por exemplo, para representar o ponto de código do caractere "A" usando este esquema, você precisará escrever 65 no número binário de 32 bits:

00000000 00000000 00000000 01000001 (Big Endian)

Se você der uma olhada mais de perto, você notará que os sete bits mais certos são na verdade os mesmos bits ao usar o esquema ASCII. Mas como o UTF-32 é esquema de largura fixa , devemos anexar três bytes adicionais. O que significa que se temos dois arquivos que contêm apenas o caractere "A", um é codificado em ASCII e o outro é codificado em UTF-32, seu tamanho será de 1 byte e 4 bytes correspondentemente.

UTF-16

Muitas pessoas pensam que, como o UTF-32 usa 32 bits de largura fixa para representar um ponto de código, o UTF-16 tem 16 bits de largura fixa. ERRADO!

Em UTF-16, o ponto de código pode ser representado em 16 bits, OR 32 bits. Portanto, este esquema é um sistema de codificação de comprimento variável. Qual é a vantagem sobre o UTF-32? Pelo menos para o ASCII, o tamanho dos arquivos não será 4 vezes o original (mas ainda o dobro), então ainda não somos compatíveis com versões anterioresASCII.

Como os 7 bits são suficientes para representar o caractere "A", podemos usar 2 bytes em vez de 4 como o UTF-32. Será parecido com:

00000000 01000001

UTF-8

Você adivinhou certo .. Em UTF-8 o ponto de código pode ser representado usando 32, 16, 24 ou 8 bits, e como o sistema UTF-16, este também é um sistema de codificação de comprimento variável.

Finalmente, podemos representar "A" da mesma forma que o representamos usando o sistema de codificação ASCII:

01001101

Um pequeno exemplo em que o UTF-16 é realmente melhor que o UTF-8:

Considere a letra chinesa "語" - sua codificação UTF-8 é:

11101000 10101010 10011110

Enquanto sua codificação UTF-16 é menor:

10001010 10011110

Para entender a representação e como ela é interpretada, visite o post original.

20
Maroun

UTF-8

  • não tem conceito de ordem de byte
  • usa entre 1 e 4 bytes por caractere
  • ASCII é um subconjunto de codificação compatível
  • completamente auto-sincronizado, e. um byte perdido de qualquer lugar em um fluxo corromperá no máximo um único caractere
  • praticamente todas as línguas européias são codificadas em dois bytes ou menos por caractere

UTF-16

  • deve ser analisado com uma ordem de bytes conhecida ou lendo um byte-order-mark (BOM)
  • usa 2 ou 4 bytes por caractere

UTF-32

  • cada personagem tem 4 bytes
  • deve ser analisado com uma ordem de bytes conhecida ou lendo um byte-order-mark (BOM)

O UTF-8 será o mais eficiente em termos de espaço, a menos que a maioria dos caracteres seja do espaço de caracteres CJK (chinês, japonês e coreano).

O UTF-32 é melhor para acesso aleatório por deslocamento de caracteres em uma matriz de bytes.

18
Jeff Adamson

Fiz alguns testes para comparar o desempenho do banco de dados entre UTF-8 e UTF-16 no MySQL.

Atualizar velocidades

UTF-8

Enter image description here

UTF-16

Enter image description here

Insira velocidades

Enter image description here

Enter image description here

Excluir velocidades

Enter image description here

Enter image description here

13
Farid Movsumov

Em UTF-32, todos os caracteres são codificados com 32 bits. A vantagem é que você pode calcular facilmente o comprimento da string. A desvantagem é que para cada caractere ASCII você perde um extra de três bytes.

Em UTF-8 caracteres têm comprimento variável, ASCII caracteres são codificados em um byte (oito bits), a maioria dos caracteres especiais ocidentais são codificados em dois bytes ou três bytes (por exemplo € é três bytes), e personagens mais exóticos podem levar até quatro bytes. A clara desvantagem é que, a priori, você não pode calcular o tamanho da string. Mas é preciso muito menos bytes para codificar o texto do alfabeto latino (inglês), em comparação com o UTF-32.

O UTF-16 também tem comprimento variável. Os caracteres são codificados em dois bytes ou quatro bytes. Eu realmente não vejo o ponto. Ele tem a desvantagem de ser de tamanho variável, mas não tem a vantagem de economizar tanto espaço quanto o UTF-8.

Destes três, claramente UTF-8 é o mais amplamente difundido.

11
vartec

Dependendo do seu ambiente de desenvolvimento, você pode até não ter a escolha de qual codificação seu tipo de dados de string usará internamente.

Mas, para armazenar e trocar dados, eu sempre usaria o UTF-8, se você tivesse a escolha. Se você tem principalmente ASCII dados, isso lhe dará a menor quantidade de dados para transferir, enquanto ainda é capaz de codificar tudo. Otimizar para o mínimo de E/S é o caminho a percorrer nas máquinas modernas.

6
mghie

Como mencionado, a diferença é principalmente o tamanho das variáveis ​​subjacentes, que em cada caso aumentam para permitir que mais caracteres sejam representados.

No entanto, fontes, codificação e coisas são perversamente complicadas (desnecessariamente?), Então um grande link é necessário para preencher mais detalhes:

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

Não espere entender tudo, mas se você não quiser ter problemas mais tarde, vale a pena aprender o máximo que puder, o mais cedo possível (ou apenas pedir a alguém para resolver o problema).

Paulo.

2
Paul W Homer

Em resumo, a única razão para usar UTF-16 ou UTF-32 é suportar scripts não ingleses e antigos, respectivamente.

Eu estava me perguntando por que alguém escolheria ter codificação não-UTF-8 quando é obviamente mais eficiente para fins de web/programação.

Um equívoco comum - o número com sufixo NÃO é uma indicação de sua capacidade. Todos eles suportam o Unicode completo, só que o UTF-8 pode manipular ASCII com um único byte, então é MAIS eficiente/menos corrupto para a CPU e pela internet.

Algumas boas leituras: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html e http://utf8everywhere.org =

0
killjoy