Qual é a base do Unicode e por que a necessidade de UTF-8 ou UTF-16? Eu pesquisei isso no Google e procurei aqui também, mas não está claro para mim.
No VSS, ao fazer uma comparação de arquivos, às vezes há uma mensagem dizendo que os dois arquivos têm UTFs diferentes. Por que isso seria o caso?
Por favor, explique em termos simples.
Respostas:
Por que precisamos de Unicode?
Nos (não muito) primeiros dias, tudo o que existia era ASCII. Tudo bem, pois tudo o que seria necessário eram alguns caracteres de controle, pontuação, números e letras como os desta frase. Infelizmente, o estranho mundo da intercomunicação global e das mídias sociais de hoje não estava previsto, e não é incomum ver Inglês, العربية, 汉语, עִבְרִית, ελληνικά e ភាសាខ្មែរ no mesmo documento (espero não ter quebrado nenhum velho navegadores).
Mas, por uma questão de argumento, digamos que Joe Average é desenvolvedor de software. Ele insiste que só precisará usar o inglês e, como tal, só quer usar o ASCII. Isso pode ser bom para Joe, o usuário , mas não é bom para Joe, o desenvolvedor de software . Aproximadamente metade do mundo usa caracteres não latinos e o uso de ASCII é indiscutível para essas pessoas; além disso, ele está fechando seu software para uma economia grande e crescente.
Portanto, é necessário um conjunto de caracteres abrangente, incluindo todos os idiomas. Assim veio o Unicode. Ele atribui a cada caractere um número exclusivo chamado ponto de código . Uma vantagem do Unicode sobre outros conjuntos possíveis é que os primeiros 256 pontos de código são idênticos ao ISO-8859-1 e, portanto, também ao ASCII. Além disso, a grande maioria dos caracteres comumente usados é representável por apenas dois bytes, em uma região chamada BMP (Basic Multilingual Plane) . Agora é necessária uma codificação de caracteres para acessar esse conjunto de caracteres e, conforme a pergunta, vou me concentrar em UTF-8 e UTF-16.
Considerações sobre memória
Então, quantos bytes dão acesso a quais caracteres nessas codificações?
Vale ressaltar agora que os personagens que não estão no BMP incluem scripts antigos, símbolos matemáticos, símbolos musicais e caracteres chineses / japoneses / coreanos (CJK) mais raros .
Se você estiver trabalhando principalmente com caracteres ASCII, o UTF-8 certamente será mais eficiente em termos de memória. No entanto, se você estiver trabalhando principalmente com scripts não europeus, o uso de UTF-8 pode ter até 1,5 vezes menos eficiência de memória que o UTF-16. Ao lidar com grandes quantidades de texto, como páginas da Web grandes ou documentos extensos do Word, isso pode afetar o desempenho.
Noções básicas de codificação
Nota: Se você souber como UTF-8 e UTF-16 são codificados, pule para a próxima seção para aplicações práticas.
1
evitar colidir com os caracteres ASCII.Como pode ser visto, UTF-8 e UTF-16 não são nem de longe compatíveis entre si. Portanto, se você estiver executando E / S, saiba qual codificação está usando! Para mais detalhes sobre essas codificações, consulte as Perguntas frequentes sobre UTF .
Considerações práticas de programação
Tipos de dados de caracteres e seqüências de caracteres: como eles são codificados na linguagem de programação? Se forem bytes brutos, no minuto em que você tentar gerar caracteres não ASCII, poderá ter alguns problemas. Além disso, mesmo que o tipo de caractere seja baseado em uma UTF, isso não significa que as seqüências de caracteres sejam UTF adequadas. Eles podem permitir seqüências de bytes ilegais. Geralmente, você precisará usar uma biblioteca que suporte UTF, como ICU para C, C ++ e Java. De qualquer forma, se você deseja inserir / produzir algo diferente da codificação padrão, precisará convertê-lo primeiro.
Codificações recomendadas / padrão / dominantes: quando é possível escolher qual UTF usar, geralmente é melhor seguir os padrões recomendados para o ambiente em que você está trabalhando. Por exemplo, o UTF-8 é dominante na web e, desde o HTML5, ele foi a codificação recomendada . Por outro lado, os ambientes .NET e Java são baseados em um tipo de caractere UTF-16. De maneira confusa (e incorreta), frequentemente são feitas referências à "codificação Unicode", que geralmente se refere à codificação UTF dominante em um determinado ambiente.
Suporte de biblioteca: as bibliotecas que você está usando suportam algum tipo de codificação. Qual? Eles suportam os casos de canto? Como a necessidade é a mãe da invenção, as bibliotecas UTF-8 geralmente suportam caracteres de 4 bytes corretamente, pois caracteres de 1, 2 e até 3 bytes podem ocorrer com freqüência. No entanto, nem todas as supostas bibliotecas UTF-16 suportam pares substitutos corretamente, pois ocorrem muito raramente.
Contando caracteres: Existem caracteres combinados em Unicode. Por exemplo, o ponto de código U + 006E (n) e U + 0303 (um til de combinação) formam ñ, mas o ponto de código U + 00F1 forma ñ. Eles devem parecer idênticos, mas um algoritmo de contagem simples retornará 2 para o primeiro exemplo, 1 para o último. Isso não é necessariamente errado, mas também pode não ser o resultado desejado.
Comparando para igualdade: A, А e Α têm a mesma aparência, mas são latim, cirílico e grego, respectivamente. Você também tem casos como C e Ⅽ, um é uma letra e o outro, um número romano. Além disso, também temos os caracteres combinados a serem considerados. Para mais informações, consulte Caracteres duplicados em Unicode .
Pares substitutos: eles surgem com frequência suficiente no SO, então fornecerei alguns exemplos de links:
Outras?:
fonte
fonte
Como sempre é necessário um recurso confiável, mas o relatório oficial é enorme, sugiro que você leia o seguinte:
Uma breve explicação:
Os computadores leem bytes e as pessoas leem caracteres; portanto, usamos padrões de codificação para mapear caracteres para bytes. O ASCII foi o primeiro padrão amplamente utilizado, mas cobre apenas o latim (7 bits / caractere pode representar 128 caracteres diferentes). Unicode é um padrão com o objetivo de cobrir todos os caracteres possíveis no mundo (pode conter até 1.114.112 caracteres, o que significa 21 bits / caractere no máximo. O atual Unicode 8.0 especifica 120.737 caracteres no total, e isso é tudo).
A principal diferença é que um caractere ASCII pode caber em um byte (8 bits), mas a maioria dos caracteres Unicode não. Portanto, formulários / esquemas de codificação (como UTF-8 e UTF-16) são usados, e o modelo de caractere é assim:
Cada caractere mantém uma posição enumerada de 0 a 1.114.111 (hex: 0-10FFFF) chamada ponto de código .
Um formulário de codificação mapeia um ponto de código para uma sequência de unidades de código. Uma unidade de código é a maneira que você deseja que os caracteres sejam organizados na memória, unidades de 8 bits, unidades de 16 bits e assim por diante. O UTF-8 usa 1 a 4 unidades de 8 bits e o UTF-16 usa 1 ou 2 unidades de 16 bits, para cobrir todo o Unicode de no máximo 21 bits. As unidades usam prefixos para que os limites dos caracteres possam ser identificados, e mais unidades significam mais prefixos que ocupam bits. Portanto, embora o UTF-8 use 1 byte para o script latino, ele precisa de 3 bytes para scripts posteriores no Basic Multilingual Plane, enquanto o UTF-16 usa 2 bytes para todos esses. E essa é a principal diferença deles.
Por fim, um esquema de codificação (como UTF-16BE ou UTF-16LE) mapeia (serializa) uma sequência de unidades de código para uma sequência de bytes.
caractere: π
ponto do código: U + 03C0
formulários de codificação (unidades de código):
UTF-8: CF 80
UTF-16: 03C0
esquemas de codificação (bytes):
UTF-8: CF 80
UTF-16BE: 03 C0
UTF-16LE: C0 03
Dica: um dígito hexadecimal representa 4 bits; portanto, um número hexadecimal de dois dígitos representa um byte.
Dê uma olhada nos mapas de avião na Wikipedia para ter uma ideia do layout do conjunto de caracteres
fonte
Originalmente, o Unicode deveria ter uma codificação de 16 bits de largura fixa (UCS-2). Os primeiros usuários do Unicode, como Java e Windows NT, construíram suas bibliotecas em torno de cadeias de caracteres de 16 bits.
Posteriormente, o escopo do Unicode foi expandido para incluir caracteres históricos, o que exigiria mais do que os 65.536 pontos de código suportados por uma codificação de 16 bits. Para permitir que os caracteres adicionais sejam representados nas plataformas que usavam o UCS-2, a codificação UTF-16 foi introduzida. Ele usa "pares substitutos" para representar caracteres nos planos suplementares.
Enquanto isso, muitos softwares e protocolos de rede mais antigos estavam usando cadeias de caracteres de 8 bits. O UTF-8 foi criado para que esses sistemas pudessem suportar Unicode sem precisar usar caracteres largos. É compatível com versões anteriores com ASCII de 7 bits.
fonte
Este artigo explica todos os detalhes http://kunststube.net/encoding/
ESCREVER PARA AMORTECEDOR
se você gravar em um buffer de 4 bytes, símbolo
あ
com codificação UTF8, seu binário ficará assim:00000000 11100011 10000001 10000010
se você gravar em um buffer de 4 bytes, símbolo
あ
com codificação UTF16, seu binário ficará assim:00000000 00000000 00110000 01000010
Como você pode ver, dependendo do idioma que você usaria no seu conteúdo, isso afetará sua memória de acordo.
Por exemplo, para este símbolo em particular: a
あ
codificação UTF16 é mais eficiente, pois temos 2 bytes sobressalentes para usar no próximo símbolo. Mas isso não significa que você deve usar o UTF16 para o alfabeto japonês.LEITURA DO BUFFER
Agora, se você quiser ler os bytes acima, precisará saber em qual codificação foi gravada e decodificá-la novamente.
eg Se você decodificar este: 00000000 11100011 10000001 10000010 em codificação UTF16, você vai acabar com
臣
nãoあ
Nota: Codificação e Unicode são duas coisas diferentes. Unicode é o grande (tabela) com cada símbolo mapeado para um ponto de código exclusivo. por exemplo, o
あ
símbolo (letra) possui um (ponto de código) : 30 42 (hex). A codificação, por outro lado, é um algoritmo que converte símbolos de maneira mais apropriada ao armazenar em hardware.fonte
Unicode é um padrão que mapeia os caracteres em todos os idiomas para um valor numérico específico chamado Code Points . O motivo disso é que permite a possibilidade de codificações diferentes usando o mesmo conjunto de pontos de código.
UTF-8 e UTF-16 são duas dessas codificações. Eles recebem pontos de código como entrada e os codificam usando alguma fórmula bem definida para produzir a sequência codificada.
A escolha de uma codificação específica depende dos seus requisitos. Codificações diferentes têm requisitos de memória diferentes e, dependendo dos caracteres com os quais você estará lidando, você deve escolher a codificação que usa menos sequências de bytes para codificar esses caracteres.
Para obter detalhes mais detalhados sobre Unicode, UTF-8 e UTF-16, confira este artigo,
O que todo programador deve saber sobre Unicode
fonte
Por que unicode? Porque o ASCII possui apenas 127 caracteres. Os de 128 a 255 diferem em diferentes países, é por isso que existem páginas de código. Então eles disseram que vamos ter até 1114111 caracteres. Então, como você armazena o ponto de código mais alto? Você precisará armazená-lo usando 21 bits, para usar um DWORD com 32 bits e 11 bits desperdiçados. Portanto, se você usar um DWORD para armazenar um caractere unicode, é a maneira mais fácil, pois o valor em seu DWORD corresponde exatamente ao ponto de código. Mas as matrizes DWORD são obviamente maiores que as matrizes WORD e, é claro, ainda maiores que as matrizes BYTE. É por isso que não há apenas utf-32, mas também utf-16. Mas utf-16 significa um fluxo WORD, e um WORD possui 16 bits. Como o ponto de código mais alto 1114111 pode se encaixar em um WORD? Eu não posso! Então, eles colocam tudo mais que 65535 em um DWORD que eles chamam de par substituto. Esses pares substitutos são duas PALAVRAS e podem ser detectados observando os primeiros 6 bits. Então, e o utf-8? É uma matriz de bytes ou um fluxo de bytes, mas como o ponto de código mais alto 1114111 se encaixa em um byte? Eu não posso! Ok, então eles colocaram também um DWORD, certo? Ou possivelmente uma PALAVRA, certo? Quase certo! Eles inventaram sequências utf-8, o que significa que todo código de código maior que 127 deve ser codificado em uma sequência de 2 bytes, 3 bytes ou 4 bytes. Uau! Mas como podemos detectar essas seqüências? Bem, tudo até 127 é ASCII e é um byte único. O que começa com 110 é uma sequência de dois bytes, o que começa com 1110 é uma sequência de três bytes e o que começa com 11110 é uma sequência de quatro bytes. Os bits restantes desses chamados "startbytes" pertencem ao ponto de código. Agora, dependendo da sequência, os seguintes bytes devem ser seguidos. Um byte a seguir começa com 10, os bits restantes são 6 bits de carga útil e pertencem ao ponto de código. Concatene os bits da carga útil do startbyte e o seguinte byte / s, e você terá o ponto de código. Essa é toda a magia do utf-8.
fonte
ASCII - O software aloca apenas 8 bits de memória na memória para um determinado caractere. Funciona bem para caracteres em inglês e adotados (palavras de empréstimo como fachada), pois seus valores decimais correspondentes ficam abaixo de 128 no valor decimal. Exemplo de programa C.
UTF-8 - O software aloca 1 a 4 bytes variáveis de 8 bits para um determinado caractere. O que significa variável aqui? Digamos que você esteja enviando o caractere 'A' através de suas páginas HTML no navegador (o HTML é UTF-8), o valor decimal correspondente de A é 65, quando você o converte em decimal, se torna 01000010. Isso requer apenas 1 bytes , 1 byte de memória é alocado mesmo para caracteres especiais em inglês adotados como 'ç' em uma fachada de palavras. No entanto, quando você deseja armazenar caracteres europeus, são necessários 2 bytes, portanto, você precisa de UTF-8. No entanto, quando você procura caracteres asiáticos, precisa de no mínimo 2 bytes e no máximo 4 bytes. Da mesma forma, os Emoji exigem de 3 a 4 bytes. UTF-8 resolverá todas as suas necessidades.
O UTF-16 alocará no mínimo 2 bytes e no máximo 4 bytes por caractere, não alocará 1 ou 3 bytes. Cada caractere é representado em 16 ou 32 bits.
Então, por que existe UTF-16? Originalmente, o Unicode era de 16 bits e não de 8 bits. Java adotou a versão original do UTF-16.
Em poucas palavras, você não precisa de UTF-16 em nenhum lugar, a menos que já tenha sido adotado pelo idioma ou plataforma em que está trabalhando.
O programa Java chamado pelos navegadores da Web usa UTF-16, mas o navegador da Web envia caracteres usando UTF-8.
fonte
UTF significa sigla para Unicode Transformation Format. Basicamente, no mundo de hoje, existem scripts escritos em centenas de outros idiomas, formatos não cobertos pelo ASCII básico usado anteriormente. Portanto, a UTF passou a existir.
O UTF-8 possui recursos de codificação de caracteres e sua unidade de código é de 8 bits, enquanto que para o UTF-16 é de 16 bits.
fonte