Por que existem várias codificações Unicode?


41

Eu pensei que o Unicode foi projetado para contornar todo o problema de ter muitas codificações diferentes devido a um pequeno espaço de endereço (8 bits) na maioria das tentativas anteriores (ASCII, etc.).

Por que, então, existem tantas codificações Unicode? Até várias versões do (essencialmente) o mesmo, como UTF-8, UTF-16, etc.


11
UTF-8 não é o mesmo que UTF-16. A lista aumentará assim que encontrarmos outros sistemas solares com planetas semelhantes à Terra.
Setzamora #

11
@ Joset: Nós já temos o Klingon. Temos a maioria das línguas terrestres no BMP, com leve derramamento nas planícies 1,2. Se as correntes atuais estiverem corretas e houver apenas 42 espécies sencientes na galáxia que atingem um ponto em que possam usar viagens espaciais (portanto, permitir o primeiro contato), poderemos espremer todos os caracteres em todos os idiomas para o UNICODE (supondo que possamos expandir de 21 a 22 bits para permitir 64 planícies). Isso deixa até 10 bits de espaço no buffer se queremos incluir as espécies primitivas que não alcançaram o vôo espacial.
Martin York

7
@Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Portanto, existem pelo menos 6 codificações reais. UTF-9 e UTF-18 são enganados.
MSalters

9
A coisa boa sobre padrões é que há tantos deles
Homde

11
Veja o que Spolsky tinha a dizer sobre Unicode e codificação .
MPelletier

Respostas:


29

Porque as pessoas não querem gastar 21 bits em cada personagem. Em todos os sistemas modernos, isso significaria essencialmente o uso de três bytes por caractere, o que é três vezes mais do que as pessoas estavam acostumadas, portanto, não estavam dispostas a adotar o Unicode. É necessário encontrar compromissos: por exemplo, o UTF-8 é ótimo para o texto em inglês porque os arquivos ASCII herdados não precisam ser convertidos, mas são menos úteis para os idiomas europeus e pouco utilizados para os idiomas asiáticos.

Então, basicamente, sim, poderíamos ter definido uma única codificação universal e um único gráfico de caracteres universal, mas o mercado não a aceitaria.


8
+1 ótima resposta. Para ser sincero, é o único que realmente responde a essa pergunta. Todas as outras respostas são (mais ou menos) sobre como os bytes são dispostos em todas as codificações unicode diferentes.
Jacek Prucia

Historicamente, é uma simples questão de desacordo. No entanto, não vejo muita utilidade para nada além do UTF-8 hoje, enquanto há cenários teóricos em que o UTF-16 consumiria menos espaço, não é por uma grande margem e são raros. O lugar mais importante onde você deseja economizar espaço é para sites, mas eles são cheios de códigos HTML, que são de longe o mais curto usando UTF-8. Você pode, por exemplo, usar Shift JISpara tornar um site japonês menor que o equivalente UTF-8, mas isso só funciona porque é um conjunto de caracteres especificamente para o japonês.
Aaaaaaaaaaaa

2
Também não é verdade. Como os formatos compactados são realmente usados ​​apenas para transporte e armazenamento. Dentro de um aplicativo, é mais comum usar o UCS-2 ou UCS-4, pois estes têm largura fixa, mas ocupam 2 ou 4 bytes por caractere. Portanto, os aplicativos estão dispostos a abrir espaço para a facilidade de uso.
Martin York

but it is less useful for European languages, and of little use for Asian languages- isso está errado. Por "utilidade" você quer dizer compressão? Bem, o UTF-8 oferece uma melhor compactação para os idiomas europeus, porque em todo texto existem espaços e sinais de pontuação que levam apenas um byte.
precisa saber é o seguinte

37

Unicode é um caractere de 21 bits que codifica exclusivamente os "CodePoints", cada pontos de código sendo representados por um glifo (uma representação gráfica).

  • 16 bits usados ​​para identificar um ponto de código em um plano (a maioria dos pontos de código está no plano 0).
  • 5 bits para identificar o avião.

As codificações suportadas são:

  • UTF-8 (para codificar cada ponto usando valores de 8 bits)
  • UTF-16 (para codificar cada ponto usando valores de 16 bits)
  • UTF-32 (para codificar cada ponto usando valores de 32 bits)

Mas não importa qual seja a codificação quando você decodifica, todos eles são mapeados de volta para um ponto de código específico que tem o mesmo significado (e é por isso que é legal).

UTF-8

Este é um formato de tamanho variável. Onde cada ponto de código é representado por 1 a 4 bytes.

UTF-16

Este é um formato de tamanho variável. Os pontos de código no "Plano multilíngue básico" (BMP ou Plano 0) podem ser representados por um valor único de 16 bits. Os pontos de código em outros planos são representados por um par substituto (2 valores de 16 bits).

UTF-32

Este é um formato de tamanho fixo. Todos os pontos de código são representados por um único valor de 32 bits.


2
Eu também gosto dessa resposta. Estava escrevendo um similar, mas este é claro. Eu também acrescentaria que o UTF-8 também é útil, pois as seqüências ASCII são automaticamente UTF-8.
Kevin Hsu

4
Por favor, é o plano multilíngue básico , não é simples .
JSB #

3
Essa é uma boa resposta, mas acho que ainda implora a pergunta "Por quê?", Embora essa resposta toque implicitamente nisso. Para elaborar: UTF-32 é uma abordagem mais direta (alguns diriam mais fácil) da codificação de caracteres Unicode, mas também desperdiça muito espaço, pois cada caractere ocupa 4 bytes. O UTF-8 é muito mais compacto e compatível com versões anteriores do ASCII, mas não é regular: um caractere pode levar de 1 a 4 bytes para codificar, o que dificulta o trabalho. O UTF-16 é um tipo de abordagem híbrida entre os dois, principalmente com os prós e contras de cada um.
Mipadi

4
Há uma troca entre o uso da memória (onde o UTF-8 é melhor, já que os caracteres mais comuns são de byte único) e a velocidade de processamento (onde o UTF-32 é melhor, porque todos os caracteres são do mesmo tamanho, permitindo certas otimizações e otimização perfeita). Alinhamento de 32 bits na memória). Como resultado, protocolos de rede e formatos de arquivo geralmente usam UTF-8 (para economizar largura de banda / espaço de armazenamento), enquanto os intérpretes de script e os tempos de execução do idioma podem preferir UTF-16 ou UTF-32.
tdammers 21/05

2
@Marcel: Um "CodePoint" é um "CodePoint" e não um character(como um caractere pode ser construído a partir de vários "CodePoints"). Não confunda os dois termos. Mas você está correto "CodePoints" não se refere a glifos. Um Glyph é apenas uma representação gráfica de um ponto de código. Uma diferença sutil, mas importante.
Martin York

25

Eu acho que é útil separar as 2 idéias:

  1. Unicode - mapeamento de caracteres de todo o mundo para pontos de código.
  2. Codificação - mapeamento de pontos de código para padrões de bits (UTF-8, UTF-16, etc).

As codificações UTF-8, UTF-16 e outras possuem vantagens e desvantagens. Melhor consultar a Wikipedia sobre isso.


@jfs: Por que o Unicode, apesar de tudo, se ainda haverá uma dúzia ou mais de codificações diferentes, que são todas diferentes no fio de qualquer maneira? Qual a utilidade de ter um mapeamento global por si só?
Matthew Scharley

10
@ Matthew Scharley: Você está olhando errado. UNICODE mapeia todos os caracteres de todos os idiomas (incluindo o Klingon) para um ID ÚNICO (ponto de código). As codificações são apenas uma maneira de compactar os pontos de código em um disco ou fluxo em uma rede. UTF significa "formato de transporte UNICODE". Você deve sempre pensar em um ponto de código UNICODE como um valor de 21 bits. A vantagem sobre outros formatos é que todos os caracteres são identificados exclusivamente e não se sobrepõem (ao contrário do Latin-1, Latin-2, etc.).
Martin York

@ Matthew Scharley Por que fazer um mapeamento global? Na verdade, todo mundo tinha seu próprio mapeamento no passado (lembra-se das páginas de códigos?). Eu acho que um exemplo bobo vai esclarecer as coisas. Imagine a ideia do amor. Como você o representará para alguém? Dar flores? Diga "eu te amo"? Todo mundo tem sua própria maneira de expressar isso. O amor (que é uma idéia abstrata) é como os pontos do código. Expressá-lo é como as codificações. :)
JFS

4
Unicode é o alfabeto global. UTF-x é a maneira como é transportado pelos computadores, pois é difícil empurrar o papel pelos fios.
Mel

11
@ Martin, Klingon na verdade não conseguiu. Tengwar e Cirith também não usavam para escrever as línguas élficas de Tolkein.
TRiG 23/05

9

UTF-7, UTF-8, UTF-16 e UTF-32 são simplesmente formatos de transformação algorítmica da mesma codificação (pontos de código) de caracteres. São codificações de um sistema de codificação de caracteres.

Eles também são algoritmicamente mais fáceis de navegar para frente e para trás do que a maioria dos esquemas anteriores para lidar com conjuntos de caracteres maiores que 256 caracteres.

Isso é muito diferente da codificação de glifos geralmente específica para o país e, às vezes, para o fornecedor. Somente no japonês, havia uma tonelada de variações do JIS sozinho, sem mencionar o EUC-JP e a transformação do JIS orientada por página de código que as máquinas DOS / Windows usavam chamada Shift-JIS. (Até certo ponto, houve transformações algorítmicas delas, mas elas não eram particularmente simples e havia diferenças específicas de fornecedor em caracteres que estavam disponíveis. Multiplique isso por algumas centenas de países e a evolução gradual de sistemas de fontes mais sofisticados (post greenscreen era) e você teve um pesadelo real.

Por que você precisaria dessas formas de transformação do Unicode? Como muitos sistemas legados assumiram sequências de caracteres de 7 bits do intervalo ASCII, você precisou de uma solução limpa de 7 bits que passasse com segurança os dados não corrompidos por esses sistemas; portanto, precisava de UTF-7. Depois, havia sistemas mais modernos que podiam lidar com conjuntos de caracteres de 8 bits, mas os nulos geralmente tinham significados especiais para eles, portanto o UTF-16 não funcionava para eles. 2 bytes poderiam codificar todo o plano multilíngue básico do Unicode em sua primeira encarnação, de modo que o UCS-2 parecia uma abordagem razoável para sistemas que seriam "sensíveis ao Unicode desde o início" (como Windows NT e Java VM); as extensões além desses precisavam de caracteres adicionais, que resultou na transformação algorítmica dos 21 bits de codificações reservadas pelo padrão Unicode, e nasceram pares substitutos; isso exigia UTF-16. Se você tivesse alguma aplicação em que a consistência da largura dos caracteres fosse mais importante que a eficiência do armazenamento, o UTF-32 (uma vez chamado UCS-4) era uma opção.

UTF-16 é a única coisa remotamente complexa de se lidar, e é facilmente mitigada pelo pequeno intervalo de caracteres afetados por essa transformação e pelo fato de que as sequências principais de 16 bits estão ordenadamente em um intervalo totalmente distinto do final Sequências de 16 bits. Também é um mundo mais fácil do que tentar avançar e retroceder em muitas codificações do início do Leste Asiático, onde você precisava de uma máquina de estado (JIS e EUC) para lidar com as seqüências de escape ou potencialmente retrocedeu vários caracteres até encontrar algo garantido. ser apenas um byte principal (Shift-JIS). O UTF-16 tinha algumas vantagens em sistemas que também podiam executar sequências de 16 bits com eficiência.

A menos que você tenha que viver com dezenas (centenas, realmente) de codificações diferentes por aí, ou tenha que criar sistemas que suportem vários idiomas em codificações diferentes, às vezes até no mesmo documento (como o WorldScript nas versões mais antigas do MacOs), você pode pensar dos formatos de transformação unicode como complexidade desnecessária. Mas é uma redução drástica da complexidade em relação às alternativas anteriores, e cada formato resolve uma restrição técnica real. Eles também são realmente eficientemente conversíveis entre si, não exigindo tabelas de pesquisa complexas.


11
As várias máquinas de estado JIS e EUC são realmente desagradáveis, e duplamente se você estiver trabalhando com a transformação entre elas. O Unicode simplifica bastante isso. O único grande problema com o Unicode é que você precisa parar de pensar em bytes como caracteres; você deve usar chauvinista ASCII usando caracteres pequenos!
Donal Fellows

6

O Unicode não foi projetado para contornar todo o problema de ter muitas codificações diferentes.

O Unicode foi projetado para contornar toda a questão de um número que representa muitas coisas diferentes, dependendo da página de código em uso. Os números de 0 a 127 representam os mesmos caracteres em qualquer página de código Ansi. Isso é também conhecido como gráfico ASCII ou conjunto de caracteres. Nas páginas de código Ansi, que permitem 256 caracteres, os números 128 a 255 representam caracteres diferentes em diferentes páginas de código.

Por exemplo

  • O número $ 57 representa um W maiúsculo em todas as páginas de código, mas
  • O número $ EC representa o símbolo de inifinity na página de código 437 (EUA), mas uma "LETRA LATINA PEQUENA N COM CEDILHA" na página de código 775 (Báltico)
  • O sinal de centavo é o número $ 9B na página de código 437, mas o número 96 na página de código 775

O que o Unicode fez foi virar tudo de cabeça para baixo. No Unicode, não há "reutilização". Cada número representa um único caractere único. O número $ 00A2 em Unicode é o sinal de centavo e o sinal de centavo não aparece em nenhum outro lugar na definição de Unicode.

Por que, então, existem tantas codificações Unicode? Até várias versões do (essencialmente) o mesmo, como UTF-8, UTF-16, etc.

Não há várias versões da mesma codificação. Existem várias codificações do mesmo mapa de definição de caracteres Unicode e elas foram "inventadas" para administrar requisitos de armazenamento para diferentes usos dos vários planos linguais existentes no Unicode.

Unicode define (ou tem espaço para definir) 4.294.967.295 caracteres únicos. Se você deseja mapear esses dados para o armazenamento em disco / memória sem fazer nenhuma conversão algorítmica, precisará de 4 bytes por caractere. Se você precisar armazenar textos com caracteres de todos os planos linguais, provavelmente é o que você precisa UTF-32 (que é basicamente uma codificação direta de armazenamento de 1 caractere - 4 bytes da definição de unicode).

Mas quase nenhum texto usa caracteres de todos os planos linguais. E então usar 4 bytes por caractere parece um grande desperdício. Especialmente quando você leva em consideração que a maioria dos idiomas do mundo é definida dentro do que é conhecido como Plano Multilíngue Básico (BMP): os primeiros 65536 números da definição Unicode.

E foi aí que entrou o UTF-16. Se você usar apenas caracteres do BMP, o UTF-16 armazenará isso de maneira muito eficiente usando apenas dois bytes por caractere. Ele usará apenas mais bytes para caracteres fora do BMP. A distinção entre UTF-16LE (Little Endian) e UTF-16BE (Big Endian) realmente tem algo a ver com a forma como os números são representados na memória do computador (padrão de bytes que A0significa hex $ A0 ou $ 0A).

Se o seu texto usar ainda menos caracteres diferentes, como a maioria dos textos nos idiomas da Europa Ocidental, você desejará restringir ainda mais os requisitos de armazenamento para seus textos. Portanto, o UTF-8, que usa um único byte para armazenar os caracteres presentes no gráfico ASCII (os primeiros 128 números) e uma seleção dos caracteres Ansi (os segundos 128 números das várias páginas de códigos). Ele usará apenas mais bytes para caracteres fora deste conjunto de "caracteres mais usados".

Então, para recapitular:

  • Unicode é um mapeamento dos caracteres em todos os idiomas do mundo (e alguns klingon para inicializar) e depois alguns (matemáticos, musicais, etc.) para um número único.
  • Codificações são algoritmos definidos para armazenar textos usando os números desse mapa de caracteres exclusivo da maneira mais eficiente possível, com o espaço possível, considerando o "uso médio" dos caracteres nos textos.

2
"Os números 0 - 127 representam os mesmos caracteres em qualquer página de código." - Bem, a menos que você está falando EBCDIC, caso em que $57não é um W
MSalters

@ Salters: você está absolutamente certo. EBCDIC é diferente (e existem outros EBCDIC). Eu acho que meus dias de mainframe são tão longas atrás de mim que eu não me lembro, ou eu ter reprimido essas memórias muito duro e muito tempo ... :-)
Marjan Venema

"Os números 0 - 127 representam os mesmos caracteres em qualquer página de código." Na verdade, existem codificações, como BinarySignWriting, que não são superconjuntos de ASCII. BinarySignWriting, de fato, não inclui nenhum caractere ASCII.
TRiG 20/05

@TRiG: Foi por isso que editei minha declaração para ser especificamente sobre as páginas de código da Ansi. Deve ter feito isso antes de você atualizado ...
Marjan Venema

Sim. Houve um comentário extra e uma atualização pós feita enquanto eu escrevia meu comentário. Ainda assim, BinarySignWriting é interessante.
TRiG 20/05

2

Unicode define o mapa entre números e caracteres. No entanto, quando você envia um número para um destinatário, ainda precisa definir como representar esse número. É para isso que serve a UTF. Ele define como representar um número em um fluxo de bytes.


2

A lógica por trás do UTF-32 é simples: é a representação mais direta dos pontos de código Unicode. Então, por que não está tudo em UTF-32? Duas razões principais:

Um é o tamanho . UTF-32 requer 4 bytes para cada caractere. Para texto que usa apenas caracteres no local multilíngue básico, isso é duas vezes mais espaço que UTF-16. Para texto em inglês, é 4 vezes mais espaço que US-ASCII.

A razão maior é a compatibilidade com versões anteriores . Cada codificação Unicode diferente do UTF-32 "não codificado" foi projetada para compatibilidade com versões anteriores com um padrão anterior.

  • UTF-8: Compatibilidade com versões anteriores com US-ASCII.
  • UTF-16: Compatibilidade com versões anteriores do UCS-2 (Unicode de 16 bits antes de ser expandido além do BMP).
  • UTF-7: Compatibilidade com versões anteriores com servidores de correio não limpos de 8 bits.
  • GB18030: Compatibilidade com versões anteriores com as codificações GB2312 e GBK para chinês.
  • UTF-EBCDIC: Compatibilidade com versões anteriores com o subconjunto Latino básico do EBCDIC.

Eu pensei que o Unicode foi projetado para contornar toda a questão de ter muitas codificações diferentes

Foi, e fez. É muito mais fácil converter entre UTF-8, -16 e -32 do que lidar com o sistema antigo de centenas de codificações de caracteres diferentes para diferentes idiomas e sistemas operacionais diferentes.


1

Você sabe que um arquivo zip pode compactar um arquivo para ser muito menor (especialmente texto) e descompactá-lo em uma cópia idêntica do arquivo original.

Na verdade, o algoritmo de zipagem tem vários algoritmos diferentes com características diferentes para escolher: armazenado (sem compactação), Encolhido, Reduzido (métodos 1-4), Imploded, Tokenizing, Deflated, Deflate64, BZIP2, LZMA (EFS), WavPack, PPMd, onde, teoricamente, poderia tentar todos eles e escolher o melhor resultado, mas geralmente basta usar Deflated.

UTF funciona da mesma maneira. Existem vários algoritmos de codificação, cada um com características diferentes, mas geralmente você escolhe UTF-8 porque ele é amplamente suportado em oposição a outras variantes UTF, o que, por sua vez, é porque é bit a bit compatível com o ASCII de 7 bits, facilitando use na maioria das plataformas de computadores modernas que geralmente usam uma extensão de 8 bits do ASCII.


Nota: A diferença com um arquivo zip é que existe um cabeçalho que informa qual compressão está em vigor. Com arquivos de texto, ainda precisamos adivinhar, não é?
Matthew Scharley

Há uma sequência especial que diz exatamente isso. Devido à compatibilidade com versões anteriores do ASCII, é opcional.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.