Quando coloco 'a' em um arquivo de texto, ele produz 2 bytes, mas quando coloco, digamos 'ա', que é uma letra do alfabeto armênio, produz 3 bytes.
Qual é a diferença entre alfabetos para um computador?
Por que o inglês ocupa menos espaço?
Quando coloco 'a' em um arquivo de texto, ele produz 2 bytes, mas quando coloco, digamos 'ա', que é uma letra do alfabeto armênio, produz 3 bytes.
Qual é a diferença entre alfabetos para um computador?
Por que o inglês ocupa menos espaço?
Respostas:
Um dos primeiros esquemas de codificação a serem desenvolvidos para uso em computadores convencionais é o padrão ASCII ( American Standard Code for Information Interchange ). Foi desenvolvido na década de 1960 nos Estados Unidos.
O alfabeto inglês usa parte do alfabeto latino (por exemplo, existem poucas palavras acentuadas em inglês). Existem 26 letras individuais nesse alfabeto, sem considerar o caso. E também teria que existir os números e sinais de pontuação individuais em qualquer esquema que pretenda codificar o alfabeto inglês.
A década de 1960 também foi uma época em que os computadores não tinham a quantidade de memória ou espaço em disco que temos agora. O ASCII foi desenvolvido para ser uma representação padrão de um alfabeto funcional em todos os computadores americanos. Na época, a decisão de fazer com que todos os caracteres ASCII tivessem 8 bits (1 byte) de comprimento foi tomada devido a detalhes técnicos da época (o artigo da Wikipedia menciona o fato de que a fita perfurada mantinha 8 bits em uma posição por vez). De fato, o esquema ASCII original pode ser transmitido usando 7 bits, os oito podem ser usados para verificações de paridade. Desenvolvimentos posteriores expandiram o esquema ASCII original para incluir vários caracteres acentuados, matemáticos e terminais.
Com o recente aumento do uso de computadores em todo o mundo, mais e mais pessoas de diferentes idiomas tiveram acesso a um computador. Isso significava que, para cada idioma, novos esquemas de codificação tinham que ser desenvolvidos, independentemente de outros esquemas, que entrariam em conflito se lidos em terminais de idiomas diferentes.
O Unicode surgiu como uma solução para a existência de diferentes terminais, mesclando todos os caracteres significativos possíveis em um único conjunto de caracteres abstratos.
UTF-8 é uma maneira de codificar o conjunto de caracteres Unicode. É uma codificação de largura variável (por exemplo, caracteres diferentes podem ter tamanhos diferentes) e foi projetada para compatibilidade retroativa com o antigo esquema ASCII. Como tal, o conjunto de caracteres ASCII permanecerá com um byte grande, enquanto outros caracteres terão dois ou mais bytes. UTF-16 é outra maneira de codificar o conjunto de caracteres Unicode. Em comparação com UTF-8, os caracteres são codificados como um conjunto de uma ou duas unidades de código de 16 bits.
Conforme declarado nos comentários, o caractere 'a' ocupa um único byte enquanto 'ա' ocupa dois bytes, denotando uma codificação UTF-8. O byte extra na sua pergunta ocorreu devido à existência de um caractere de nova linha no final (sobre o qual o OP descobriu).
echo 'ա' > file.txt
o editar ou editar usando alguns editores, eles adicionarão automaticamente uma nova linha após ela. Se você executar xxd file.txt
, o último byte provavelmente será um 0a
feed de linha.
a
, usará dois bytes (ou um múltiplo de dois).
1 byte é 8 bits e, portanto, pode representar até 256 (2 ^ 8) valores diferentes.
Para idiomas que exigem mais possibilidades do que isso, um mapeamento simples de 1 para 1 não pode ser mantido; portanto, são necessários mais dados para armazenar um caractere.
Observe que, geralmente, a maioria das codificações usa os primeiros 7 bits (128 valores) para caracteres ASCII . Isso deixa o oitavo bit, ou 128 mais valores para mais caracteres. . . adicione caracteres acentuados, idiomas asiáticos, cirílico etc., e você poderá ver facilmente por que 1 byte não é suficiente para manter todos os caracteres.
No UTF-8, os caracteres ASCII usam um byte, outros caracteres usam dois, três ou quatro bytes.
A quantidade de bytes necessários para um caractere (sobre o qual a pergunta é aparentemente) depende da codificação de caracteres. Se você usar a codificação ArmSCII, cada letra armênia ocupa apenas um byte. Hoje em dia, não é uma boa escolha.
Na codificação de transferência UTF-8 para Unicode, os caracteres precisam de um número diferente de bytes. Nele, “a” ocupa apenas um byte (a idéia de dois bytes é uma espécie de confusão), “á” ocupa dois bytes e a letra armênia ayb “ա” também ocupa dois bytes. Três bytes devem ser algum tipo de confusão. Por outro lado, por exemplo, a letra bengali a “অ” ocupa três bytes em UTF-8.
O pano de fundo é simplesmente que o UTF-8 foi projetado para ser muito eficiente para caracteres Ascii, bastante eficiente para sistemas de escrita na Europa e arredores e todo o resto é menos eficiente. Isso significa que, em letras latinas básicas (que é basicamente o texto em inglês), é necessário apenas um byte para um caractere; para grego, cirílico, armênio e alguns outros, são necessários dois bytes; todo o resto precisa de mais.
O UTF-8 possui (como apontado em um comentário) também a propriedade útil de que os dados Ascii (quando representados como unidades de 8 bits, que são quase a única maneira há muito tempo) também são trivialmente codificados por UTF-8.
Os códigos de caracteres na década de 1960 (e muito além) eram específicos da máquina. Nos anos 80, usei brevemente uma máquina DEC 2020, que tinha 36 bits de palavras e 5, 6 e 8 ( IIRC ) bits por codificação de caracteres. Antes disso, usei uma série IBM 370 com EBCDIC. O ASCII com 7 bits trouxe ordem, mas causou confusão com as "páginas de código" do IBM PC usando todos os 8 bits para representar caracteres extras, como todo tipo de desenho de caixa para pintar menus primitivos e extensões ASCII posteriores, como o Latin-1 (8 bits). codificações, com os primeiros 7 bits como ASCII e a outra metade para "caracteres nacionais" como ñ
, Ç
ou outros. Provavelmente o mais popular foi o Latin-1, adaptado ao inglês e à maioria dos idiomas europeus usando caracteres latinos (e sotaques e variantes).
Escrever texto misturando, por exemplo, inglês e espanhol correu bem (basta usar o latim-1, superconjunto de ambos), mas misturar qualquer coisa que usasse codificações diferentes (por exemplo, incluir um trecho de grego ou russo, sem mencionar um idioma asiático como o japonês) foi um verdadeiro pesadelo. O pior foi que o russo, principalmente o japonês e o chinês, possuíam várias codificações populares e completamente incompatíveis.
Hoje usamos Unicode, que é acoplado a codificações eficientes como UTF-8 que favorecem caracteres em inglês (surpreendentemente, a codificação de letras em inglês corresponde a ASCII), fazendo com que muitos caracteres que não sejam do inglês usem codificações mais longas.
Arquivo em inglês / americano do Windows 8.1 com um único 'a' salvo no bloco de notas.
Arquivo com um único 'ա' salvo com o bloco de notas
Um único 'a' é codificado como um byte único no ANSI; no Unicode, cada caractere geralmente tem 2 bytes; também há uma lista técnica de 2 bytes no início do arquivo. O UTF-8 possui uma lista técnica de 3 bytes e o caractere de byte único.
Para o 'ա', esse caractere não existe no conjunto de caracteres ANSI e não pode ser salvo na minha máquina. O arquivo Unicode é o mesmo de antes e o arquivo UTF-8 é 1 byte maior, pois o caractere leva 2 bytes.
Se a sua máquina for de uma região diferente, você pode ter uma página de código OEM diferente instalada, com glifos diferentes para os 255 caracteres possíveis no intervalo ASCII. Como o @ntoskrnl mencionou, a página de códigos OEM da minha máquina seria Windows-1252, que é o padrão para o inglês dos EUA.
Se você estiver interessado em saber como os caracteres são armazenados, acesse www.unicode.org e dê uma olhada. No topo da página principal, há um link "Gráficos de códigos" que mostra todos os códigos de caracteres disponíveis no Unicode.
Em suma, há um pouco mais de um milhão de códigos disponíveis no Unicode (nem todos são usados). Um byte pode conter 256 valores diferentes; portanto, você precisará de três bytes se desejar armazenar todos os códigos Unicode possíveis.
Em vez disso, o Unicode geralmente é armazenado na codificação "UTF-8", que usa menos bytes para alguns caracteres e mais para outros. Os primeiros 128 valores de código são armazenados em um único byte, até os primeiros valores de código 2048 são armazenados em dois bytes, até 65536 são armazenados em três bytes e o restante ocupa quatro bytes. Isso foi organizado para que os valores de código usados com mais frequência ocupem menos espaço. AZ, az, 0-9 e! @ $% ^ & * () - [} {}; ': "|,. / <>? E alguns que eu esqueci de usar um byte; quase todo o inglês, 98% de Alemão e francês (apenas adivinhando) podem ser armazenados em um byte por caractere, e esses são os caracteres mais usados: cirílico, grego, hebraico, árabe e outros usam dois bytes por caractere. , Coreano, tailandês, toneladas de símbolos matemáticos, pode ser escrito em três bytes por caractere. Coisas raras (se você quiser escrever texto em Linear A ou Linear B, Emojis) levam quatro bytes.
Outra codificação é UTF-16. Tudo o que leva 1, 2 ou 3 bytes em UTF-8 leva dois bytes em UTF-16. Essa é uma vantagem se você tiver texto em chinês ou japonês com muito poucos caracteres latinos no meio.
Sobre os motivos do design UTF-8: Possui várias vantagens sobre outros designs. Eles são:
Compatibilidade com caracteres US-ASCII
Compacidade razoável
Auto-sincronização: Isso significa que, se você receber parte de uma sequência de bytes que são caracteres na codificação UTF-8, poderá descobrir onde os caracteres são iniciados. Em algumas codificações, xy e yx podem ser codificações válidas de caracteres, portanto, se você receber parte de uma sequência ... xyxyxyxyxyxy ... não poderá saber quais caracteres você possui.
Correção da classificação: se você classificar cadeias contendo caracteres codificados em UTF-8 pelos valores de bytes, elas serão automaticamente classificadas corretamente de acordo com os valores Unicode.
Compatível com código de byte único: a maioria dos códigos que assumem valores de byte único funciona automaticamente corretamente com caracteres codificados em UTF-8.
Além disso, por qualquer motivo que eu tenha esquecido.