Todo mundo conhece a codificação UTF-8, que há muito tempo domina o espaço da Internet e é usada há muitos anos. Parece que tudo se sabe sobre ela e não há nada de interessante para contar sobre esse assunto. Se você lê recursos populares como a Wikipedia, então realmente não há nada incomum lá, exceto que a versão em inglês menciona brevemente uma história estranha sobre como foi "esboçado em um guardanapo em uma lanchonete".
Na verdade, a invenção dessa codificação não pode ser tão banal, pelo menos porque Ken Thompson, uma pessoa lendária, participou de sua criação. Trabalhou com Dennis Ritchie, foi um dos criadores do UNIX, contribuiu para o desenvolvimento do C (inventou seu antecessor - B) e, posteriormente, trabalhando no Google, participou da criação da linguagem Go.
Antes de você - a tradução de várias cartas em que os desenvolvedores relembram a história da criação da codificação.
Personagens:
ken (at) entrisphere.com - Ken Thompson
Ken Thompson (à esquerda) com Dennis Ritchie
"Rob 'Commander' Pike" - Robert Pike , um programador canadense que trabalhou em UTF-8 com Ken Thompson
mkuhn (at) acm.org - Markus Kuhn , cientista da computação alemão
henry (at) spsystems.net - Henry Spurser , autor de uma das implementações RegExp
Russ Cox < rsc@plan9.bell-labs.com > - Russ Cox , funcionário da Bell Labs que trabalhou no Plano 9
Greger sistema Leijonhufvud < greger@friherr.com> - Um dos membros da equipe do X / Open
Plan 9 - O sistema operacional, que foi o primeiro a usar a codificação UTF-8 para fornecer multilinguismo.
UTF-8 - codificação de caracteres Unicode
Correspondência de 2003
Abaixo está a correspondência entre os criadores da codificação, Robert e Ken, que Robert Pike começou, reclamando que sua contribuição para a criação do UTF-8 foi imerecida e esquecida. Robert pede a um de seus velhos conhecidos que vasculhe os arquivos do servidor de correio e encontre evidências de sua participação. (aprox. por.)
Subject: UTF-8 history From: "Rob 'Commander' Pike" <r (at) google.com> Date: Wed, 30 Apr 2003 22:32:32 -0700 (Thu 06:32 BST) To: mkuhn (at) acm.org, henry (at) spsystems.net Cc: ken (at) entrisphere.com
Olhando para as conversas sobre as origens do UTF-8, vejo a mesma história se repetindo indefinidamente.
Versão errada:
- O UTF-8 foi desenvolvido pela IBM.
- Foi implementado no Plan 9 (um sistema operacional desenvolvido pela Bell Laboratories)
Não é verdade. Eu vi em primeira mão como o UTF-8 foi inventado em um guardanapo uma noite em setembro de 1992 em uma lanchonete de Nova Jersey.
Aconteceu desta forma. Usamos o UTF ISO 10646 original para suportar caracteres de 16 bits no Plano 9, que odiamos, e estávamos prontos para lançar o Plano 9 quando alguns caras me ligaram tarde da noite, acho que eram da IBM. Lembro-me de tê-los conhecido na reunião do comitê X / Open em Austin. Eles queriam que Ken e eu víssemos seu projeto FSS / UTF.
(, ..) . Bell Labs , Plan 9 — , , , . , .Entendemos porque eles queriam mudar o design e decidimos que esta é uma boa oportunidade de usar nossa experiência para desenvolver um novo padrão e fazer com que o pessoal do X / Open o promova. Tínhamos que contar a eles sobre isso, e eles concordaram com a condição de que lidássemos com isso rapidamente.
Unicode , , , , , .
(. .)
Depois fomos comer alguma coisa e, durante o jantar, Ken separou o pacote de batidas e, quando voltamos, eles ligaram para os caras do X / Open e explicaram nossa ideia para eles. Enviamos nosso esboço pelo correio, e eles responderam que era melhor que o deles (mas lembro exatamente que não nos mostraram sua versão) e perguntaram quando poderíamos implementá-lo.
Uma das opções para delimitar caracteres era uma barra, mas isso poderia confundir o sistema de arquivos, poderia interpretá-lo como uma sequência de escape.Parece-me que aconteceu na quarta-feira à noite. Prometemos que lançaríamos o sistema na segunda-feira, quando acho que eles têm alguma reunião importante agendada. Naquela noite, Ken escreveu o código do codificador / decodificador e comecei a lidar com C e as bibliotecas gráficas. No dia seguinte o código estava pronto e começamos a converter os arquivos de texto do sistema. Na sexta-feira, o Plano 9 já estava instalado e funcionando no chamado UTF-8.
(aprox. por.)
E depois a história foi um pouco reescrita.
Por que não usamos apenas o FSS / UTF deles?
Pelo que me lembro, naquela primeira ligação eu cantei para Desiderata meus requisitos de codificação, e FSS / UTF não tinha pelo menos uma coisa - a capacidade de sincronizar um fluxo de bytes retirados do meio do fluxo usando o mínimo os caracteres possíveis para a sincronização (veja acima, sobre como definir os limites dos caracteres.
cantou para eles Desiderat
.
, 1971 , : «Desiderata» , , : «». , « » « ». ( .)
, 1971 , : «Desiderata» , , : «». , « » « ». ( .)
Como não havia solução em lugar nenhum, éramos livres para fazer o que quiséssemos.
Acho que "a história foi inventada pela IBM e implementada no Plano 9" tem suas origens na documentação RFC 2279. Ficamos tão felizes quando o UTF-8 criou raízes que não contamos a história a ninguém.
Nenhum de nós trabalha mais na Bell Labs, mas tenho certeza de que há um arquivo de e-mail que pode corroborar nossa história e posso pedir a alguém que investigue.
Portanto, todo o crédito vai para o pessoal do X / Open e da IBM por tornar isso possível e empurrar a codificação, mas Ken o desenvolveu e eu o ajudei com isso, não importa o que os livros de história digam.
-Roubar
Date: Sat, 07 Jun 2003 18:44:05 -0700 From: "Rob `Commander' Pike" <r@google.com> To: Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> cc: henry@spsystems.net, ken@entrisphere.com, Greger Leijonhufvud <greger@friherr.com> Subject: Re: UTF-8 history
Pedi a Russ Cox para vasculhar os arquivos. Estou anexando sua mensagem. Acho que você vai concordar que isso confirma a história que postei anteriormente. O e-mail que enviamos para o X / Open (acho que Ken editou e divulgou este documento) inclui um novo "desiderato número 6" sobre detecção de limite de caractere.
Não saberemos mais o impacto que a solução original do X / Open teve sobre nós. Embora sejam diferentes, eles têm características comuns. Não me lembro de ter olhado em detalhes, foi há muito tempo (na última carta ele diz que o X / Open não mostrou sua implementação. Aprox. Lane) . Mas me lembro muito bem de como Ken escreveu esboços em um guardanapo e depois desejou que o tivéssemos salvado.
-Roubar
From: Russ Cox <rsc@plan9.bell-labs.com> To: r@google.com Subject: utf digging Date-Sent: Saturday, June 07, 2003 7:46 PM -0400
O arquivo de inicialização do usuário
/sys/src/libc/port/rune.c
foi modificado por divisão pesada em 4 de setembro de 1992. A versão no dump tem um tempo de 19:51:55. No dia seguinte, um comentário foi adicionado a ele, mas, caso contrário, ele não mudou até 14 de novembro de 1996, quando
runelen
foi acelerado ao verificar explicitamente o valor em
rune
vez de usar o valor de retorno
runetochar
. A última alteração foi em 26 de maio de 2001, quando foi adicionado
runenlen
. (Rune é uma estrutura que contém um valor Unicode. Runelen e runetochar são funções que funcionam com este tipo de dados. Aprox. Trans.)
Várias cartas de suas caixas de correio foram geradas por captura de linha utf.
O primeiro é sobre um arquivo
utf.c
que é uma cópia
wctomb
e
mbtowc
(funções de conversão de caracteres. Aprox. Por.) Que manipula a codificação UTF-8 de 32 bits completa de 6 bytes.
runes.
Com lógica de controle de fluxo, parece muito feio. Acho que esse código veio daquele primeiro e-mail.
Em
/usr/ken/utf/xutf
, encontrei uma cópia do que parece ser a fonte desse método de codificação não auto-sincronizado, com o esquema UTF-8 anexado ao final do e-mail (começa com "Nós definimos 7 tipos
byte
").
A versão da carta abaixo, datada de 2 de setembro às 23:44:10, é a primeira. Após várias edições, na manhã do dia 8 de setembro, saiu a segunda versão. Os registros do servidor de e-mail mostram como a segunda versão da carta é enviada e, depois de um tempo, retorna para Ken:
helix: Sep 8 03:22:13: ken: upas/sendmail: remote inet!xopen.co.uk!xojig >From ken Tue Sep 8 03:22:07 EDT 1992 (xojig@xopen.co.uk) 6833 helix: Sep 8 03:22:13: ken: upas/sendmail: delivered rob From ken Tue Sep 8 03:22:07 EDT 1992 6833 helix: Sep 8 03:22:16: ken: upas/sendmail: remote pyxis!andrew From ken Tue Sep 8 03:22:07 EDT 1992 (andrew) 6833 helix: Sep 8 03:22:19: ken: upas/sendmail: remote coma!dmr From ken Tue Sep 8 03:22:07 EDT 1992 (dmr) 6833 helix: Sep 8 03:25:52: ken: upas/sendmail: delivered rob From ken Tue Sep 8 03:24:58 EDT 1992 141 helix: Sep 8 03:36:13: ken: upas/sendmail: delivered ken From ken Tue Sep 8 03:36:12 EDT 1992 6833
Boa sorte.
Arquivos do arquivo de e-mail
Em seguida, está um arquivo com a correspondência do despejo do servidor de e-mail, que Russ Cox anexou ao seu, em resposta ao pedido de Robert para mergulhar na história. Esta é a "primeira versão". (Aproximadamente.)
>From ken Fri Sep 4 03:37:39 EDT 1992
Aqui está nossa sugestão para modificar o FSS-UTF. É quase a mesma coisa que no anterior. Peço desculpas ao autor.
O código foi testado até certo ponto e deve estar em muito bom estado. Reprojetamos o código do Plan 9 para usar essa codificação e vamos lançar a distribuição e selecionar usuários universitários para os testes iniciais.
Formato de transformação do conjunto de caracteres universal seguro do sistema de arquivos (FSS-UTF)
Com o ISO / IEC 10646 (Unicode) sendo estabelecido como um padrão internacional e a expectativa de adoção generalizada deste Universal Coded Character Set (UCS), os sistemas operacionais historicamente baseados em ASCII precisam desenvolver maneiras de representar e lidar com um grande número de caracteres que pode codificar com o novo padrão. UCS tem vários problemas que precisam ser resolvidos em sistemas operacionais estabelecidos historicamente e no ambiente de programação em C.
(O texto abaixo menciona "sistemas operacionais históricos" várias vezes. Aparentemente no contexto de "trabalhar historicamente com codificação ASCII." omitiu este epíteto ou substituiu-o por "existente", etc. aproximadamente pista)
O maior problema é o esquema de codificação usado no UCS. Ou seja, a integração do padrão UCS com linguagens de programação, sistemas operacionais e utilitários existentes. Problemas em linguagens de programação e sistemas operacionais estão sendo tratados em todos os setores, mas ainda enfrentamos o manuseio do UCS por sistemas operacionais e utilitários.
Dentre os problemas associados ao manuseio de UCS em sistemas operacionais, o principal é a apresentação de dados dentro do sistema de arquivos. O conceito subjacente é apoiar os sistemas operacionais existentes nos quais o investimento foi feito e ao mesmo tempo aproveitar o grande número de caracteres fornecidos pelo UCS.
O UCS torna possível codificar texto multilíngue usando um único conjunto de caracteres. Mas UCS e UTF não protegem bytes nulos (o fim de linhas em alguns idiomas. Aprox. Por.) E / ou uma barra em ASCII /, o que torna a codificação incompatível com Unix. A proposta a seguir fornece um formato de transformação UCS compatível com Unix, para que os sistemas Unix possam suportar texto multilíngue em uma única codificação.
Este formato de conversão de codificação destina-se à codificação de arquivos como uma etapa intermediária para o suporte UCS completo. No entanto, uma vez que quase todas as implementações Unis enfrentam os mesmos problemas de suporte UCS, esta proposta se destina a fornecer compatibilidade de codificação geral neste estágio.
Finalidade / Objetivo
Com base na suposição, obtemos que, se quase todos os problemas de processamento e armazenamento de UCS em sistemas de arquivos do SO forem conhecidos, precisaremos usar esse formato de conversão de UCS que funcionará sem violar a estrutura do sistema operacional. O objetivo é que o processo de conversão do formato possa ser usado para codificar o arquivo.
Critérios para formato de conversão
A seguir estão as diretrizes a serem seguidas ao definir o formato de conversão UCS:
- Compatibilidade com sistemas de arquivos existentes.
É proibido usar um byte nulo e uma barra como parte do nome do arquivo. - .
ASCII. UCS, ASCII, ASCII. - UCS .
- .
- , , .
- , (. ..).
FSS-UTF
O formato de transformação UCS proposto codifica valores UCS em um intervalo
[0,0x7fffffff]
usando bytes múltiplos por caractere e comprimentos de 1, 2, 3, 4, 5 e 6 bytes. Em todos os casos de codificação com mais de um byte, o byte inicial determina o número de bytes usados, com o bit mais significativo definido em cada byte. Cada byte que não começa com 10XXXXXX é o início de uma sequência de caracteres UCS.
Uma maneira fácil de lembrar o formato: o número de uns altos no primeiro byte significa o número de bytes em um caractere multibyte.
Bits Hex Min Hex Max Byte Sequence in Binary 1 7 00000000 0000007f 0vvvvvvv 2 11 00000080 000007FF 110vvvvv 10vvvvvv 3 16 00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv 4 21 00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv 5 26 00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 6 31 04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
O valor do caractere UCD codificado por multibyte é uma concatenação de v-bits. Se vários métodos de codificação forem possíveis, por exemplo UCS 0, o mais curto é considerado aceitável.
Abaixo estão exemplos de implementações de funções C padrão
wcstombs()
e
mbstowcs()
que demonstram algoritmos para conversão de UCS para formato de conversão e conversão de formato de conversão para UCS. Exemplos de implementações incluem verificação de erros, alguns dos quais podem não ser necessários para consistência:
typedef
struct
{
int cmask;
int cval;
int shift;
long lmask;
long lval;
} Tab;
static
Tab tab[] =
{
0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */
0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */
0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 byte sequence */
0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */
0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */
0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */
0, /* end of table */
};
int
mbtowc(wchar_t *p, char *s, size_t n)
{
long l;
int c0, c, nc;
Tab *t;
if(s == 0)
return 0;
nc = 0;
if(n <= nc)
return -1;
c0 = *s & 0xff;
l = c0;
for(t=tab; t->cmask; t++) {
nc++;
if((c0 & t->cmask) == t->cval) {
l &= t->lmask;
if(l < t->lval)
return -1;
*p = l;
return nc;
}
if(n <= nc)
return -1;
s++;
c = (*s ^ 0x80) & 0xFF;
if(c & 0xC0)
return -1;
l = (l<<6) | c;
}
return -1;
}
int
wctomb(char *s, wchar_t wc)
{
long l;
int c, nc;
Tab *t;
if(s == 0)
return 0;
l = wc;
nc = 0;
for(t=tab; t->cmask; t++) {
nc++;
if(l <= t->lmask) {
c = t->shift;
*s = t->cval | (l>>c);
while(c > 0) {
c -= 6;
s++;
*s = 0x80 | ((l>>c) & 0x3F);
}
return nc;
}
}
return -1;
}
>From ken Tue Sep 8 03:24:58 EDT 1992
Mandei pelo correio, mas a carta entrou em um buraco negro, então não recebi minha cópia. Este endereço de internet deve estar em coma.
Segunda versão da carta, com revisões
Em seguida, uma cópia da carta é anexada, que é descrita acima como: "Depois de várias correções, na manhã do dia 8 de setembro, a segunda versão saiu." A parte repetitiva está escondida sob o spoiler. (tradução aprox.)
>From ken Tue Sep 8 03:42:43 EDT 1992
Finalmente consegui minha cópia.
--- /usr/ken/utf/xutf from dump of Sep 2 1992 ---
Texto oculto
ISO/IEC 10646 (Unicode) (UCS), , ASCII, , . UCS , C.
, UCS. UCS , . , UCS .
, UCS , . , , , , UCS.
UCS . UCS UTF ( . . .) / ASCII /, Unix. UCS, Unix, , , Unix- .
, UCS. , Unis UCS, .
, UCS , UCS, . , .
, , UCS:
UCS UCS
1, 2, 3, 4, 5, 6 . , . , 10XXXXXX, UCS.
: .
UCD — v-. , UCS 0, .
C
, UCS UCS. , :
File System Safe Universal Character Set Transformation Format (FSS-UTF)
ISO/IEC 10646 (Unicode) (UCS), , ASCII, , . UCS , C.
, UCS. UCS , . , UCS .
, UCS , . , , , , UCS.
UCS . UCS UTF ( . . .) / ASCII /, Unix. UCS, Unix, , , Unix- .
, UCS. , Unis UCS, .
/
, UCS , UCS, . , .
, , UCS:
- .
. - .
ASCII. UCS, ASCII, ASCII. - UCS .
- .
- , , .
- , (. ..).
FSS-UTF
UCS UCS
[0,0x7fffffff]
1, 2, 3, 4, 5, 6 . , . , 10XXXXXX, UCS.
: .
Bits Hex Min Hex Max Byte Sequence in Binary 1 7 00000000 0000007f 0vvvvvvv 2 11 00000080 000007FF 110vvvvv 10vvvvvv 3 16 00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv 4 21 00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv 5 26 00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 6 31 04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
UCD — v-. , UCS 0, .
C
wcstombs()
mbstowcs()
, UCS UCS. , :
typedef
struct
{
int cmask;
int cval;
int shift;
long lmask;
long lval;
} Tab;
static
Tab tab[] =
{
0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */
0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */
0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 byte sequence */
0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */
0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */
0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */
0, /* end of table */
};
int
mbtowc(wchar_t *p, char *s, size_t n)
{
long l;
int c0, c, nc;
Tab *t;
if(s == 0)
return 0;
nc = 0;
if(n <= nc)
return -1;
c0 = *s & 0xff;
l = c0;
for(t=tab; t->cmask; t++) {
nc++;
if((c0 & t->cmask) == t->cval) {
l &= t->lmask;
if(l < t->lval)
return -1;
*p = l;
return nc;
}
if(n <= nc)
return -1;
s++;
c = (*s ^ 0x80) & 0xFF;
if(c & 0xC0)
return -1;
l = (l<<6) | c;
}
return -1;
}
int
wctomb(char *s, wchar_t wc)
{
long l;
int c, nc;
Tab *t;
if(s == 0)
return 0;
l = wc;
nc = 0;
for(t=tab; t->cmask; t++) {
nc++;
if(l <= t->lmask) {
c = t->shift;
*s = t->cval | (l>>c);
while(c > 0) {
c -= 6;
s++;
*s = 0x80 | ((l>>c) & 0x3F);
}
return nc;
}
}
return -1;
}
int mbtowc(wchar_t *p, const char *s, size_t n) { unsigned char *uc; /* so that all bytes are nonnegative */ if ((uc = (unsigned char *)s) == 0) return 0; /* no shift states */ if (n == 0) return -1; if ((*p = uc[0]) < 0x80) return uc[0] != '\0'; /* return 0 for '\0', else 1 */ if (uc[0] < 0xc0) { if (n < 2) return -1; if (uc[1] < 0x80) goto bad; *p &= 0x3f; *p <<= 7; *p |= uc[1] & 0x7f; *p += OFF1; return 2; } if (uc[0] < 0xe0) { if (n < 3) return -1; if (uc[1] < 0x80 || uc[2] < 0x80) goto bad; *p &= 0x1f; *p <<= 14; *p |= (uc[1] & 0x7f) << 7; *p |= uc[2] & 0x7f; *p += OFF2; return 3; } if (uc[0] < 0xf0) { if (n < 4) return -1; if (uc[1] < 0x80 || uc[2] < 0x80 || uc[3] < 0x80) goto bad; *p &= 0x0f; *p <<= 21; *p |= (uc[1] & 0x7f) << 14; *p |= (uc[2] & 0x7f) << 7; *p |= uc[3] & 0x7f; *p += OFF3; return 4; } if (uc[0] < 0xf8) { if (n < 5) return -1; if (uc[1] < 0x80 || uc[2] < 0x80 || uc[3] < 0x80 || uc[4] < 0x80) goto bad; *p &= 0x07; *p <<= 28; *p |= (uc[1] & 0x7f) << 21; *p |= (uc[2] & 0x7f) << 14; *p |= (uc[3] & 0x7f) << 7; *p |= uc[4] & 0x7f; if (((*p += OFF4) & ~(wchar_t)0x7fffffff) == 0) return 5; } bad:; errno = EILSEQ; return -1; }
Definimos 7 tipos de bytes:
T0 0xxxxxxx 7 free bits Tx 10xxxxxx 6 free bits T1 110xxxxx 5 free bits T2 1110xxxx 4 free bits T3 11110xxx 3 free bits T4 111110xx 2 free bits T5 111111xx 2 free bits
A codificação é parecida com esta:
>From hex Thru hex Sequence Bits 00000000 0000007f T0 7 00000080 000007FF T1 Tx 11 00000800 0000FFFF T2 Tx Tx 16 00010000 001FFFFF T3 Tx Tx Tx 21 00200000 03FFFFFF T4 Tx Tx Tx Tx 26 04000000 FFFFFFFF T5 Tx Tx Tx Tx Tx 32
Algumas notas:
- Dois bytes podem codificar potência de 2 ^ 11 caracteres, mas apenas 2 ^ 11-2 ^ 7 serão usados. Códigos no intervalo 0-7F serão considerados inválidos. Acho que isso é melhor do que adicionar um monte de constantes "mágicas" sem nenhum benefício real. Essa observação se aplica a todas as sequências mais longas.
- Seqüências de 4, 5 e 6 bytes existem apenas por motivos políticos. Eu preferiria removê-los.
- A sequência de 6 bytes abrange 32 bits, a proposta FSS-UTF abrange apenas 31.
- Todas as sequências são sincronizadas com qualquer byte que não seja
Tx.
***
Essa curta correspondência colocou tudo em seu lugar. Embora aquele “guardanapo lendário” não tenha sobrevivido, havia trechos suficientes do arquivo do servidor de e-mail para que a comunidade reconhecesse seus méritos. A Wikipedia acrescentou os nomes de Ken e Robert e um fato engraçado sobre um guardanapo em uma lanchonete, e na Internet essa história é divulgada e discutida "como está", na forma de um texto simples contendo várias letras e parte de um lixo do servidor de e-mail.
O sistema operacional Plan 9 foi esquecido há muito tempo, ninguém se lembra para que foi escrito e por que era o “número nove”, e o UTF-8, quase trinta anos depois, ainda é relevante e não vai se aposentar.
Parece que isso é apenas uma codificação, mas mesmo uma história simples pode ser divertida se você se aprofundar um pouco. No início do desenvolvimento da tecnologia, era impossível prever o que iria disparar e entrar para a história, e o que seria esquecido.
Fonte de arquivos