SlideShare ist ein Scribd-Unternehmen logo
1 von 129
Minicurso de
    Encoding
André Willik Valenti (Daitan Group)
  Andrei Tognolo (Dextra Sistemas)

    The Developer’s Conference
           Goiânia 2012
Roteiro
▒ Parte 1
  ▒ O que é e por que existe
▒ Parte 2
  ▒ Como funciona
  ▒ Por que dá errado
▒ Parte 3
  ▒ Como faz pra dar certo
Parte 1

   O que é e por que existe
Quem é o encoding?
▒ O encoding é o culpado por:
 ▒ Programação
    Programação
    Programa 褯

 ▒ José Luís Assunção Júnior
    José Luís Assunção Júnior
    Jos 題 uAssun 褯 Jr
Quem é o encoding?
▒ Mais especificamente:
 ▒ Character encoding


▒ Também conhecido como:
 ▒ Codificação de caracteres
 ▒ Charset
Por que encoding?
▒ Se dá tanto problema...
 ▒ Por que a gente usa?
Por que encoding?
▒ Computador é uma máquina de armazenar
  e processar informação

▒ Informação é um conceito abstrato

▒ Computador não entende conceitos
  abstratos

▒ Computador entende de bits, bytes,
  números
Por que encoding?
▒ Exemplo: imagens
Por que encoding?
▒ Como a gente representa uma
  imagem num computador?
 ▒ Imagem          pixels
 ▒ pixels          números
 ▒ números         bytes/bits
 ▒ bytes/bits      algum formato
                     (png, jpeg, gif etc.)
PNG     JPEG

1000110   0011000
0010010   1011...
0100...
(440KB)   (62KB)
Por que encoding?
▒ A imagem é uma informação

▒ Bytes / bits são dados

▒ Dados são concretos, informação é
  abstrata

▒ Informação = dados + forma de
  interpretá­los
Informação
        =
  dados + forma
de interpretá-los
Encoding
▒ “Forma de interpretá­los”
 ▒ Isso é o encoding!
Encoding
▒ Exemplos de encoding:
 ▒ PNG
 ▒ JPEG
 ▒ MPEG
 ▒ MP3
 ▒ PDF
Character encoding
▒ O que é então um character
  encoding?
 ▒ É só uma determinada maneira de se
   representar caracteres usando bytes
Encoding
▒ Por que a gente usa encoding,
  então?
 ▒ Porque não tem como não usar!
Parte 2

     Como (não) funciona

     Por que dá errado
História
▒ Década de 60
  ▒ Mais de 60 maneiras diferentes de
    representar caracteres

  ▒ Cada fabricante implementava do seu
    jeito


▒ Bob Bemer:
  ▒ “Vamos uniformizar esse negócio...”
ASCII
▒ American Standard Code for
  Information Interchange

▒ 7 bits

▒ 128 diferentes caracteres
ASCII
▒ ASCII é, ao mesmo tempo:
 ▒ Um encoding
 ▒ Uma tabela de caracteres
ASCII
▒ Exemplos:

 Caractere    Decimal   Hexa   Binário
     5          53      0x35   0110101
     A          65      0x41   1000001
     }          125     0x7D   1111101
ASCII
▒ 128 caracteres (nenhum
  acentuado)

▒ Intervalo válido
 ▒ Em decimal:           0 – 127
 ▒ Em binário:     0000000 – 1111111
 ▒ Em hexadecimal:    0x00 – 0x7F
ASCII
▒ 7 bits?
  ▒ Muitas máquinas usavam/usam o padrão
    de 8 bits para 1 byte


▒ E esse bit sobrando aí?
  ▒ “Já sei... Vamos usar pra codificar
    caracteres locais de cada país!”
ASCII estendido
▒ 8 bits: 256 caracteres

▒ Intervalo válido:
 ▒    0 – 255    (em decimal)
 ▒ 0x00 – 0xFF   (em hexadecimal)
ASCII estendido
▒ 0x00 – 0x7F: igual ASCII
 ▒a   b   C   D   3   5   9   %   &   /

▒ 0x80 – 0xFF: caracteres locais
 ▒ç   Á   ã   é   ü   ¿
ASCII original
0x00 0x01 0x02 ... 0x7F



0x80 0x81 0x82 ... 0xFF

     ASCII estendido
ASCII estendido
▒ Problema:
  ▒ Não existe “o encoding ASCII
    estendido”

  ▒ Existem UM MONTE de encodings que
    são “ASCII estendido”
ASCIIs estendidos
▒ Codepages
   ▒   437   —   The original IBM PC code page
   ▒   720   —   Arabic
   ▒   737   —   Greek
   ▒   775   —   Estonian, Lithuanian and Latvian
   ▒   850   —   "Multilingual (Latin­1)"
   ▒   852   —   "Slavic (Latin­2)"
   ▒   855   —   Cyrillic
   ▒   857   —   Turkish
   ▒   858   —   "Multilingual" with euro symbol
   ▒   860   —   Portuguese
   ▒   863   —   French (Quebec French)
   ▒   865   —   Danish/Norwegian
   ▒   866   —   Cyrillic
   ▒   869   —   Greek
   ▒   874   —   Thai
   ▒   ...
ASCIIs estendidos
▒ ISO­8859­1
  ▒ Também conhecido como LATIN­1


▒ É um ASCII estendido:
  ▒ 256 caracteres
  ▒ Compatível com ASCII


▒ Usado até hoje
ASCIIs estendidos
▒ Maravilha!

▒ Milhares de encodings
  diferentes

▒ Agora todo mundo vai conseguir
  representar seus caracteres!
ASCIIs estendidos
▒ E a interoperabilidade?
 ▒ Internet, internacionalização?
 ▒ Troca de textos, documentos?
 ▒ Nomes de arquivos?
Júnior.txt
Olá, meu nome é
   José Luís de
Assunção Júnior,
 sou irmão da Sí
lvia, da Cláudia e
      do João.
ASCII
▒ No fim das contas, ficou assim:
ASCII
▒ Na teoria:

  ▒ ASCII original:      0x00 – 0x7F

  ▒ Extensão do ASCII:   0x80 – 0xFF
ASCII
▒ Na prática:

  ▒ ASCII original:      Blz!

  ▒ Extensão do ASCII:   Esquece!
Exemplo
▒ Você, aqui no Brasil, usando o DOS,
  gostaria de dar o seu olá

▒ Você escreve:
  ▒ Ola!


▒ No Brasil, a gente usava o encoding
  chamado “Codepage 850” (ou CP850)
Exemplo
▒ Essa sua sequência de 4 caracteres
  (“Ola!”) é uma informação

▒ Informação só existe na cabeça dos
  seres humanos

▒ Computador não conhece informação.
  Computador conhece dados.
Exemplo
▒ Para um computador, não existe:
  ▒ Ola!


▒ O que existe são estes 4 bytes:
  ▒ 0x4F   0x6C   0x61   0x21

▒ Resultado:
Exemplo
▒ Blz !
 ▒ O        l      a       !
 ▒ ↑        ↑      ↑       ↑
 ▒ 0x4F    0x6C   0x61   0x21
Exemplo
▒ Mensagem foi codificada em CP850
  ▒ Todos os caracteres eram ASCII
    também

▒ Na prática:
  ▒ A mensagem está em ASCII
  ▒ Todo computador entende ASCII
  ▒ Então blz!
Exemplo
▒ E se a gente escrever...
  ▒ Olá!


▒ Resultado:
Exemplo
▒ Blz !
 ▒ O        l      á        !
 ▒ ↑        ↑      ↑        ↑
 ▒ 0x4F    0x6C   0xE1    0x21

▒ (Usando codepage 850)
Exemplo
▒ Até você tentar ler isso num
  computador russo e...
Exemplo
▒ Não blz 
 ▒ O       l      р       !
 ▒ ↑       ↑      ↑       ↑
 ▒ 0x4F   0x6C   0xE1   0x21
Exemplo
▒ Encoding russo disse:
 ▒ 0xE1 é um р


▒ Encoding brasileiro tinha dito:
 ▒ 0xE1 é um á


▒ Quem está certo?
Encodings
▒ Não existe uma forma única de
  representar o caractere á

▒ A sequência de bytes é ambígua:
 ▒ 0x4F   0x6C   0xE1    0x21
Encodings
▒ E se tivesse um jeito...
 ▒ ...de informar ao computador
   russo que a gente usou o CP850?


▒ Segure essa ideia!
Encodings
▒ O mundo inteiro...
 ▒ ...cada um com o seu encoding?


▒ É óbvio que não daria certo
 ▒ Teria que uniformizar de verdade!
Encodings
▒ E se houvesse...
 ▒ Um código...
 ▒ Um código único...
 ▒ Um único código...
 ▒ Um...
UNICODE!!
Unicode
▒ O que é Unicode?
The Unicode 5.0 Standard
▒ 1472 páginas
▒ É grande 
O que é Unicode?
▒ Unicode é:
  ▒ Um padrão gigantesco
  ▒ Subdividido em muitas partes


▒ Unicode, ao contrário do ASCII:
  ▒ Não É uma tabela de caracteres
  ▒ Não É um encoding
O que é Unicode?
▒ Unicode TEM uma tabela de
  caracteres:
 ▒ UCS: Universal Character Set


▒ Unicode TEM diversos encodings
 ▒ UTF­8, UTF­16, UTF­32 (Unicode
   Transformation Format)
UCS
▒ Tabela gigante de caracteres
  (~100.000)

▒ Cada caractere possui um código,
  chamado code point
 ▒ Code point é representado por U+ e
   um número em hexadecimal
UCS
▒ Exemplos:
  ▒ U+0058:    X
  ▒ U+00E3:    ã
  ▒ U+2603:    ☃
  ▒ U+10123:
UCS
▒ Intervalo U+0000 – U+007F
 ▒ Mesmos caracteres da tabela ASCII
UCS
▒ Caracteres na tabela são
  abstratos (são informação)

▒ Para concretizá­los, é
  necessário um encoding
Encodings Unicode
▒ Maneiras de transformar
  caracteres abstratos em
  concretos

▒ Três principais: UTF­8, UTF­16,
  UTF­32
UTF­32
▒ Exemplos:
  ▒ U+0058:    0x00   0x00   0x00   0x58
  ▒ U+00E3:    0x00   0x00   0x00   0xE3
  ▒ U+2603:    0x00   0x00   0x26   0x03
  ▒ U+10123:   0x00   0x01   0x01   0x23
UTF­16
▒ Exemplos:
  ▒ U+0058:                  0x00   0x58
  ▒ U+00E3:                  0x00   0xE3
  ▒ U+2603:                  0x26   0x03
  ▒ U+10123:   0xD8   0x00   0xDD   0x23
UTF­8
▒ Exemplos:
  ▒ U+0058:                         0x58
  ▒ U+00E3:                  0xC3   0xA3
  ▒ U+2603:           0xE2   0x98   0x83
  ▒ U+10123:   0xF0   0x90   0x84   0xA3
UTF­8
▒ Compatível com ASCII entre
  U+0000 e U+007F

▒ A partir de U+0080, usa mais de
  1 byte

▒ Para os caracteres da língua
  portuguesa, usa 1 ou 2 bytes
UCS e UTF
▒ O que eu preciso saber disso
  tudo?

▒ Apenas o seguinte:
UCS e UTF
▒ Tabela de caracteres ≠ encoding

▒ Diferentes de representação
  ▒ Mais comum: UTF­8


▒ UTF­8
  ▒ Número variável de bytes por
    caractere (em geral, 1 ou 2)
No mundo real de hoje
▒ Encodings mais usados nos
  sistemas que rodam no Brasil:
 ▒ UTF­8
 ▒ LATIN­1
No mundo real de hoje
▒ U+0000 – U+007F
 ▒ Mesmos caracteres da tabela ASCII


▒ U+0000 – U+00FF
 ▒ Mesmos caracteres da tabela LATIN­1
LATIN­1
▒ Serve para representar qualquer
  caractere Unicode?
LATIN­1
▒ Não!
  ▒ Usa exatamente 1 byte por caractere
  ▒ 1 byte não seria suficiente
LATIN­1 e UTF­8
▒ Exemplos

              Bytes usando Bytes usando
  Caractere
                  UTF-8      LATIN-1
      X           0x58         0x58

      Ã        0xC3 0xA3         0xE3

     ☃        0xE2 0x98 0x83   Não existe
LATIN­1 e UTF­8
▒ Blz!
  ▒ Então vamos representar a string
    “José”


▒ String: é uma informação ou um
  dado?
LATIN­1 e UTF­8
▒ Lembra o Barakis Obamis com o
  PNG e o JPEG?
PNG     JPEG

1000110   0011000
0010010   1011...
0100...
(440KB)   (62KB)
LATIN­1 e UTF­8
▒ O José com o LATIN­1 e UTF­8 é a
  mesma coisa!
LATIN­1
            José
                            UTF­8
0x4A 0x6F 0x73 0xE9
(4 bytes)

            0x4A 0x6F 0x73 0xC3 0xA9
                           (5 bytes)
LATIN­1 e UTF­8
▒ Blz. Mas por que eu escrevo
  “José” num lugar e depois
  aparece “José” no outro?
LATIN­1 e UTF­8
▒ Codificando “José” em UTF­8:
 ▒ J       o       s         é
 ▒ ↑       ↑       ↑         ↑
 ▒ 0x4A   0x6F    0x73   0xC3 0xA9
LATIN­1 e UTF­8
▒ Aí você envia esses bytes

   0x4A   0x6F   0x73   0xC3   0xA9

 para alguém
LATIN­1 e UTF­8
▒ Se a pessoa ler em UTF­8, blz!

 ▒ 0x4A   0x6F   0x73   0xC3        0xA9
    ↓      ↓       ↓            ↓
    J      o       s           é
LATIN­1 e UTF­8
▒ Mas e se ela ler em LATIN­1?

 ▒ 0x4A   0x6F   0x73   0xC3   0xA9
    ↓      ↓       ↓      ↓       ↓
    J      o       s     Ã       ©
LATIN­1 e UTF­8
▒ O texto foi:
  ▒ Escrito em UTF­8
  ▒ Enviado a outro sistema


▒ Como o outro sistema vai
  adivinhar que o texto está em
  UTF­8?
Unicode
▒ Mas então não é só todo mundo
  codificar seus caracteres usando
  Unicode e vai dar tudo certo!?
Unicode
▒ Calma ...
 ▒ Em 1º lugar, Unicode não é um
   encoding. Não existe “codificar
   caracteres usando Unicode”.

 ▒ Em 2º lugar, não temos controle
   sobre todos os sistemas do mundo.
   Não podemos fazer com que todos usem
   o mesmo encoding (nem deveríamos).
Parte 3

    Como faz pra dar certo
Informação
        =
  dados + forma
de interpretá-los
Informação      String

      =             =

    Dados         Bytes

      +             +
   Forma de
                 Encoding
interpretá­los
String..
       =..
bytes + encoding
Não existe string
  sem encoding!
Não existe relação
 byte  caractere
   sem encoding!
Como faz pra dar certo
▒ 2 dicas para evitar problemas de
  encoding:
Como faz pra dar certo
▒ 1) Use sequências de escape
  sempre que possível

▒ Para escrever “Programação”:
 ▒ Em Java:
   ▒ "Programau00e7u00e3o"
 ▒ Em HTML:
   ▒ <p>Programa&ccedil;&atilde;o</p>
Como faz pra dar certo
▒ 2) Faça conversões só quando
  realmente for necessário

▒ Ao fazer qualquer conversão, SEMPRE
  especifique o encoding
Como faz pra dar certo
▒ Vetor de bytes não é string!
▒ String não é vetor de bytes!

▒ O que é válido é:
  ▒ Decompor string em vetor de bytes +
    encoding
  ▒ Compor string a partir de um vetor de
    bytes + um encoding
Como faz pra dar certo
▒ Quando é que realmente precisamos
  fazer conversões?
  ▒ Quando fazemos entrada/saída
Como faz pra dar certo
▒ Exemplos:
Como faz pra dar certo
▒ Você vai enviar texto em uma
  requisição HTTP?
 ▒ Converta a string para bytes usando
   algum encoding

 ▒ Avise ao servidor que você vai usar
   esse encoding

 ▒ Envie os bytes
Como faz pra dar certo
▒ Errado:
  ▒ Content-Type: text/plain


▒ Certo:
  ▒ Content-Type: text/plain; charset=utf-8

  ▒ Content-Type: text/plain; charset=iso-8859-1
Como faz pra dar certo
▒ Vai receber um XML?
 ▒ Receba o conteúdo (bytes)
 ▒ Repasse diretamente os bytes para a
   sua biblioteca de processamento de
   XML
Como faz pra dar certo
▒ Não preciso me preocupar com
  encoding ao processar XML?
 ▒ Em geral, não!
 ▒ XML informa seu encoding dentro do
   próprio documento
   ▒ <?xml version="1.0" encoding="utf­8"?>
   ▒ (deveria, pelo menos!)
Como faz pra dar certo
▒ “Tem que passar o encoding, tem
  que passar o encoding...”

▒ E se eu não passar o encoding?
  Não funciona?
Como faz pra dar certo
▒ Funciona!
  ▒ ...às vezes!


▒ O que acontece se eu não
  especificar encoding?
  ▒ Nenhum encoding será usado!
  ▒ Certo!?
!!!!!!!!!!!
!!ERRADO!!
!!!!!!!!!!!
Como faz pra dar certo
▒ Se você não especificar
  encoding, será usado o encoding
  padrão da plataforma

▒ E isso é   ERRADO!
  ▒ É um perigo!
  ▒ É um absurdo!
Como faz pra dar certo
▒ Plataformas MUDAM!
▒ Configurações de ambiente MUDAM!
▒ Encoding padrão MUDA!
Java: jeito errado
▒ byte[] meusBytes =
     string.getBytes();

 (...)

 String minhaString =
    new String(bytes);

▒ Está dependente de plataforma!
Java: jeito certo
▒ byte[] meusBytes =
     string.getBytes("UTF­8");

 (...)

 String minhaString =
    new String(bytes, "UTF­8");

▒ Agora, sim, independe de plataforma!
Java: jeito certo
▒ Não precisa ser UTF­8, pode ser
  qualquer outro
Java: jeito certo
▒ byte[] meusBytes =
    string.getBytes("LATIN1");

 (...)

 String minhaString =
   new String(bytes, "LATIN1");
Java: jeito certo
▒ byte[] meusBytes =
    string.getBytes("UTF­16");

 (...)

 String minhaString =
   new String(bytes, "UTF­16");
Java: jeito certo
▒ byte[] meusBytes =
    string.getBytes("UTF­32");

 (...)

 String minhaString =
   new String(bytes, "UTF­32");
Demonstração...
Conclusões
▒ Problemas de encoding acontecem
  nas melhores famílias
Conclusões
▒ Causas são sempre as mesmas:
  ▒ String sendo lida e/ou escrita usando o
    encoding errado

  ▒ Uso indevido do encoding padrão da
    plataforma


▒ Causa raiz de todo o problema:
  ▒ Ambiguidade: mais de uma maneira de
    representar a mesma informação
Conclusões
▒ A solução é:
  ▒ Lembrar: não existe string sem
    encoding!

  ▒ Informar o encoding toda vez que
    fizer entrada/saída
Referências
▒ The Absolute Minimum Every
  Software Developer Absolutely,
  Positively Must Know About
  Unicode and Character Sets (No
  Excuses!)
 ▒ http://www.joelonsoftware.com/articles/U
Referências
▒ Lista de caracteres Unicode e
  suas diferentes representações
 ▒ http://www.fileformat.info/info/unicode/


▒ The Unicode Consortium
 ▒ http://unicode.org/
Referências
▒ ASCII
  ▒ http://en.wikipedia.org/wiki/ASCII


▒ Unicode
  ▒ http://en.wikipedia.org/wiki/Unicode


▒ UTF­8
  ▒ http://en.wikipedia.org/wiki/UTF-8
Adendo
▒ “José” em UTF­8 gasta 8 bytes?
 ▒ http://en.wikipedia.org/wiki/Byte_order_


▒ Encoding padrão da plataforma?
 ▒ Em geral, é errado usar
 ▒ Em raras situações, é correto. Ex:
   upload de arquivo no cliente.
Contatos
▒ Andru00e9 Willik Valenti
 ▒ awvalenti@gmail.com
 ▒ @awvFi


▒ Andrei de Oliveira Tognolo
 ▒ andreitognolo@gmail.com
 ▒ /andreitognolo

Weitere ähnliche Inhalte

Ähnlich wie Minicurso de Encoding - resolvendo problemas com acentuação (#TDC2012 Goiânia)

Ähnlich wie Minicurso de Encoding - resolvendo problemas com acentuação (#TDC2012 Goiânia) (6)

Unidades de Medidas Computacionais
Unidades de Medidas ComputacionaisUnidades de Medidas Computacionais
Unidades de Medidas Computacionais
 
Unicode: Os segredos da Codificação de Caracteres
Unicode: Os segredos da Codificação de CaracteresUnicode: Os segredos da Codificação de Caracteres
Unicode: Os segredos da Codificação de Caracteres
 
Bits & Bytes
Bits & BytesBits & Bytes
Bits & Bytes
 
Programação para Atari 2600
Programação para Atari 2600Programação para Atari 2600
Programação para Atari 2600
 
Cool 3 assembly para linux
Cool 3   assembly para linuxCool 3   assembly para linux
Cool 3 assembly para linux
 
Códigos BCD, Gray e ASCII
Códigos  BCD, Gray e ASCIICódigos  BCD, Gray e ASCII
Códigos BCD, Gray e ASCII
 

Minicurso de Encoding - resolvendo problemas com acentuação (#TDC2012 Goiânia)

  • 1. Minicurso de Encoding André Willik Valenti (Daitan Group) Andrei Tognolo (Dextra Sistemas) The Developer’s Conference Goiânia 2012
  • 2. Roteiro ▒ Parte 1 ▒ O que é e por que existe ▒ Parte 2 ▒ Como funciona ▒ Por que dá errado ▒ Parte 3 ▒ Como faz pra dar certo
  • 3. Parte 1 O que é e por que existe
  • 4. Quem é o encoding? ▒ O encoding é o culpado por: ▒ Programação  Programação  Programa 褯 ▒ José Luís Assunção Júnior  José Luís Assunção Júnior  Jos 題 uAssun 褯 Jr
  • 5. Quem é o encoding? ▒ Mais especificamente: ▒ Character encoding ▒ Também conhecido como: ▒ Codificação de caracteres ▒ Charset
  • 6. Por que encoding? ▒ Se dá tanto problema... ▒ Por que a gente usa?
  • 7. Por que encoding? ▒ Computador é uma máquina de armazenar e processar informação ▒ Informação é um conceito abstrato ▒ Computador não entende conceitos abstratos ▒ Computador entende de bits, bytes, números
  • 8. Por que encoding? ▒ Exemplo: imagens
  • 9.
  • 10.
  • 11.
  • 12. Por que encoding? ▒ Como a gente representa uma imagem num computador? ▒ Imagem  pixels ▒ pixels  números ▒ números  bytes/bits ▒ bytes/bits  algum formato (png, jpeg, gif etc.)
  • 13. PNG JPEG 1000110 0011000 0010010 1011... 0100... (440KB) (62KB)
  • 14. Por que encoding? ▒ A imagem é uma informação ▒ Bytes / bits são dados ▒ Dados são concretos, informação é abstrata ▒ Informação = dados + forma de interpretá­los
  • 15. Informação = dados + forma de interpretá-los
  • 16. Encoding ▒ “Forma de interpretá­los” ▒ Isso é o encoding!
  • 17. Encoding ▒ Exemplos de encoding: ▒ PNG ▒ JPEG ▒ MPEG ▒ MP3 ▒ PDF
  • 18. Character encoding ▒ O que é então um character encoding? ▒ É só uma determinada maneira de se representar caracteres usando bytes
  • 19. Encoding ▒ Por que a gente usa encoding, então? ▒ Porque não tem como não usar!
  • 20. Parte 2 Como (não) funciona Por que dá errado
  • 21. História ▒ Década de 60 ▒ Mais de 60 maneiras diferentes de representar caracteres ▒ Cada fabricante implementava do seu jeito ▒ Bob Bemer: ▒ “Vamos uniformizar esse negócio...”
  • 22.
  • 23. ASCII ▒ American Standard Code for Information Interchange ▒ 7 bits ▒ 128 diferentes caracteres
  • 24. ASCII ▒ ASCII é, ao mesmo tempo: ▒ Um encoding ▒ Uma tabela de caracteres
  • 25. ASCII ▒ Exemplos: Caractere Decimal Hexa Binário 5 53 0x35 0110101 A 65 0x41 1000001 } 125 0x7D 1111101
  • 26. ASCII ▒ 128 caracteres (nenhum acentuado) ▒ Intervalo válido ▒ Em decimal: 0 – 127 ▒ Em binário: 0000000 – 1111111 ▒ Em hexadecimal: 0x00 – 0x7F
  • 27. ASCII ▒ 7 bits? ▒ Muitas máquinas usavam/usam o padrão de 8 bits para 1 byte ▒ E esse bit sobrando aí? ▒ “Já sei... Vamos usar pra codificar caracteres locais de cada país!”
  • 28. ASCII estendido ▒ 8 bits: 256 caracteres ▒ Intervalo válido: ▒ 0 – 255 (em decimal) ▒ 0x00 – 0xFF (em hexadecimal)
  • 29. ASCII estendido ▒ 0x00 – 0x7F: igual ASCII ▒a b C D 3 5 9 % & / ▒ 0x80 – 0xFF: caracteres locais ▒ç Á ã é ü ¿
  • 30. ASCII original 0x00 0x01 0x02 ... 0x7F 0x80 0x81 0x82 ... 0xFF ASCII estendido
  • 31. ASCII estendido ▒ Problema: ▒ Não existe “o encoding ASCII estendido” ▒ Existem UM MONTE de encodings que são “ASCII estendido”
  • 32. ASCIIs estendidos ▒ Codepages ▒ 437 — The original IBM PC code page ▒ 720 — Arabic ▒ 737 — Greek ▒ 775 — Estonian, Lithuanian and Latvian ▒ 850 — "Multilingual (Latin­1)" ▒ 852 — "Slavic (Latin­2)" ▒ 855 — Cyrillic ▒ 857 — Turkish ▒ 858 — "Multilingual" with euro symbol ▒ 860 — Portuguese ▒ 863 — French (Quebec French) ▒ 865 — Danish/Norwegian ▒ 866 — Cyrillic ▒ 869 — Greek ▒ 874 — Thai ▒ ...
  • 33. ASCIIs estendidos ▒ ISO­8859­1 ▒ Também conhecido como LATIN­1 ▒ É um ASCII estendido: ▒ 256 caracteres ▒ Compatível com ASCII ▒ Usado até hoje
  • 34. ASCIIs estendidos ▒ Maravilha! ▒ Milhares de encodings diferentes ▒ Agora todo mundo vai conseguir representar seus caracteres!
  • 35. ASCIIs estendidos ▒ E a interoperabilidade? ▒ Internet, internacionalização? ▒ Troca de textos, documentos? ▒ Nomes de arquivos?
  • 37.
  • 38. Olá, meu nome é José Luís de Assunção Júnior, sou irmão da Sí lvia, da Cláudia e do João.
  • 39.
  • 40. ASCII ▒ No fim das contas, ficou assim:
  • 41. ASCII ▒ Na teoria: ▒ ASCII original: 0x00 – 0x7F ▒ Extensão do ASCII: 0x80 – 0xFF
  • 42. ASCII ▒ Na prática: ▒ ASCII original: Blz! ▒ Extensão do ASCII: Esquece!
  • 43. Exemplo ▒ Você, aqui no Brasil, usando o DOS, gostaria de dar o seu olá ▒ Você escreve: ▒ Ola! ▒ No Brasil, a gente usava o encoding chamado “Codepage 850” (ou CP850)
  • 44. Exemplo ▒ Essa sua sequência de 4 caracteres (“Ola!”) é uma informação ▒ Informação só existe na cabeça dos seres humanos ▒ Computador não conhece informação. Computador conhece dados.
  • 45. Exemplo ▒ Para um computador, não existe: ▒ Ola! ▒ O que existe são estes 4 bytes: ▒ 0x4F 0x6C 0x61 0x21 ▒ Resultado:
  • 46. Exemplo ▒ Blz ! ▒ O l a ! ▒ ↑ ↑ ↑ ↑ ▒ 0x4F 0x6C 0x61 0x21
  • 47. Exemplo ▒ Mensagem foi codificada em CP850 ▒ Todos os caracteres eram ASCII também ▒ Na prática: ▒ A mensagem está em ASCII ▒ Todo computador entende ASCII ▒ Então blz!
  • 48. Exemplo ▒ E se a gente escrever... ▒ Olá! ▒ Resultado:
  • 49. Exemplo ▒ Blz ! ▒ O l á ! ▒ ↑ ↑ ↑ ↑ ▒ 0x4F 0x6C 0xE1 0x21 ▒ (Usando codepage 850)
  • 50. Exemplo ▒ Até você tentar ler isso num computador russo e...
  • 51. Exemplo ▒ Não blz  ▒ O l р ! ▒ ↑ ↑ ↑ ↑ ▒ 0x4F 0x6C 0xE1 0x21
  • 52. Exemplo ▒ Encoding russo disse: ▒ 0xE1 é um р ▒ Encoding brasileiro tinha dito: ▒ 0xE1 é um á ▒ Quem está certo?
  • 53.
  • 54. Encodings ▒ Não existe uma forma única de representar o caractere á ▒ A sequência de bytes é ambígua: ▒ 0x4F 0x6C 0xE1 0x21
  • 55. Encodings ▒ E se tivesse um jeito... ▒ ...de informar ao computador russo que a gente usou o CP850? ▒ Segure essa ideia!
  • 56. Encodings ▒ O mundo inteiro... ▒ ...cada um com o seu encoding? ▒ É óbvio que não daria certo ▒ Teria que uniformizar de verdade!
  • 57. Encodings ▒ E se houvesse... ▒ Um código... ▒ Um código único... ▒ Um único código... ▒ Um...
  • 59. Unicode ▒ O que é Unicode?
  • 60.
  • 61. The Unicode 5.0 Standard ▒ 1472 páginas ▒ É grande 
  • 62. O que é Unicode? ▒ Unicode é: ▒ Um padrão gigantesco ▒ Subdividido em muitas partes ▒ Unicode, ao contrário do ASCII: ▒ Não É uma tabela de caracteres ▒ Não É um encoding
  • 63. O que é Unicode? ▒ Unicode TEM uma tabela de caracteres: ▒ UCS: Universal Character Set ▒ Unicode TEM diversos encodings ▒ UTF­8, UTF­16, UTF­32 (Unicode Transformation Format)
  • 64. UCS ▒ Tabela gigante de caracteres (~100.000) ▒ Cada caractere possui um código, chamado code point ▒ Code point é representado por U+ e um número em hexadecimal
  • 65. UCS ▒ Exemplos: ▒ U+0058: X ▒ U+00E3: ã ▒ U+2603: ☃ ▒ U+10123:
  • 66. UCS ▒ Intervalo U+0000 – U+007F ▒ Mesmos caracteres da tabela ASCII
  • 67. UCS ▒ Caracteres na tabela são abstratos (são informação) ▒ Para concretizá­los, é necessário um encoding
  • 68. Encodings Unicode ▒ Maneiras de transformar caracteres abstratos em concretos ▒ Três principais: UTF­8, UTF­16, UTF­32
  • 69. UTF­32 ▒ Exemplos: ▒ U+0058: 0x00 0x00 0x00 0x58 ▒ U+00E3: 0x00 0x00 0x00 0xE3 ▒ U+2603: 0x00 0x00 0x26 0x03 ▒ U+10123: 0x00 0x01 0x01 0x23
  • 70. UTF­16 ▒ Exemplos: ▒ U+0058: 0x00 0x58 ▒ U+00E3: 0x00 0xE3 ▒ U+2603: 0x26 0x03 ▒ U+10123: 0xD8 0x00 0xDD 0x23
  • 71. UTF­8 ▒ Exemplos: ▒ U+0058: 0x58 ▒ U+00E3: 0xC3 0xA3 ▒ U+2603: 0xE2 0x98 0x83 ▒ U+10123: 0xF0 0x90 0x84 0xA3
  • 72. UTF­8 ▒ Compatível com ASCII entre U+0000 e U+007F ▒ A partir de U+0080, usa mais de 1 byte ▒ Para os caracteres da língua portuguesa, usa 1 ou 2 bytes
  • 73. UCS e UTF ▒ O que eu preciso saber disso tudo? ▒ Apenas o seguinte:
  • 74. UCS e UTF ▒ Tabela de caracteres ≠ encoding ▒ Diferentes de representação ▒ Mais comum: UTF­8 ▒ UTF­8 ▒ Número variável de bytes por caractere (em geral, 1 ou 2)
  • 75. No mundo real de hoje ▒ Encodings mais usados nos sistemas que rodam no Brasil: ▒ UTF­8 ▒ LATIN­1
  • 76. No mundo real de hoje ▒ U+0000 – U+007F ▒ Mesmos caracteres da tabela ASCII ▒ U+0000 – U+00FF ▒ Mesmos caracteres da tabela LATIN­1
  • 77. LATIN­1 ▒ Serve para representar qualquer caractere Unicode?
  • 78. LATIN­1 ▒ Não! ▒ Usa exatamente 1 byte por caractere ▒ 1 byte não seria suficiente
  • 79. LATIN­1 e UTF­8 ▒ Exemplos Bytes usando Bytes usando Caractere UTF-8 LATIN-1 X 0x58 0x58 Ã 0xC3 0xA3 0xE3 ☃ 0xE2 0x98 0x83 Não existe
  • 80. LATIN­1 e UTF­8 ▒ Blz! ▒ Então vamos representar a string “José” ▒ String: é uma informação ou um dado?
  • 81. LATIN­1 e UTF­8 ▒ Lembra o Barakis Obamis com o PNG e o JPEG?
  • 82. PNG JPEG 1000110 0011000 0010010 1011... 0100... (440KB) (62KB)
  • 83. LATIN­1 e UTF­8 ▒ O José com o LATIN­1 e UTF­8 é a mesma coisa!
  • 84. LATIN­1 José UTF­8 0x4A 0x6F 0x73 0xE9 (4 bytes) 0x4A 0x6F 0x73 0xC3 0xA9 (5 bytes)
  • 85. LATIN­1 e UTF­8 ▒ Blz. Mas por que eu escrevo “José” num lugar e depois aparece “José” no outro?
  • 86. LATIN­1 e UTF­8 ▒ Codificando “José” em UTF­8: ▒ J o s é ▒ ↑ ↑ ↑ ↑ ▒ 0x4A 0x6F 0x73 0xC3 0xA9
  • 87. LATIN­1 e UTF­8 ▒ Aí você envia esses bytes 0x4A 0x6F 0x73 0xC3 0xA9 para alguém
  • 88. LATIN­1 e UTF­8 ▒ Se a pessoa ler em UTF­8, blz! ▒ 0x4A 0x6F 0x73 0xC3 0xA9 ↓ ↓ ↓ ↓ J o s é
  • 89. LATIN­1 e UTF­8 ▒ Mas e se ela ler em LATIN­1? ▒ 0x4A 0x6F 0x73 0xC3 0xA9 ↓ ↓ ↓ ↓ ↓ J o s à ©
  • 90. LATIN­1 e UTF­8 ▒ O texto foi: ▒ Escrito em UTF­8 ▒ Enviado a outro sistema ▒ Como o outro sistema vai adivinhar que o texto está em UTF­8?
  • 91. Unicode ▒ Mas então não é só todo mundo codificar seus caracteres usando Unicode e vai dar tudo certo!?
  • 92. Unicode ▒ Calma ... ▒ Em 1º lugar, Unicode não é um encoding. Não existe “codificar caracteres usando Unicode”. ▒ Em 2º lugar, não temos controle sobre todos os sistemas do mundo. Não podemos fazer com que todos usem o mesmo encoding (nem deveríamos).
  • 93. Parte 3 Como faz pra dar certo
  • 94. Informação = dados + forma de interpretá-los
  • 95. Informação String = = Dados Bytes + + Forma de Encoding interpretá­los
  • 96. String.. =.. bytes + encoding
  • 97. Não existe string sem encoding!
  • 98. Não existe relação byte  caractere sem encoding!
  • 99. Como faz pra dar certo ▒ 2 dicas para evitar problemas de encoding:
  • 100. Como faz pra dar certo ▒ 1) Use sequências de escape sempre que possível ▒ Para escrever “Programação”: ▒ Em Java: ▒ "Programau00e7u00e3o" ▒ Em HTML: ▒ <p>Programa&ccedil;&atilde;o</p>
  • 101. Como faz pra dar certo ▒ 2) Faça conversões só quando realmente for necessário ▒ Ao fazer qualquer conversão, SEMPRE especifique o encoding
  • 102. Como faz pra dar certo ▒ Vetor de bytes não é string! ▒ String não é vetor de bytes! ▒ O que é válido é: ▒ Decompor string em vetor de bytes + encoding ▒ Compor string a partir de um vetor de bytes + um encoding
  • 103. Como faz pra dar certo ▒ Quando é que realmente precisamos fazer conversões? ▒ Quando fazemos entrada/saída
  • 104. Como faz pra dar certo ▒ Exemplos:
  • 105. Como faz pra dar certo ▒ Você vai enviar texto em uma requisição HTTP? ▒ Converta a string para bytes usando algum encoding ▒ Avise ao servidor que você vai usar esse encoding ▒ Envie os bytes
  • 106. Como faz pra dar certo ▒ Errado: ▒ Content-Type: text/plain ▒ Certo: ▒ Content-Type: text/plain; charset=utf-8 ▒ Content-Type: text/plain; charset=iso-8859-1
  • 107. Como faz pra dar certo ▒ Vai receber um XML? ▒ Receba o conteúdo (bytes) ▒ Repasse diretamente os bytes para a sua biblioteca de processamento de XML
  • 108. Como faz pra dar certo ▒ Não preciso me preocupar com encoding ao processar XML? ▒ Em geral, não! ▒ XML informa seu encoding dentro do próprio documento ▒ <?xml version="1.0" encoding="utf­8"?> ▒ (deveria, pelo menos!)
  • 109. Como faz pra dar certo ▒ “Tem que passar o encoding, tem que passar o encoding...” ▒ E se eu não passar o encoding? Não funciona?
  • 110. Como faz pra dar certo ▒ Funciona! ▒ ...às vezes! ▒ O que acontece se eu não especificar encoding? ▒ Nenhum encoding será usado! ▒ Certo!?
  • 112.
  • 113. Como faz pra dar certo ▒ Se você não especificar encoding, será usado o encoding padrão da plataforma ▒ E isso é ERRADO! ▒ É um perigo! ▒ É um absurdo!
  • 114. Como faz pra dar certo ▒ Plataformas MUDAM! ▒ Configurações de ambiente MUDAM! ▒ Encoding padrão MUDA!
  • 115. Java: jeito errado ▒ byte[] meusBytes = string.getBytes(); (...) String minhaString = new String(bytes); ▒ Está dependente de plataforma!
  • 116. Java: jeito certo ▒ byte[] meusBytes = string.getBytes("UTF­8"); (...) String minhaString = new String(bytes, "UTF­8"); ▒ Agora, sim, independe de plataforma!
  • 117. Java: jeito certo ▒ Não precisa ser UTF­8, pode ser qualquer outro
  • 118. Java: jeito certo ▒ byte[] meusBytes = string.getBytes("LATIN1"); (...) String minhaString = new String(bytes, "LATIN1");
  • 119. Java: jeito certo ▒ byte[] meusBytes = string.getBytes("UTF­16"); (...) String minhaString = new String(bytes, "UTF­16");
  • 120. Java: jeito certo ▒ byte[] meusBytes = string.getBytes("UTF­32"); (...) String minhaString = new String(bytes, "UTF­32");
  • 122. Conclusões ▒ Problemas de encoding acontecem nas melhores famílias
  • 123. Conclusões ▒ Causas são sempre as mesmas: ▒ String sendo lida e/ou escrita usando o encoding errado ▒ Uso indevido do encoding padrão da plataforma ▒ Causa raiz de todo o problema: ▒ Ambiguidade: mais de uma maneira de representar a mesma informação
  • 124. Conclusões ▒ A solução é: ▒ Lembrar: não existe string sem encoding! ▒ Informar o encoding toda vez que fizer entrada/saída
  • 125. Referências ▒ The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) ▒ http://www.joelonsoftware.com/articles/U
  • 126. Referências ▒ Lista de caracteres Unicode e suas diferentes representações ▒ http://www.fileformat.info/info/unicode/ ▒ The Unicode Consortium ▒ http://unicode.org/
  • 127. Referências ▒ ASCII ▒ http://en.wikipedia.org/wiki/ASCII ▒ Unicode ▒ http://en.wikipedia.org/wiki/Unicode ▒ UTF­8 ▒ http://en.wikipedia.org/wiki/UTF-8
  • 128. Adendo ▒ “José” em UTF­8 gasta 8 bytes? ▒ http://en.wikipedia.org/wiki/Byte_order_ ▒ Encoding padrão da plataforma? ▒ Em geral, é errado usar ▒ Em raras situações, é correto. Ex: upload de arquivo no cliente.
  • 129. Contatos ▒ Andru00e9 Willik Valenti ▒ awvalenti@gmail.com ▒ @awvFi ▒ Andrei de Oliveira Tognolo ▒ andreitognolo@gmail.com ▒ /andreitognolo