Eu ouvi opiniões conflitantes de pessoas - de acordo com a página UTF-8 da Wikipedia .
Eles são a mesma coisa, não são? Alguém pode esclarecer?
Eu ouvi opiniões conflitantes de pessoas - de acordo com a página UTF-8 da Wikipedia .
Eles são a mesma coisa, não são? Alguém pode esclarecer?
Respostas:
Para expandir as respostas que outras pessoas deram:
Temos muitos idiomas com muitos caracteres que os computadores devem exibir idealmente. Unicode atribui a cada caractere um número único ou ponto de código.
Os computadores lidam com números como bytes ... pulando um pouco da história aqui e ignorando os problemas de memória, os computadores de 8 bits tratam um byte de 8 bits como a maior unidade numérica facilmente representada no hardware, os computadores de 16 bits se expandem isso para dois bytes, e assim por diante.
As codificações de caracteres antigas, como ASCII, são da era (pré) de 8 bits e tentam compactar o idioma dominante na computação da época, ou seja, o inglês, em números que variam de 0 a 127 (7 bits). Com 26 letras no alfabeto, tanto em maiúsculas quanto em maiúsculas, números e sinais de pontuação, funcionou muito bem. O ASCII foi estendido em um oitavo bit para outros idiomas que não o inglês, mas os 128 números / pontos de código adicionais disponibilizados por essa expansão seriam mapeados para caracteres diferentes, dependendo do idioma exibido. Os padrões ISO-8859 são as formas mais comuns desse mapeamento; ISO-8859-1 e ISO-8859-15 (também conhecidas como ISO-Latin-1, latin1 e sim, existem duas versões diferentes do padrão ISO 8859 também).
Mas isso não é suficiente quando você deseja representar caracteres de mais de um idioma, portanto, agrupar todos os caracteres disponíveis em um único byte simplesmente não funcionará.
Existem essencialmente dois tipos diferentes de codificação: um expande a faixa de valores adicionando mais bits. Exemplos dessas codificações seriam UCS2 (2 bytes = 16 bits) e UCS4 (4 bytes = 32 bits). Eles sofrem inerentemente do mesmo problema que os padrões ASCII e ISO-8859, pois sua faixa de valor ainda é limitada, mesmo que o limite seja muito maior.
O outro tipo de codificação usa um número variável de bytes por caractere, e as codificações mais comumente conhecidas para isso são as codificações UTF. Todas as codificações UTF funcionam aproximadamente da mesma maneira: você escolhe um tamanho de unidade, que para UTF-8 é de 8 bits, para UTF-16 é de 16 bits e para UTF-32 é de 32 bits. O padrão define alguns desses bits como sinalizadores: se eles estiverem definidos, a próxima unidade em uma sequência de unidades será considerada parte do mesmo caractere. Se não estiverem definidas, esta unidade representa um caractere completo. Portanto, os caracteres mais comuns (em inglês) ocupam apenas um byte em UTF-8 (dois em UTF-16, 4 em UTF-32), mas outros caracteres de idioma podem ocupar seis bytes ou mais.
As codificações de vários bytes (devo dizer várias unidades após a explicação acima) têm a vantagem de serem relativamente eficientes em termos de espaço, mas a desvantagem de operações como encontrar substrings, comparações etc., todos eles precisam decodificar os caracteres para o código unicode pontos antes que essas operações possam ser executadas (existem alguns atalhos).
Os padrões UCS e UTF codificam os pontos de código conforme definido em Unicode. Em teoria, essas codificações poderiam ser usadas para codificar qualquer número (dentro do intervalo que a codificação suporta) - mas é claro que essas codificações foram feitas para codificar pontos de código Unicode. E esse é o seu relacionamento entre eles.
O Windows manipula as chamadas seqüências de caracteres "Unicode" como UTF-16, enquanto a maioria dos UNIXes usa como padrão o UTF-8 atualmente. Protocolos de comunicação como HTTP tendem a funcionar melhor com UTF-8, pois o tamanho da unidade em UTF-8 é o mesmo que em ASCII, e a maioria desses protocolos foi projetada na era ASCII. Por outro lado, o UTF-16 oferece o melhor desempenho médio de espaço / processamento ao representar todos os idiomas ativos.
O padrão Unicode define menos pontos de código do que pode ser representado em 32 bits. Portanto, para todos os fins práticos, UTF-32 e UCS4 se tornaram a mesma codificação, pois é improvável que você precise lidar com caracteres de várias unidades em UTF-32.
Espero que preencha alguns detalhes.
0x04000000
até 0x7FFFFFFF
, ou em binário, é 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
- e são de fato 6 bytes. No entanto, 6 bytes É o máximo e não como o artigo afirma confundidamente "seis bytes ou mais ".
Deixe-me usar um exemplo para ilustrar este tópico:
A chinese character: 汉
it's unicode value: U+6C49
convert 6C49 to binary: 01101100 01001001
Nada mágico até agora, é muito simples. Agora, digamos que decidimos armazenar esse personagem em nosso disco rígido. Para fazer isso, precisamos armazenar o caractere em formato binário. Podemos simplesmente armazená-lo como está '01101100 01001001'. Feito!
Mas espere um minuto, '01101100 01001001' é um ou dois caracteres? Você sabia que esse é um personagem porque eu lhe disse, mas quando um computador lê, ele não faz ideia. Portanto, precisamos de algum tipo de "codificação" para dizer ao computador para tratá-lo como um.
É aqui que as regras do 'UTF-8' entram: http://www.fileformat.info/info/unicode/utf8.htm
Binary format of bytes in sequence
1st Byte 2nd Byte 3rd Byte 4th Byte Number of Free Bits Maximum Expressible Unicode Value
0xxxxxxx 7 007F hex (127)
110xxxxx 10xxxxxx (5+6)=11 07FF hex (2047)
1110xxxx 10xxxxxx 10xxxxxx (4+6+6)=16 FFFF hex (65535)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (3+6+6+6)=21 10FFFF hex (1,114,111)
De acordo com a tabela acima, se queremos armazenar esse caractere usando o formato 'UTF-8', precisamos prefixar nosso caractere com alguns 'cabeçalhos'. Nosso caractere chinês tem 16 bits (conte o valor binário), portanto, usaremos o formato na linha 3, pois ele fornece espaço suficiente:
Header Place holder Fill in our Binary Result
1110 xxxx 0110 11100110
10 xxxxxx 110001 10110001
10 xxxxxx 001001 10001001
Escrevendo o resultado em uma linha:
11100110 10110001 10001001
Este é o valor UTF-8 (binário) do caractere chinês! (confirme você mesmo: http://www.fileformat.info/info/unicode/char/6c49/index.htm )
A chinese character: 汉
it's unicode value: U+6C49
convert 6C49 to binary: 01101100 01001001
embed 6C49 as UTF-8: 11100110 10110001 10001001
PS Se você quiser aprender este tópico em python, clique aqui
0
, o caractere é representado por 1 mordida (a atual), se o byte começa com 110
, o caractere é representado por 2 bytes (o atual e o próximo ( bits restantes depois 10
)), se o byte começar com 1110
, o caractere será representado por 3 bytes, o atual e os próximos 2 bytes (bits restantes depois 10
).
Infelizmente, o "Unicode" é usado de várias maneiras diferentes, dependendo do contexto. Seu uso mais correto (IMO) é como um conjunto de caracteres codificados - ou seja, um conjunto de caracteres e um mapeamento entre os caracteres e os pontos de código inteiro que os representam.
UTF-8 é uma codificação de caracteres - uma maneira de converter de sequências de bytes para sequências de caracteres e vice-versa. Abrange todo o conjunto de caracteres Unicode. O ASCII é codificado como um byte único por caractere, e outros caracteres levam mais bytes, dependendo do ponto de código exato (até 4 bytes para todos os pontos de código definidos atualmente, ou seja, até U-0010FFFF, e de fato 4 bytes podem lidar com até U-001FFFFF).
Quando "Unicode" é usado como o nome de uma codificação de caracteres (por exemplo, a propriedade .NET Encoding.Unicode ), geralmente significa UTF-16 , que codifica os caracteres mais comuns como dois bytes. Algumas plataformas (principalmente .NET e Java) usam UTF-16 como sua codificação de caracteres "nativa". Isso leva a problemas complicados se você precisar se preocupar com caracteres que não podem ser codificados em um único valor UTF-16 (eles são codificados como "pares substitutos") - mas a maioria dos desenvolvedores nunca se preocupa com isso, IME.
Algumas referências no Unicode:
Eles não são a mesma coisa - o UTF-8 é uma maneira específica de codificar Unicode.
Você pode escolher entre várias codificações diferentes, dependendo do aplicativo e dos dados que pretende usar. Os mais comuns são UTF-8, UTF-16 e UTF-32 s, até onde eu sei.
Unicode define apenas pontos de código , ou seja, um número que representa um caractere. Como você armazena esses pontos de código na memória depende da codificação que você está usando. UTF-8 é uma maneira de codificar caracteres Unicode, entre muitos outros.
Unicode é um padrão que define, juntamente com o ISO / IEC 10646, Universal Character Set (UCS), que é um superconjunto de todos os caracteres existentes necessários para representar praticamente todos os idiomas conhecidos.
O Unicode atribui um nome e um número ( código de caractere ou ponto de código ) a cada caractere em seu repertório.
A codificação UTF-8 é uma maneira de representar esses caracteres digitalmente na memória do computador. UTF-8 mapeia cada ponto de código em uma sequência de octetos (bytes de 8 bits)
Por exemplo,
Caractere UCS = Caractere Han Unicode
Ponto de código UCS = U + 24B62
Codificação UTF-8 = F0 A4 AD A2 (hex) = 11110000 10100100 10101101 10100010 (bin)
http://www.wikiwand.com/en/UTF-8#/Description
Dê uma olhada na primeira linha.
Unicode é apenas um padrão que define um conjunto de caracteres ( UCS ) e codificações ( UTF ) para codificar esse conjunto de caracteres. Mas, em geral, Unicode é referido ao conjunto de caracteres e não ao padrão.
Leia o mínimo absoluto que todo desenvolvedor de software deve saber absolutamente, positivamente sobre Unicode e conjuntos de caracteres (sem desculpas!) E Unicode em 5 minutos .
As respostas existentes já explicam muitos detalhes, mas aqui está uma resposta muito curta com a explicação e o exemplo mais diretos.
Unicode é o padrão que mapeia caracteres para pontos de código.
Cada caractere tem um ponto de código exclusivo (número de identificação), que é um número como 9731.
UTF-8 é a codificação dos pontos de código.
Para armazenar todos os caracteres no disco (em um arquivo), o UTF-8 divide os caracteres em até 4 octetos (sequências de 8 bits) - bytes. UTF-8 é uma das várias codificações (métodos de representação de dados). Por exemplo, em Unicode, o ponto de código (decimal) 9731 representa um boneco de neve ( ☃
), que consiste em 3 bytes em UTF-8:E2 98 83
Aqui está uma lista classificada com alguns exemplos aleatórios .
Existem muitos personagens em todo o mundo, como "$, &, h, a, t,?, 张, 1, =, + ...".
Depois, chega uma organização dedicada a esses personagens,
Eles criaram um padrão chamado "Unicode".
O padrão é o seguinte:
PS: É claro que há outra organização chamada ISO mantendo outro padrão - "ISO 10646" - quase o mesmo.
Como acima, U + 0024 é apenas uma posição, portanto não podemos salvar "U + 0024" no computador para o caractere "$".
Deve haver um método de codificação.
Existem métodos de codificação, como UTF-8, UTF-16, UTF-32, UCS-2 ....
Sob UTF-8, o ponto de código "U + 0024" é codificado em 00100100.
00100100 é o valor que economizamos no computador para "$".
Eu verifiquei os links na resposta do Gumbo e queria colar parte dessas coisas aqui para existir também no Stack Overflow.
"... Algumas pessoas estão erradas no conceito de que Unicode é simplesmente um código de 16 bits, em que cada caractere ocupa 16 bits e, portanto, existem 65.536 caracteres possíveis. Na verdade, isso não está correto. É o mito mais comum sobre Unicode. , se você pensou assim, não se sinta mal.
De fato, o Unicode tem uma maneira diferente de pensar sobre os personagens, e você precisa entender a maneira como as coisas são pensadas ou nada fará sentido.
Até agora, assumimos que uma carta mapeia para alguns bits que você pode armazenar no disco ou na memória:
A -> 0100 0001
No Unicode, uma carta é mapeada para algo chamado ponto de código, que ainda é apenas um conceito teórico. Como esse ponto de código é representado na memória ou no disco é outra história ... "
"... Cada letra platônica de cada alfabeto recebe um número mágico do consórcio Unicode, que é escrito assim: U + 0639. Esse número mágico é chamado de ponto de código. O U + significa" Unicode "e os números são hexadecimais. U + 0639 é a letra árabe Ain. A letra em inglês A seria U + 0041 .... "
"... OK, digamos que temos uma string:
Olá
que, em Unicode, corresponde a esses cinco pontos de código:
U + 0048 U + 0065 U + 006C U + 006C U + 006F.
Apenas um monte de pontos de código. Números, realmente. Ainda não dissemos nada sobre como armazenar isso na memória ou representá-lo em uma mensagem de e-mail ... "
"... É aí que entram as codificações.
A idéia mais antiga para a codificação Unicode, que levou ao mito sobre os dois bytes, foi, ei, vamos armazenar esses números em dois bytes cada. Então Olá se torna
00 48 00 65 00 6C 00 6C 00 6F
Direita? Não tão rápido! Também não poderia ser:
48 00 65 00 6C 00 6C 00 6F 00? ... "
UTF-8 é um esquema de codificação possível para texto Unicode .
Unicode é um padrão de escopo amplo que define mais de 130.000 caracteres e atribui a cada um código numérico (um ponto de código). Ele também define regras de como classificar este texto, normalizá-lo, alterar seu caso e muito mais. Um caractere no Unicode é representado por um ponto de código de zero a 0x10FFFF, inclusive, embora alguns pontos de código sejam reservados e não possam ser usados para caracteres.
Há mais de uma maneira em que uma sequência de pontos de código Unicode pode ser codificada em um fluxo binário. Estes são chamados de "codificações". A codificação mais direta é UTF-32 , que simplesmente armazena cada ponto de código como um número inteiro de 32 bits, cada um com 4 bytes de largura.
O UTF-8 é outra codificação e está se tornando o padrão de fato, devido a várias vantagens sobre o UTF-32 e outras. UTF-8 codifica como uma sequência de valores de byte único. Cada ponto de código pode usar um número variável desses valores de bytes. Os pontos de código no intervalo ASCII são codificados, para serem compatíveis com o ASCII. Os pontos de código fora desse intervalo usam um número variável de bytes, 2, 3 ou 4, dependendo do intervalo em que estão.
O UTF-8 foi projetado com estas propriedades em mente:
Os caracteres ASCII são codificados exatamente como no ASCII, de modo que uma sequência ASCII também seja uma sequência UTF-8 válida.
Classificação binária: a classificação de cadeias UTF-8 usando uma classificação binária ingênua ainda resultará na classificação de todos os pontos de código em ordem numérica.
Os caracteres que requerem vários bytes não contêm valores de bytes no intervalo ASCII, garantindo que parte deles não possa ser confundida com caracteres ASCII. Esse também é um recurso de segurança.
O UTF-8 pode ser facilmente validado e diferenciado de outras codificações de caracteres por um validador. O texto em outras codificações de 8 bits ou de vários bytes muito raramente será validado como UTF-8.
Acesso aleatório: Em qualquer ponto da string UTF-8, é possível saber se o byte nessa posição é o primeiro byte de um caractere ou não, e encontrar o início do caractere seguinte ou atual, sem precisar avançar. ou mais de alguns bytes para trás ou leia qualquer coisa no início do fluxo.
Eles são a mesma coisa, não são?
Não, eles não são.
Acho que a primeira frase da página da Wikipedia que você mencionou fornece um resumo breve e agradável:
UTF-8 é uma codificação de caracteres de largura variável capaz de codificar todos os 1.112.064 pontos de código válidos no Unicode usando um a quatro bytes de 8 bits.
Para elaborar:
Unicode é um padrão, que define um mapa de caracteres para números, os chamados pontos de código (como no exemplo abaixo). Para o mapeamento completo, você pode dar uma olhada aqui .
! -> U+0021 (21),
" -> U+0022 (22),
\# -> U+0023 (23)
UTF-8 é uma das maneiras de codificar esses pontos de código de uma forma que um computador possa entender, também conhecido como bits . Em outras palavras, é uma maneira / algoritmo de converter cada um desses pontos de código em uma sequência de bits ou converter uma sequência de bits em pontos de código equivalentes. Observe que existem muitas codificações alternativas para Unicode.
Joel dá uma explicação muito boa e uma visão geral da história aqui .
Se eu puder resumir o que reuni neste tópico:
Unicode 'traduz' caracteres para números ordinais (na forma decimal) .
à = 224
UTF-8 é uma codificação que 'converte' esses números em representações binárias .
224 = 11000011 10100000
Observe que estamos falando da representação binária de 224, não de sua forma binária, que é 0b11100000.
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.
30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.
30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.