Qual é a diferença entre codificação e charset?

151

Estou confuso sobre a codificação e o conjunto de caracteres de texto. Por muitas razões, tenho que aprender coisas que não são Unicode e não UTF8 no meu próximo trabalho.

Eu encontro a palavra "charset" nos cabeçalhos de email, como em "ISO-2022-JP", mas não existe tal codificação nos editores de texto. (Eu olhei em volta dos diferentes editores de texto.)

Qual é a diferença entre codificação de texto e conjunto de caracteres? Eu apreciaria se você pudesse me mostrar alguns exemplos de casos de uso.

TK.
fonte
Veja esta postagem: stackoverflow.com/questions/13743250/…
rghome

Respostas:

144

Basicamente:

  1. charset é o conjunto de caracteres que você pode usar
  2. codificação é a maneira como esses caracteres são armazenados na memória
Svetlozar Angelov
fonte
42
É verdade, mas no uso real "charset" geralmente refere-se a ambos o repertório de caracteres e o esquema de codificação.
Alan Moore
@AlanMoore De fato, da mesma maneira que as pessoas dizem "número decimal" para se referir a qualquer número com um "separador decimal". Não está realmente correto, mas sim, você deve estar ciente de que algumas pessoas o usam assim.
bvdb
2
Isso não está exatamente certo. Por exemplo, Unicode refere-se ao conjunto de caracteres, mas há várias codificações possíveis (UTF-8, UTF-16, UTF-32).
Rgome
84

Toda codificação tem um conjunto de caracteres específico associado, mas pode haver mais de uma codificação para um determinado conjunto de caracteres. Um conjunto de caracteres é simplesmente o que parece, um conjunto de caracteres. Há um grande número de conjuntos de caracteres, incluindo muitos destinados a scripts ou idiomas específicos.

No entanto, estamos no caminho certo na transição para o Unicode, que inclui um conjunto de caracteres capaz de representar quase todos os scripts do mundo. No entanto, existem várias codificações para Unicode. Uma codificação é uma maneira de mapear uma sequência de caracteres para uma sequência de bytes. Exemplos de codificações Unicode incluem UTF-8 , UTF-16 BE e UTF-16 LE . Cada um desses possui vantagens para aplicativos específicos ou arquiteturas de máquinas.

Matthew Flaschen
fonte
20
Observe que o javadoc usa incorretamente "charset" em vez de "codificação", por exemplo, em InputStreamReader , lemos "Um InputStreamReader é uma ponte de fluxos de bytes para fluxos de caracteres: lê bytes e os decodifica em caracteres usando um conjunto de caracteres especificado. ele pode ser especificado pelo nome ou pode ser fornecido explicitamente, ou o conjunto de caracteres padrão da plataforma pode ser aceito ". . No entanto, o que eles querem dizer é "codificação".
David Tonhofer
4
Obrigado pela sua explicação. Unicode é um conjunto de caracteres e UTF-8 é uma maneira de codificação do Unicode , e UTF-16 é outra maneira de codificação do Unicode .
HongchaoZhang
47

Além das outras respostas, acho que este artigo é uma boa leitura http://www.joelonsoftware.com/articles/Unicode.html

O artigo é intitulado " O mínimo absoluto que todo desenvolvedor de software deve saber absolutamente, positivamente sobre conjuntos de caracteres e Unicode (sem desculpas!) ", Escrito por Joel Spolsky . O ensaio tem mais de 10 anos, mas (infelizmente) o conteúdo ainda é válido ...

mattanja
fonte
2
Muito obrigado por apresentar o artigo. Ele é uma boa.
TK.
9
Essa resposta poderia ser melhorada, dando uma breve explicação sobre por que eu deveria ler o artigo de Joel.
James.garriss 20/09/2013
@mattanja O link que você forneceu é realmente ótimo. Obrigado por compartilhar. Votado.
hagrawal
1
Também quero colocar este ótimo artigo, que é um apêndice ao de Joel Spolsky; kunststube.net/encoding
mkb
Não entendi o artigo de Joel na minha primeira leitura. Em vez eu encontrei este powerpoint para ser muito mais clara e específica: unicode.org/notes/tn23/Muller-Slides+Narr.pdf
johnsimer
27

Uma codificação de caracteres consiste em:

  1. O conjunto de caracteres suportados
  2. Um mapeamento entre caracteres e números inteiros ("pontos de código")
  3. Como os pontos de código são codificados como uma série de "unidades de código" (por exemplo, unidades de 16 bits para UTF-16)
  4. Como as unidades de código são codificadas em bytes (por exemplo, big endian ou little endian)

O passo 1 é, por si só, um "repertório de caracteres" ou um "conjunto de caracteres abstrato" e o número 1 + # 2 = um "conjunto de caracteres codificados".

Mas antes de o Unicode se tornar popular e todo mundo (exceto os asiáticos orientais) estava usando uma codificação de byte único, as etapas 3 e 4 eram triviais (ponto de código = unidade de código = byte). Assim, protocolos mais antigos não distinguiam claramente entre "codificação de caracteres" e "conjunto de caracteres codificados". Protocolos mais antigos usam charsetquando realmente significam codificação.

dan04
fonte
seria por que podemos ler charset = 'utf-8' na tag html META? porque foi definido há muito tempo
Eildosa 15/09/2015
26

Lançar mais luz para as pessoas que visitam a partir de agora, espero que seja útil.


Conjunto de caracteres

Existem caracteres em cada idioma e a coleção desses caracteres forma o "conjunto de caracteres" desse idioma. Quando um caractere é codificado, ele recebe um identificador exclusivo ou um número chamado como ponto de código. No computador, esses pontos de código serão representados por um ou mais bytes.

Exemplos de conjunto de caracteres: ASCII (abrange todos os caracteres em inglês), ISO / IEC 646, Unicode (abrange caracteres de todos os idiomas vivos do mundo)

Conjunto de caracteres codificados

Um conjunto de caracteres codificados é um conjunto no qual um número exclusivo é atribuído a cada caractere. Esse número exclusivo é chamado como "ponto de código".
Conjuntos de caracteres codificados às vezes são chamados de páginas de código.

Codificação

Codificação é o mecanismo para mapear os pontos de código com alguns bytes, para que um caractere possa ser lido e gravado uniformemente em diferentes sistemas usando o mesmo esquema de codificação.

Exemplos de codificação: esquemas de codificação ASCII, Unicode, como UTF-8, UTF-16, UTF-32.

Elaboração dos 3 conceitos acima

  • Considere isto - o caractere 'क' no conjunto de caracteres Devanagari possui um ponto de código decimal 2325 que será representado por dois bytes ( 09 15) ao usar a codificação UTF-16
  • No esquema de codificação “ISO-8859-1”, “ü” (isso não passa de um caractere no conjunto de caracteres latinos) é representado como valor hexa-decimal, FCenquanto em “UTF-8” ele é representado como C3 BCe em UTF-16 comoFE FF 00 FC .
  • Esquemas de codificação diferentes podem usar o mesmo ponto de código para representar caracteres diferentes. Por exemplo, em “ISO-8859-1” (também chamado de Latin1), o valor do ponto de código decimal para a letra 'é' é 233. No entanto, na ISO 8859-5 , o mesmo ponto de código representa o caracter cirílico 'щ'.
  • Por outro lado, um único ponto de código no conjunto de caracteres Unicode pode realmente ser mapeado para diferentes seqüências de bytes, dependendo de qual codificação foi usada para o documento. O caractere Devanagari क, com o ponto de código 2325 (que é 915 em notação hexadecimal), será representado por dois bytes ao usar a codificação UTF-16 ( 09 15), três bytes com UTF-8 ( E0 A4 95) ou quatro bytes com UTF-32 ( 00 00 09 15)
hagrawal
fonte
11

Um conjunto de caracteres, ou repertório de caracteres, é simplesmente um conjunto (uma coleção não ordenada) de caracteres. Um conjunto de caracteres codificados atribui um número inteiro (um "ponto de código") a cada caractere no repertório. Uma codificação é uma maneira de representar pontos de código inequivocamente como um fluxo de bytes.

Jonathan Feinberg
fonte
Essa deve ser a resposta aceita. Ele define claramente três conceitos: conjunto de caracteres, conjunto de caracteres codificados e codificação.
Marcus Junius Brutus
6

Pesquisei no Google. http://en.wikipedia.org/wiki/Character_encoding

A diferença parece ser sutil. O termo charset, na verdade, não se aplica ao Unicode. O Unicode passa por uma série de abstrações. caracteres abstratos -> pontos de código -> codificação de pontos de código em bytes.

Os conjuntos de caracteres, na verdade, pulam isso e pulam diretamente de caracteres para bytes. sequência de bytes <-> sequência de caracteres

Em resumo, a codificação: pontos de código -> bytes charset: caracteres -> bytes

Fakrudeen
fonte
5

Um conjunto de caracteres é apenas um conjunto; ou contém, por exemplo, o símbolo do Euro, ou não. Isso é tudo.

Uma codificação é um mapeamento bijetivo de um conjunto de caracteres para um conjunto de números inteiros. Se ele suportar o sinal do Euro, deverá atribuir um número inteiro específico a esse caractere e a nenhum outro.

Kilian Foth
fonte
Tem que ser bijetivo?
Jörg W Mittag
2
Bem, a codificação e a decodificação devem ser determinísticas, portanto, realmente não pode haver nenhum mapeamento ambíguo. Suponho que você possa ter um conjunto não inteiro de números inteiros como codomain, mas isso desperdiçaria espaço quando você armazena texto, e os engenheiros odeiam espaço desperdiçado.
Kilian Foth
1
As codificações de caracteres herdadas geralmente não são bijetivas. Por exemplo, no IBM437, ß e β são representados por 0xE1.
dan04
3

Na minha opinião, um charset faz parte de uma codificação (um componente), a codificação possui um atributo charset, portanto, um charset pode ser usado em muitas codificações. Por exemplo, unicode é um conjunto de caracteres usado em codificações como UTF-8, UTF-16 e assim por diante. Veja a ilustração aqui:Veja a ilustração aqui

O char no charset não significa o tipo de char no mundo da programação, significa um char no mundo real, em inglês talvez o mesmo, mas em outros idiomas não, como o chinês, '我' é um 'char' inseparável em charsets (UNICODE, GB [usado em GBK e GB2312]), 'a' também é um caractere em conjuntos de caracteres (ASCII, ISO-8859 , UNICODE).

Eric Liu
fonte
1

Na minha opinião, a palavra "charset" deve se limitar à identificação do parâmetro usado em HTTP, MIME e padrões semelhantes para especificar uma codificação de caracteres (um mapeamento de uma série de caracteres de texto para uma sequência de bytes) pelo nome. Por exemplo: charset=utf-8.

Estou ciente, no entanto, de que MySQL, Java e outros lugares podem usar a palavra "charset" para significar uma codificação de caracteres.

Peter O.
fonte
1

Uma codificação é um mapeamento entre bytes e caracteres de um conjunto de caracteres, portanto, será útil discutir e entender a diferença entre bytes e caracteres .

Pense em bytes como números entre 0 e 255, enquanto caracteres são coisas abstratas como "a", "1", "$" e "Ä". O conjunto de todos os caracteres disponíveis é chamado de conjunto de caracteres .

Cada caractere possui uma sequência de um ou mais bytes usados ​​para representá-lo; no entanto, o número exato e o valor dos bytes dependem da codificação usada e há muitas codificações diferentes.

A maioria das codificações é baseada em um conjunto de caracteres antigo e codificação chamado ASCII, que é um byte único por caractere (na verdade, apenas 7 bits) e contém 128 caracteres, incluindo muitos caracteres comuns usados ​​no inglês dos EUA.

Por exemplo, aqui estão 6 caracteres no conjunto de caracteres ASCII representados pelos valores 60 a 65.

Extract of ASCII Table 60-65
╔══════╦══════════════╗
║ Byte ║  Character   ║
╠══════╬══════════════║
║  60  ║      <       ║
║  61  ║      =       ║
║  62  ║      >       ║
║  63  ║      ?       ║
║  64  ║      @       ║
║  65  ║      A       ║
╚══════╩══════════════╝

No conjunto ASCII completo, o valor mais baixo usado é zero e o mais alto é 127 (ambos são caracteres de controle ocultos).

No entanto, quando você começa a precisar de mais caracteres do que o ASCII básico fornece (por exemplo, letras com acentos, símbolos de moeda, símbolos gráficos etc.), o ASCII não é adequado e você precisa de algo mais extenso. Você precisa de mais caracteres (um conjunto de caracteres diferente) e uma codificação diferente, pois 128 caracteres não são suficientes para caber todos os caracteres. Algumas codificações oferecem um byte (256 caracteres) ou até seis bytes.

Com o tempo, muitas codificações foram criadas. No mundo Windows, existe o CP1252, ou ISO-8859-1, enquanto os usuários do Linux tendem a favorecer o UTF-8. Java usa UTF-16 nativamente.

Uma sequência de valores de bytes para um caractere em uma codificação pode representar um caractere completamente diferente em outra codificação ou pode até ser inválida.

Por exemplo, na norma ISO 8859-1 , â é representado por um byte de valor 226, ao passo que em UTF-8 é dois bytes: 195, 162. No entanto, na ISO 8859-1 , 195, 162haveria dois caracteres, Ã, ¢ .

Quando os computadores armazenam dados sobre caracteres internamente ou os transmitem para outro sistema, eles armazenam ou enviam bytes. Imagine um sistema abrindo um arquivo ou recebendo uma mensagem veja os bytes195, 162 . Como ele sabe quais são esses personagens?

Para que o sistema interprete esses bytes como caracteres reais (e, portanto, os exiba ou os converta em outra codificação), ele precisa conhecer a codificação usada. É por isso que a codificação aparece nos cabeçalhos XML ou pode ser especificada em um editor de texto. Diz ao sistema o mapeamento entre bytes e caracteres.

rghome
fonte