SlideShare uma empresa Scribd logo
1 de 152
Rodrigo Branas – @rodrigobranas - http://www.agilecode.com.br




Desvendando os mistérios do Charset
  Aprenda a evitar sofrimentos no furuto!
http://www.slideshare.net/rodrigobranas
@rodrigobranas
  rodrigo.branas@gmail.com
 http://www.agilecode.com.br

Formação Acadêmica
Ciências da Computação – UFSC
Gerenciamento de Projetos - FGV

Certificações

SCJA, SCJP, SCJD, SCWCD, SCBCD, PMP, MCP e CSM
Rodrigo Branas – rodrigo.branas@gmail.com
10 anos de experiência na plataforma Java
1000 horas em sala de aula
Mais de 50 palestras em eventos

Líder da área de desenvolvimento na Gennera
Autor da revista Java Magazine
Palestrante
Instrutor da Academia Java e Agile da Globalcode
Criador dos treinamentos de Clean Code, Selenium e
Maven da Agile Code

Trabalhou com as empresas: EDS, HP, GM, Citibank,
OnCast, Globalcode, V.Office, Dígitro, Softplan, Unimed,
Suntech, Vale do Rio Doce, Senai, NET.
Qual é a forma mais comum de
resolver esse tipo de problema?
Recorrendo a ciências esotéricas
Tentativa e erro... Nem sempre funciona
Começando pelo princípio...
A criação do Telégrafo - 1837
Meio revolucionário de comunicação
Transmissão de pulsos elétricos
Faz o que com os pulsos elétricos?
Samuel F. Morse
Esquecemos dos russos!
Código Morse - Cirílico
Era da computação
O negócio agora é em bytes
No início era carnaval!
Como fica a interoperabilidade?
9 sistemas de codificação diferentes
Surgimento do ASCII
   Luz no fim do túnel
ASCII
ASCII
American Standard Code for Information Interchange
ASCII
American Standard Code for Information Interchange

                Publicado em 1963
ASCII
American Standard Code for Information Interchange

               Publicado em 1963
             7 bits ou 128 caracteres
Tabela ASCII
ASCII
American Standard Code for Information Interchange

                Publicado em 1963
              7 bits ou 128 caracteres
      32 caracteres não imprimíveis (00 ~ 1F)
ASCII
American Standard Code for Information Interchange

                Publicado em 1963
              7 bits ou 128 caracteres
      32 caracteres não imprimíveis (00 ~ 1F)
        96 caracteres imprimíveis (20 ~ 7F)
ASCII
American Standard Code for Information Interchange

                 Publicado em 1963
               7 bits ou 128 caracteres
      32 caracteres não imprimíveis (00 ~ 1F)
         96 caracteres imprimíveis (20 ~ 7F)
Foi o sistema de codificação mais utilizado até 2007
        (quando foi ultrapassado pelo UTF-8)
ASCII
American Standard Code for Information Interchange

                 Publicado em 1963
               7 bits ou 128 caracteres
      32 caracteres não imprimíveis (00 ~ 1F)
         96 caracteres imprimíveis (20 ~ 7F)
Foi o sistema de codificação mais utilizado até 2007
        (quando foi ultrapassado pelo UTF-8)
  Deu origem ao sistema de codificação US-ASCII
Tabela ASCII
Só 7 bits?
Como ficam os outros idiomas?
Exemplos de caracteres comuns não
     suportados pelo ASCII:


          Ñ (Espanhol)
          É (Português)
           ß (Alemão)
            Å (Sueco)
           ő (Hungaro)
E se a gente colocar mais 1 bit?
Norma ISO 8859
Norma ISO 8859
International Standard Organization
Norma ISO 8859
    International Standard Organization

Conjunto de sistemas de codificação de 8 bits
Norma ISO 8859
    International Standard Organization

Conjunto de sistemas de codificação de 8 bits
          Regionalizado (16 tipos)
Norma ISO 8859
    International Standard Organization

Conjunto de sistemas de codificação de 8 bits
          Regionalizado (16 tipos)
      96 novos caracteres! (Agora vai)
Norma ISO 8859
      International Standard Organization

  Conjunto de sistemas de codificação de 8 bits
            Regionalizado (16 tipos)
        96 novos caracteres! (Agora vai)
Nascimento do sistema de codificação ISO-8859-x
Norma ISO 8859
      International Standard Organization

  Conjunto de sistemas de codificação de 8 bits
            Regionalizado (16 tipos)
        96 novos caracteres! (Agora vai)
Nascimento do sistema de codificação ISO-8859-x
   Compatível com o ASCII por motivos óbvios
Vamos ver os sabores!
ISO-8859-1
             Latin-1 Western Europe

  Um dos sitemas de codificação mais utilizados!

Dinamarquês, Holandês, Inglês, Finlandês, Francês,
 Alemão, Italiano, Norueguês, Português, Romeno,
            Espanhol, Catalão e Sueco.
ISO-8859-2
                Latin-2 Central Europa

                    Menos utilizado!

Bósnio, Polonês, Croata, Tcheco, Eslovaco, Esloveno, Sér
                    vio e Húngaro.
ISO-8859-3
  Latin-3 South Europe

     Menos utilizado!

Turco, Maltês e Esperanto.
ISO-8859-4
  Latin-4 North Europe

     Menos utilizado!

Difícil até de pronunciar...
ISO-8859-5 Latin/Cyrillic
ISO-8859-6 Latin/Arabic
ISO-8859-7 Latin/Greek
ISO-8859-8 Latin/Hebrew
ISO-8859-9 Latin-5 Turkish
ISO-8859-10 Latin-6 Nordic
ISO-8859-11 Latin Thai
ISO-8859-12 Latin Devanagari
ISO-8859-13 Latin Baltic Rim
ISO-8859-14 Latin Celtic
ISO-8859-15 Latin-9 (Francês completo)
ISO-8859-16 Latin-10 South-Eastern European
Só 8 bits?
Como ficam os japoneses nessa
          história?
Outros sistemas de codificação utilizados principalmente
       pelos idiomas japonês, chinês e coreano:

         Big5: Chinese, Japanese and Korean
          Institute of Information of Taiwan
                         2 bytes

                 Shift JIS: Japanese
           ASCII Corporation and Microsoft
                  Entre 1 e 2 bytes
Alguém tinha que acabar
com a bagunça!
Surgimento do Unicode
    Luz no fim do túnel
Unicode
Universal Character Set
Unicode
Universal Character Set

  Publicado em 1991
Unicode
              Universal Character Set

                Publicado em 1991
Acabar com as limitações dos sistemas de caracteres
(principalmente os pertencentes a norma ISO 8859)
Unicode
              Universal Character Set

                 Publicado em 1991
Acabar com as limitações dos sistemas de caracteres
(principalmente os pertencentes a norma ISO 8859)
        Capacidade para 1.114.112 caracteres
Unicode
              Universal Character Set

                Publicado em 1991
Acabar com as limitações dos sistemas de caracteres
(principalmente os pertencentes a norma ISO 8859)
       Capacidade para 1.114.112 caracteres
Unicode
              Universal Character Set

                 Publicado em 1991
Acabar com as limitações dos sistemas de caracteres
(principalmente os pertencentes a norma ISO 8859)
        Capacidade para 1.114.112 caracteres
 Primeiros 256 caracteres iguais aos do ISO-8859-1
             (Compatibilidade reversa)
Unicode
                Universal Character Set

                   Publicado em 1991
 Acabar com as limitações dos sistemas de caracteres
  (principalmente os pertencentes a norma ISO 8859)
          Capacidade para 1.114.112 caracteres
   Primeiros 256 caracteres iguais aos do ISO-8859-1
               (Compatibilidade reversa)
Sendo assim, os 128 primeiros caracteres são iguais aos
                    da tabela ASCII
Version   Date   Scripts   Caracteres
Histórico de versões     1.0     1991     24        7.161
                        1.0.1    1992     25       28.359
                         1.1     1993     24       34.233
                         2.0     1996     25       38.950
                         2.1     1998     25       38.952
                         3.0     1999     38       49.259
                         3.1     2001     41       94.205
                         3.2     2002     45       95.221
                         4.0     2003     52       96.447
                         4.1     2005     59       97.720
                         5.0     2006     64       99.089
                         5.1     2008     75       100.713
                         5.2     2009     90       107.361
                         6.0     2010     93       109.449
                         6.1     2012    100       110.181
Version   Date   Scripts   Caracteres
Histórico de versões     1.0     1991     24        7.161
                        1.0.1    1992     25       28.359
                         1.1     1993     24       34.233
                         2.0     1996     25       38.950
                         2.1     1998     25       38.952
                         3.0     1999     38       49.259
                         3.1     2001     41       94.205
                         3.2     2002     45       95.221
                         4.0     2003     52       96.447
                         4.1     2005     59       97.720
                         5.0     2006     64       99.089
                         5.1     2008     75       100.713
                         5.2     2009     90       107.361
                         6.0     2010     93       109.449
                         6.1     2012    100       110.181
Version   Date   Scripts   Caracteres
Histórico de versões     1.0     1991     24        7.161
                        1.0.1    1992     25       28.359
                         1.1     1993     24       34.233
                         2.0     1996     25       38.950
                         2.1     1998     25       38.952
                         3.0     1999     38       49.259
                         3.1     2001     41       94.205
                         3.2     2002     45       95.221
                         4.0     2003     52       96.447
                         4.1     2005     59       97.720
                         5.0     2006     64       99.089
                         5.1     2008     75       100.713
                         5.2     2009     90       107.361
                         6.0     2010     93       109.449
                         6.1     2012    100       110.181
Não dá pra representar o Unicode como
era feito com o ASCII e o ISO-8859-1?
O Unicode precisa ser codificado!
Imagine a palavra Maça
Imagine a palavra Maça

       M -> 4D
       a -> 61
       ç -> E7
       a -> 61
Imagine a palavra Maça

                 M -> 4D
                 a -> 61
                 ç -> E7
                 a -> 61

O primeiro encoding para Unicode foi o UCS-2

            M    a   ç    a
          004D 0061 00E7 0061
Imagine a palavra Maça

                 M -> 4D
                 a -> 61
                 ç -> E7
                 a -> 61

O primeiro encoding para Unicode foi o UCS-2

            M    a   ç    a
          004D 0061 00E7 0061
Novamente, assim não dá!
UTF-8
UTF-8
Unicode Transformation Format
UTF-8
       Unicode Transformation Format

Esse negócio de utilizar 2 bytes não vai rolar!
UTF-8
       Unicode Transformation Format

Esse negócio de utilizar 2 bytes não vai rolar!
   Representação variável de 1 a 4 bytes.
UTF-8
           Unicode Transformation Format

    Esse negócio de utilizar 2 bytes não vai rolar!
       Representação variável de 1 a 4 bytes.
No UTF-8 os caracteres abaixo de 128 são armazenados
                  em apenas 1 byte.
UTF-8
           Unicode Transformation Format

    Esse negócio de utilizar 2 bytes não vai rolar!
       Representação variável de 1 a 4 bytes.
No UTF-8 os caracteres abaixo de 128 são armazenados
                  em apenas 1 byte.
              Compatível com o ASCII.
UTF-8
           Unicode Transformation Format

    Esse negócio de utilizar 2 bytes não vai rolar!
        Representação variável de 1 a 4 bytes.
No UTF-8 os caracteres abaixo de 128 são armazenados
                  em apenas 1 byte.
              Compatível com o ASCII.
     Formado por octetos (8-bit), por isso UTF-8.
UTF-8
Unicode Transformation Format
Imagine a palavra Maça

      M -> 4D
      a -> 61
      ç -> E7
      a -> 61

Codificando com UTF-8

   M a    ç   a
  4D 61 C3 A7 61
Imagine a palavra Maça

      M -> 4D
      a -> 61
      ç -> E7
      a -> 61

Codificando com UTF-8

   M a    ç   a
  4D 61 C3 A7 61
Classe String
Tipo char

  2 bytes
Tipo char

   2 bytes
Não sinalizado
Tipo char

           2 bytes
        Não sinalizado
Armazena valores de 0 até 65535
Tipo char

              2 bytes
           Não sinalizado
  Armazena valores de 0 até 65535
Representa um code point do Unicode
Exibindo os caracteres e seus
   respectivos code points
1.   public static void main(String args[]) {
2.     String texto = “Java Magazine”;
3.     for(char c : texto.toCharArray()) {
4.       System.out.print(c);
5.       System.out.print((int) c);
6.     }
7.   }

Console:
1.   public static void main(String args[]) {
2.     String texto = “Java Magazine”;
3.     for(char c : texto.toCharArray()) {
4.       System.out.print(c);
5.       System.out.print((int) c);
6.     }
7.   }

Console:

J74a97v118a97
32M77a97g103a97z122i105n110e101
1.   public static void main(String args[]) {
2.     String texto = “Java Magazine”;
3.     for(char c : texto.toCharArray()) {
4.       System.out.print(c);
5.       System.out.print((int) c);
6.     }
7.   }

Console:

J74a97v118a97
32M77a97g103a97z122i105n110e101
Inicializando o tipo char
1.    public static void main(String args[]) {
2.      char a = ‘a’;
3.      char b = 97;
4.      char c = ‘u0061’;
5.      char d = 0x61;
6.      System.out.print(a);
7.      System.out.print(b);
8.      System.out.print(c);
9.      System.out.print(d);
10.   }

Console:
1.     public static void main(String args[]) {
2.       char a = ‘a’;
3.       char b = 97;
4.       char c = ‘u0061’;
5.       char d = 0x61;
6.       System.out.print(a);
7.       System.out.print(b);
8.       System.out.print(c);
9.       System.out.print(d);
10.    }

Console:

aaaa
Codificando a classe String
Exemplo

Codificar a palavra “Maça” em ISO-
          8859-1 e UTF-8
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmISO = texto.getBytes(“ISO-8859-1”);
4.     for(byte b : textoEmISO) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmISO = texto.getBytes(“ISO-8859-1”);
4.     for(byte b : textoEmISO) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmISO = texto.getBytes(“ISO-8859-1”);
4.     for(byte b : textoEmISO) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:

77 97 -25 97
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmUTF = texto.getBytes(“UTF-8”);
4.     for(byte b : textoEmUTF) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmUTF = texto.getBytes(“UTF-8”);
4.     for(byte b : textoEmUTF) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:
1.   public static void main(String args[]) {
2.     String texto = “Maça”;
3.     byte[] textoEmUTF = texto.getBytes(“UTF-8”);
4.     for(byte b : textoEmUTF) {
5.       System.out.print(b + “ “);
6.     }
7.   }

Console:

77 97 -61 -89 97
1.    public byte[] encodeUTF8(String value) {
2.           byte[] utf8 = new byte[bytesNeeded];
3.           // do the conversion from character code points to utf-8
4.           for (int i = 0, bytes = 0; i < ch.length; i++) {
5.                  if (ch[i] < 0x80) {
6.                         utf8[bytes++] = (byte) ch[i];
7.                  } else if (ch[i] < 0x0800) {
8.                         utf8[bytes++] = (byte) (ch[i] >> 6 | 0xC0);
9.                         utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80);
10.                 } else if (ch[i] < 0x10000) {
11.                        utf8[bytes++] = (byte) (ch[i] >> 12 | 0xE0);
12.                        utf8[bytes++] = (byte) (ch[i] >> 6 & 0x3F | 0x80);
13.                        utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80);
14.                 } else {
15.                        utf8[bytes++] = (byte) (ch[i] >> 18 | 0xF0);
16.                        utf8[bytes++] = (byte) (ch[i] >> 12 & 0x3F | 0x80);
17.                        utf8[bytes++] = (byte) (ch[i] >> 6 & 0x3F | 0x80);
18.                        utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80);
19.                 }
20.          }
21.          return utf8;
22.   }
Decodificando bytes
Exemplo

Decodificando os bytes da palavra
  “Maça” codificada em UTF-8

        97 77 -61 -89 77
1.   public static void main(String args[]) {
2.     byte[] textoEmUTF = new byte[]{77,97,-61,-89,97};
3.     String texto = new String(textoEmUTF, “ISO-8859-1”);
4.     System.out.println(texto);
5.   }

Console:
1.   public static void main(String args[]) {
2.     byte[] textoEmUTF = new byte[]{77,97,-61,-89,97};
3.     String texto = new String(textoEmUTF, “ISO-8859-1”);
4.     System.out.println(texto);
5.   }

Console:
1.   public static void main(String args[]) {
2.     byte[] textoEmUTF = new byte[]{77,97,-61,-89,97};
3.     String texto = new String(textoEmUTF, “ISO-8859-1”);
4.     System.out.println(texto);
5.   }

Console:

Maça
De onde vem os bytes?
InputStream e OutputStream
Exemplo

Lendo o conteúdo de um
     arquivo texto
1.   public static void main(String args[]) {
2.     InputStream input = new FileInputStream(“file.txt”);
3.     byte[] conteudo = new byte[input.available()];
4.     input.read(conteudo);
5.     String texto = new String(conteudo, “ISO-8859-1”);
6.     System.out.println(texto);
7.   }
1.   public static void main(String args[]) {
2.     InputStream input = new FileInputStream(“file.txt”);
3.     byte[] conteudo = new byte[input.available()];
4.     input.read(conteudo);
5.     String texto = new String(conteudo, “ISO-8859-1”);
6.     System.out.println(texto);
7.   }
Como saber o sistema de
  codificação correto?
Exemplo

Consultando uma página web por
    meio do protocolo HTTP
1.       public static void main(String args[]) {
2.         String url = “http://www.javamagazine.com.br”;
3.         InputStream input = new URL(url).openStream();
4.         byte[] conteudo = new byte[input.available()];
5.         input.read(conteudo);
6.         String html = new String(conteudo, “ISO-8859-1”);
7.         System.out.println(html);
8.       }

Console:
<html>
<head>
<title>DevMedia - Canal Java</title>
<link rel="canonical" href="http://www.devmedia.com.br/java/" />
<link rel="shortcut icon" href="/favicon.ico">
<meta http-equiv="refresh" content="300">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
...
1.       public static void main(String args[]) {
2.         String url = “http://www.javamagazine.com.br”;
3.         InputStream input = new URL(url).openStream();
4.         byte[] conteudo = new byte[input.available()];
5.         input.read(conteudo);
6.         String html = new String(conteudo, “ISO-8859-1”);
7.         System.out.println(html);
8.       }

Console:
<html>
<head>
<title>DevMedia - Canal Java</title>
<link rel="canonical" href="http://www.devmedia.com.br/java/" />
<link rel="shortcut icon" href="/favicon.ico">
<meta http-equiv="refresh" content="300">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
...
Como descobrir o sistema de
   codificação correto?
Problemas de Charset
      na Web
HTTP Request
GET /javamagazine/ HTTP/1.1
Host: www.devmedia.com.br
User-Agent: Mozilla/5.0 Gecko/20100101 Firefox/14.0.1
Accept: text/html
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
HTTP Response
HTTP/1.1 200 OK
Content-Type: text/html;charset=ISO-8859-1;
Content-Encoding: gzip
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 15 Aug 2012 03:30:07 GMT
HTTP Response
HTTP/1.1 200 OK
Content-Type: text/html;charset=ISO-8859-1;
Content-Encoding: gzip
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 15 Aug 2012 03:30:07 GMT
Simulando problemas
1.    @WebServlet(“/javamagazine”)
2.    public class EnsaioServlet extends HttpServlet {
3.      protected void doGet(HttpServletRequest req, HttpServletResponse res) {
4.        String texto = “Maça”;
5.        OutputStream output = response.getOutputStream();
6.        for(byte b : texto.getBytes(“ISO-8859-1”) {
7.          output.write(b);
8.        }
9.        output.close();
10.     }
11.   }
HTTP Response
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Length: 4
Date: Sat, 18 Aug 2012 13:49:35 GMT
Cada browser assume um sistema de
        codificação padrão
Definindo o charset no
   HTTP Response
1.    @WebServlet(“/javamagazine”)
2.    public class EnsaioServlet extends HttpServlet {
3.      protected void doGet(HttpServletRequest req, HttpServletResponse res) {
4.        String texto = “Maça”;
5.        OutputStream output = response.getOutputStream();
6.        for(byte b : texto.getBytes(“ISO-8859-1”) {
7.          output.write(b);
8.        }
9.        output.close();
10.     }
11.   }
1.    @WebServlet(“/javamagazine”)
2.    public class EnsaioServlet extends HttpServlet {
3.     protected void doGet(HttpServletRequest req, HttpServletResponse res) {
4.      String texto = “Maça”;
5.
6.            OutputStream output = response.getOutputStream();
7.            for(byte b : texto.getBytes(“ISO-8859-1”) {
8.              output.write(b);
9.            }
10.           output.close();
11.       }
12.   }
1.    @WebServlet(“/javamagazine”)
2.    public class EnsaioServlet extends HttpServlet {
3.      protected void doGet(HttpServletRequest req, HttpServletResponse res) {
4.        String texto = “Maça”;
5.        res.setContentType(“text/html;charset=ISO-8859-1”);
6.        OutputStream output = response.getOutputStream();
7.        for(byte b : texto.getBytes(“ISO-8859-1”) {
8.          output.write(b);
9.        }
10.       output.close();
11.     }
12.   }
Declarando a tag META
 no documento HTML
<HTML>
<HEAD>
<META http-equiv =“Content-Type”
content=“text/html;charset=ISO-8859-1”>
</HEAD>
<BODY>
...
</BODY>
</HTML>
Ordem de prioridade dada pelos
               browsers

1.   Charset definido na propriedade Content-Type do
     cabeçalho do HTTP Response
2.   Declaração da tag META com o atributo “http-equiv” no
     head do documento HTML
3.   O atributo charset definido em elementos de importação
     de recursos externos como Javascript.
Cuidado com a compilação dos
       arquivos fonte
1.   public class TesteCompilacao {
2.     public static void main(String[] args) {
3.       String texto = “Maça”;
4.       System.out.println(texto);
5.     }
6.   }
1.   public class TesteCompilacao {
2.     public static void main(String[] args) {
3.       String texto = “Maça”;
4.       System.out.println(texto);
5.     }
6.   }

Console:

javac TesteCompilacao.java –encoding ISO-8859-1

java TesteCompilacao

Maça
Cuidado com sistemas de codificação
específicos como MacRoman e Cp1252!
Dicas para evitar problemas
             de codificação

•   Defina um padrão na equipe
•   Evite sistemas de codificação específicos de um sistema
    operacional
•   Prefira o UTF-8
•   Fique atento a compilação
•   Sempre defina o Content-Type
•   Declare a tag META http-equiv
•   Externalize as String’s
•   Evite resolver os problemas na base da tentativa e erro
Obrigado!
www.slideshare.net/rodrigobranas

Mais conteúdo relacionado

Mais de Rodrigo Branas

Node.js - #3 - Global Objects - Rodrigo Branas
Node.js - #3 - Global Objects - Rodrigo BranasNode.js - #3 - Global Objects - Rodrigo Branas
Node.js - #3 - Global Objects - Rodrigo BranasRodrigo Branas
 
Node.js - #2 - Sistema de Módulos - Rodrigo Branas
Node.js - #2 - Sistema de Módulos - Rodrigo BranasNode.js - #2 - Sistema de Módulos - Rodrigo Branas
Node.js - #2 - Sistema de Módulos - Rodrigo BranasRodrigo Branas
 
Node.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasNode.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasRodrigo Branas
 
#6 - Git - Desfazendo as coisas
#6 - Git - Desfazendo as coisas#6 - Git - Desfazendo as coisas
#6 - Git - Desfazendo as coisasRodrigo Branas
 
#1 - Git - Introdução
#1 - Git - Introdução#1 - Git - Introdução
#1 - Git - IntroduçãoRodrigo Branas
 
#5 - Git - Contribuindo com um repositório remoto
#5 - Git - Contribuindo com um repositório remoto#5 - Git - Contribuindo com um repositório remoto
#5 - Git - Contribuindo com um repositório remotoRodrigo Branas
 
#3 - Git - Branching e Merging
#3 - Git - Branching e Merging#3 - Git - Branching e Merging
#3 - Git - Branching e MergingRodrigo Branas
 
A evolução do AngularJS
A evolução do AngularJSA evolução do AngularJS
A evolução do AngularJSRodrigo Branas
 
JavaScript - Expressões Regulares
JavaScript - Expressões RegularesJavaScript - Expressões Regulares
JavaScript - Expressões RegularesRodrigo Branas
 
Automação de Testes com AngularJS
Automação de Testes com AngularJSAutomação de Testes com AngularJS
Automação de Testes com AngularJSRodrigo Branas
 
HTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSHTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSRodrigo Branas
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJSRodrigo Branas
 
Criando Filtros com AngularJS
Criando Filtros com AngularJSCriando Filtros com AngularJS
Criando Filtros com AngularJSRodrigo Branas
 
Criando aplicações Single-Page com AngularJS
Criando aplicações Single-Page com AngularJSCriando aplicações Single-Page com AngularJS
Criando aplicações Single-Page com AngularJSRodrigo Branas
 
Construindo Diretivas com AngularJS
Construindo Diretivas com AngularJSConstruindo Diretivas com AngularJS
Construindo Diretivas com AngularJSRodrigo Branas
 
Técnicas de Refactoring
Técnicas de RefactoringTécnicas de Refactoring
Técnicas de RefactoringRodrigo Branas
 

Mais de Rodrigo Branas (20)

Node.js - #3 - Global Objects - Rodrigo Branas
Node.js - #3 - Global Objects - Rodrigo BranasNode.js - #3 - Global Objects - Rodrigo Branas
Node.js - #3 - Global Objects - Rodrigo Branas
 
Node.js - #2 - Sistema de Módulos - Rodrigo Branas
Node.js - #2 - Sistema de Módulos - Rodrigo BranasNode.js - #2 - Sistema de Módulos - Rodrigo Branas
Node.js - #2 - Sistema de Módulos - Rodrigo Branas
 
Node.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasNode.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo Branas
 
#6 - Git - Desfazendo as coisas
#6 - Git - Desfazendo as coisas#6 - Git - Desfazendo as coisas
#6 - Git - Desfazendo as coisas
 
#1 - Git - Introdução
#1 - Git - Introdução#1 - Git - Introdução
#1 - Git - Introdução
 
#5 - Git - Contribuindo com um repositório remoto
#5 - Git - Contribuindo com um repositório remoto#5 - Git - Contribuindo com um repositório remoto
#5 - Git - Contribuindo com um repositório remoto
 
#4 - Git - Stash
#4 - Git - Stash#4 - Git - Stash
#4 - Git - Stash
 
#3 - Git - Branching e Merging
#3 - Git - Branching e Merging#3 - Git - Branching e Merging
#3 - Git - Branching e Merging
 
#2 - Git - DAG
#2 - Git - DAG#2 - Git - DAG
#2 - Git - DAG
 
A evolução do AngularJS
A evolução do AngularJSA evolução do AngularJS
A evolução do AngularJS
 
JavaScript - Date
JavaScript - DateJavaScript - Date
JavaScript - Date
 
JavaScript - Expressões Regulares
JavaScript - Expressões RegularesJavaScript - Expressões Regulares
JavaScript - Expressões Regulares
 
Automação de Testes com AngularJS
Automação de Testes com AngularJSAutomação de Testes com AngularJS
Automação de Testes com AngularJS
 
Scope AngularJS
Scope AngularJSScope AngularJS
Scope AngularJS
 
HTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSHTTP Interceptors com AngularJS
HTTP Interceptors com AngularJS
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJS
 
Criando Filtros com AngularJS
Criando Filtros com AngularJSCriando Filtros com AngularJS
Criando Filtros com AngularJS
 
Criando aplicações Single-Page com AngularJS
Criando aplicações Single-Page com AngularJSCriando aplicações Single-Page com AngularJS
Criando aplicações Single-Page com AngularJS
 
Construindo Diretivas com AngularJS
Construindo Diretivas com AngularJSConstruindo Diretivas com AngularJS
Construindo Diretivas com AngularJS
 
Técnicas de Refactoring
Técnicas de RefactoringTécnicas de Refactoring
Técnicas de Refactoring
 

Desvendando os mistérios do Charset

  • 1. Rodrigo Branas – @rodrigobranas - http://www.agilecode.com.br Desvendando os mistérios do Charset Aprenda a evitar sofrimentos no furuto!
  • 3. @rodrigobranas rodrigo.branas@gmail.com http://www.agilecode.com.br Formação Acadêmica Ciências da Computação – UFSC Gerenciamento de Projetos - FGV Certificações SCJA, SCJP, SCJD, SCWCD, SCBCD, PMP, MCP e CSM
  • 4. Rodrigo Branas – rodrigo.branas@gmail.com 10 anos de experiência na plataforma Java 1000 horas em sala de aula Mais de 50 palestras em eventos Líder da área de desenvolvimento na Gennera Autor da revista Java Magazine Palestrante Instrutor da Academia Java e Agile da Globalcode Criador dos treinamentos de Clean Code, Selenium e Maven da Agile Code Trabalhou com as empresas: EDS, HP, GM, Citibank, OnCast, Globalcode, V.Office, Dígitro, Softplan, Unimed, Suntech, Vale do Rio Doce, Senai, NET.
  • 5.
  • 6.
  • 7.
  • 8. Qual é a forma mais comum de resolver esse tipo de problema?
  • 10. Tentativa e erro... Nem sempre funciona
  • 12. A criação do Telégrafo - 1837
  • 13. Meio revolucionário de comunicação
  • 14.
  • 16. Faz o que com os pulsos elétricos?
  • 18.
  • 20.
  • 21. Código Morse - Cirílico
  • 23. O negócio agora é em bytes
  • 24. No início era carnaval!
  • 25. Como fica a interoperabilidade?
  • 26. 9 sistemas de codificação diferentes
  • 27. Surgimento do ASCII Luz no fim do túnel
  • 28. ASCII
  • 29. ASCII American Standard Code for Information Interchange
  • 30. ASCII American Standard Code for Information Interchange Publicado em 1963
  • 31. ASCII American Standard Code for Information Interchange Publicado em 1963 7 bits ou 128 caracteres
  • 33. ASCII American Standard Code for Information Interchange Publicado em 1963 7 bits ou 128 caracteres 32 caracteres não imprimíveis (00 ~ 1F)
  • 34. ASCII American Standard Code for Information Interchange Publicado em 1963 7 bits ou 128 caracteres 32 caracteres não imprimíveis (00 ~ 1F) 96 caracteres imprimíveis (20 ~ 7F)
  • 35. ASCII American Standard Code for Information Interchange Publicado em 1963 7 bits ou 128 caracteres 32 caracteres não imprimíveis (00 ~ 1F) 96 caracteres imprimíveis (20 ~ 7F) Foi o sistema de codificação mais utilizado até 2007 (quando foi ultrapassado pelo UTF-8)
  • 36. ASCII American Standard Code for Information Interchange Publicado em 1963 7 bits ou 128 caracteres 32 caracteres não imprimíveis (00 ~ 1F) 96 caracteres imprimíveis (20 ~ 7F) Foi o sistema de codificação mais utilizado até 2007 (quando foi ultrapassado pelo UTF-8) Deu origem ao sistema de codificação US-ASCII
  • 39. Como ficam os outros idiomas?
  • 40. Exemplos de caracteres comuns não suportados pelo ASCII: Ñ (Espanhol) É (Português) ß (Alemão) Å (Sueco) ő (Hungaro)
  • 41.
  • 42. E se a gente colocar mais 1 bit?
  • 44. Norma ISO 8859 International Standard Organization
  • 45. Norma ISO 8859 International Standard Organization Conjunto de sistemas de codificação de 8 bits
  • 46. Norma ISO 8859 International Standard Organization Conjunto de sistemas de codificação de 8 bits Regionalizado (16 tipos)
  • 47. Norma ISO 8859 International Standard Organization Conjunto de sistemas de codificação de 8 bits Regionalizado (16 tipos) 96 novos caracteres! (Agora vai)
  • 48. Norma ISO 8859 International Standard Organization Conjunto de sistemas de codificação de 8 bits Regionalizado (16 tipos) 96 novos caracteres! (Agora vai) Nascimento do sistema de codificação ISO-8859-x
  • 49. Norma ISO 8859 International Standard Organization Conjunto de sistemas de codificação de 8 bits Regionalizado (16 tipos) 96 novos caracteres! (Agora vai) Nascimento do sistema de codificação ISO-8859-x Compatível com o ASCII por motivos óbvios
  • 50. Vamos ver os sabores!
  • 51. ISO-8859-1 Latin-1 Western Europe Um dos sitemas de codificação mais utilizados! Dinamarquês, Holandês, Inglês, Finlandês, Francês, Alemão, Italiano, Norueguês, Português, Romeno, Espanhol, Catalão e Sueco.
  • 52. ISO-8859-2 Latin-2 Central Europa Menos utilizado! Bósnio, Polonês, Croata, Tcheco, Eslovaco, Esloveno, Sér vio e Húngaro.
  • 53. ISO-8859-3 Latin-3 South Europe Menos utilizado! Turco, Maltês e Esperanto.
  • 54. ISO-8859-4 Latin-4 North Europe Menos utilizado! Difícil até de pronunciar...
  • 55. ISO-8859-5 Latin/Cyrillic ISO-8859-6 Latin/Arabic ISO-8859-7 Latin/Greek ISO-8859-8 Latin/Hebrew ISO-8859-9 Latin-5 Turkish ISO-8859-10 Latin-6 Nordic ISO-8859-11 Latin Thai ISO-8859-12 Latin Devanagari ISO-8859-13 Latin Baltic Rim ISO-8859-14 Latin Celtic ISO-8859-15 Latin-9 (Francês completo) ISO-8859-16 Latin-10 South-Eastern European
  • 57. Como ficam os japoneses nessa história?
  • 58.
  • 59. Outros sistemas de codificação utilizados principalmente pelos idiomas japonês, chinês e coreano: Big5: Chinese, Japanese and Korean Institute of Information of Taiwan 2 bytes Shift JIS: Japanese ASCII Corporation and Microsoft Entre 1 e 2 bytes
  • 60. Alguém tinha que acabar com a bagunça!
  • 61. Surgimento do Unicode Luz no fim do túnel
  • 63. Unicode Universal Character Set Publicado em 1991
  • 64. Unicode Universal Character Set Publicado em 1991 Acabar com as limitações dos sistemas de caracteres (principalmente os pertencentes a norma ISO 8859)
  • 65. Unicode Universal Character Set Publicado em 1991 Acabar com as limitações dos sistemas de caracteres (principalmente os pertencentes a norma ISO 8859) Capacidade para 1.114.112 caracteres
  • 66. Unicode Universal Character Set Publicado em 1991 Acabar com as limitações dos sistemas de caracteres (principalmente os pertencentes a norma ISO 8859) Capacidade para 1.114.112 caracteres
  • 67. Unicode Universal Character Set Publicado em 1991 Acabar com as limitações dos sistemas de caracteres (principalmente os pertencentes a norma ISO 8859) Capacidade para 1.114.112 caracteres Primeiros 256 caracteres iguais aos do ISO-8859-1 (Compatibilidade reversa)
  • 68. Unicode Universal Character Set Publicado em 1991 Acabar com as limitações dos sistemas de caracteres (principalmente os pertencentes a norma ISO 8859) Capacidade para 1.114.112 caracteres Primeiros 256 caracteres iguais aos do ISO-8859-1 (Compatibilidade reversa) Sendo assim, os 128 primeiros caracteres são iguais aos da tabela ASCII
  • 69. Version Date Scripts Caracteres Histórico de versões 1.0 1991 24 7.161 1.0.1 1992 25 28.359 1.1 1993 24 34.233 2.0 1996 25 38.950 2.1 1998 25 38.952 3.0 1999 38 49.259 3.1 2001 41 94.205 3.2 2002 45 95.221 4.0 2003 52 96.447 4.1 2005 59 97.720 5.0 2006 64 99.089 5.1 2008 75 100.713 5.2 2009 90 107.361 6.0 2010 93 109.449 6.1 2012 100 110.181
  • 70. Version Date Scripts Caracteres Histórico de versões 1.0 1991 24 7.161 1.0.1 1992 25 28.359 1.1 1993 24 34.233 2.0 1996 25 38.950 2.1 1998 25 38.952 3.0 1999 38 49.259 3.1 2001 41 94.205 3.2 2002 45 95.221 4.0 2003 52 96.447 4.1 2005 59 97.720 5.0 2006 64 99.089 5.1 2008 75 100.713 5.2 2009 90 107.361 6.0 2010 93 109.449 6.1 2012 100 110.181
  • 71. Version Date Scripts Caracteres Histórico de versões 1.0 1991 24 7.161 1.0.1 1992 25 28.359 1.1 1993 24 34.233 2.0 1996 25 38.950 2.1 1998 25 38.952 3.0 1999 38 49.259 3.1 2001 41 94.205 3.2 2002 45 95.221 4.0 2003 52 96.447 4.1 2005 59 97.720 5.0 2006 64 99.089 5.1 2008 75 100.713 5.2 2009 90 107.361 6.0 2010 93 109.449 6.1 2012 100 110.181
  • 72. Não dá pra representar o Unicode como era feito com o ASCII e o ISO-8859-1?
  • 73. O Unicode precisa ser codificado!
  • 75. Imagine a palavra Maça M -> 4D a -> 61 ç -> E7 a -> 61
  • 76. Imagine a palavra Maça M -> 4D a -> 61 ç -> E7 a -> 61 O primeiro encoding para Unicode foi o UCS-2 M a ç a 004D 0061 00E7 0061
  • 77. Imagine a palavra Maça M -> 4D a -> 61 ç -> E7 a -> 61 O primeiro encoding para Unicode foi o UCS-2 M a ç a 004D 0061 00E7 0061
  • 79. UTF-8
  • 81. UTF-8 Unicode Transformation Format Esse negócio de utilizar 2 bytes não vai rolar!
  • 82. UTF-8 Unicode Transformation Format Esse negócio de utilizar 2 bytes não vai rolar! Representação variável de 1 a 4 bytes.
  • 83. UTF-8 Unicode Transformation Format Esse negócio de utilizar 2 bytes não vai rolar! Representação variável de 1 a 4 bytes. No UTF-8 os caracteres abaixo de 128 são armazenados em apenas 1 byte.
  • 84. UTF-8 Unicode Transformation Format Esse negócio de utilizar 2 bytes não vai rolar! Representação variável de 1 a 4 bytes. No UTF-8 os caracteres abaixo de 128 são armazenados em apenas 1 byte. Compatível com o ASCII.
  • 85. UTF-8 Unicode Transformation Format Esse negócio de utilizar 2 bytes não vai rolar! Representação variável de 1 a 4 bytes. No UTF-8 os caracteres abaixo de 128 são armazenados em apenas 1 byte. Compatível com o ASCII. Formado por octetos (8-bit), por isso UTF-8.
  • 87. Imagine a palavra Maça M -> 4D a -> 61 ç -> E7 a -> 61 Codificando com UTF-8 M a ç a 4D 61 C3 A7 61
  • 88. Imagine a palavra Maça M -> 4D a -> 61 ç -> E7 a -> 61 Codificando com UTF-8 M a ç a 4D 61 C3 A7 61
  • 89.
  • 91.
  • 92. Tipo char 2 bytes
  • 93. Tipo char 2 bytes Não sinalizado
  • 94. Tipo char 2 bytes Não sinalizado Armazena valores de 0 até 65535
  • 95. Tipo char 2 bytes Não sinalizado Armazena valores de 0 até 65535 Representa um code point do Unicode
  • 96. Exibindo os caracteres e seus respectivos code points
  • 97. 1. public static void main(String args[]) { 2. String texto = “Java Magazine”; 3. for(char c : texto.toCharArray()) { 4. System.out.print(c); 5. System.out.print((int) c); 6. } 7. } Console:
  • 98. 1. public static void main(String args[]) { 2. String texto = “Java Magazine”; 3. for(char c : texto.toCharArray()) { 4. System.out.print(c); 5. System.out.print((int) c); 6. } 7. } Console: J74a97v118a97 32M77a97g103a97z122i105n110e101
  • 99. 1. public static void main(String args[]) { 2. String texto = “Java Magazine”; 3. for(char c : texto.toCharArray()) { 4. System.out.print(c); 5. System.out.print((int) c); 6. } 7. } Console: J74a97v118a97 32M77a97g103a97z122i105n110e101
  • 101. 1. public static void main(String args[]) { 2. char a = ‘a’; 3. char b = 97; 4. char c = ‘u0061’; 5. char d = 0x61; 6. System.out.print(a); 7. System.out.print(b); 8. System.out.print(c); 9. System.out.print(d); 10. } Console:
  • 102. 1. public static void main(String args[]) { 2. char a = ‘a’; 3. char b = 97; 4. char c = ‘u0061’; 5. char d = 0x61; 6. System.out.print(a); 7. System.out.print(b); 8. System.out.print(c); 9. System.out.print(d); 10. } Console: aaaa
  • 104. Exemplo Codificar a palavra “Maça” em ISO- 8859-1 e UTF-8
  • 105. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmISO = texto.getBytes(“ISO-8859-1”); 4. for(byte b : textoEmISO) { 5. System.out.print(b + “ “); 6. } 7. } Console:
  • 106. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmISO = texto.getBytes(“ISO-8859-1”); 4. for(byte b : textoEmISO) { 5. System.out.print(b + “ “); 6. } 7. } Console:
  • 107. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmISO = texto.getBytes(“ISO-8859-1”); 4. for(byte b : textoEmISO) { 5. System.out.print(b + “ “); 6. } 7. } Console: 77 97 -25 97
  • 108. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmUTF = texto.getBytes(“UTF-8”); 4. for(byte b : textoEmUTF) { 5. System.out.print(b + “ “); 6. } 7. } Console:
  • 109. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmUTF = texto.getBytes(“UTF-8”); 4. for(byte b : textoEmUTF) { 5. System.out.print(b + “ “); 6. } 7. } Console:
  • 110. 1. public static void main(String args[]) { 2. String texto = “Maça”; 3. byte[] textoEmUTF = texto.getBytes(“UTF-8”); 4. for(byte b : textoEmUTF) { 5. System.out.print(b + “ “); 6. } 7. } Console: 77 97 -61 -89 97
  • 111. 1. public byte[] encodeUTF8(String value) { 2. byte[] utf8 = new byte[bytesNeeded]; 3. // do the conversion from character code points to utf-8 4. for (int i = 0, bytes = 0; i < ch.length; i++) { 5. if (ch[i] < 0x80) { 6. utf8[bytes++] = (byte) ch[i]; 7. } else if (ch[i] < 0x0800) { 8. utf8[bytes++] = (byte) (ch[i] >> 6 | 0xC0); 9. utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80); 10. } else if (ch[i] < 0x10000) { 11. utf8[bytes++] = (byte) (ch[i] >> 12 | 0xE0); 12. utf8[bytes++] = (byte) (ch[i] >> 6 & 0x3F | 0x80); 13. utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80); 14. } else { 15. utf8[bytes++] = (byte) (ch[i] >> 18 | 0xF0); 16. utf8[bytes++] = (byte) (ch[i] >> 12 & 0x3F | 0x80); 17. utf8[bytes++] = (byte) (ch[i] >> 6 & 0x3F | 0x80); 18. utf8[bytes++] = (byte) (ch[i] & 0x3F | 0x80); 19. } 20. } 21. return utf8; 22. }
  • 113. Exemplo Decodificando os bytes da palavra “Maça” codificada em UTF-8 97 77 -61 -89 77
  • 114. 1. public static void main(String args[]) { 2. byte[] textoEmUTF = new byte[]{77,97,-61,-89,97}; 3. String texto = new String(textoEmUTF, “ISO-8859-1”); 4. System.out.println(texto); 5. } Console:
  • 115. 1. public static void main(String args[]) { 2. byte[] textoEmUTF = new byte[]{77,97,-61,-89,97}; 3. String texto = new String(textoEmUTF, “ISO-8859-1”); 4. System.out.println(texto); 5. } Console:
  • 116. 1. public static void main(String args[]) { 2. byte[] textoEmUTF = new byte[]{77,97,-61,-89,97}; 3. String texto = new String(textoEmUTF, “ISO-8859-1”); 4. System.out.println(texto); 5. } Console: Maça
  • 117. De onde vem os bytes?
  • 119. Exemplo Lendo o conteúdo de um arquivo texto
  • 120. 1. public static void main(String args[]) { 2. InputStream input = new FileInputStream(“file.txt”); 3. byte[] conteudo = new byte[input.available()]; 4. input.read(conteudo); 5. String texto = new String(conteudo, “ISO-8859-1”); 6. System.out.println(texto); 7. }
  • 121. 1. public static void main(String args[]) { 2. InputStream input = new FileInputStream(“file.txt”); 3. byte[] conteudo = new byte[input.available()]; 4. input.read(conteudo); 5. String texto = new String(conteudo, “ISO-8859-1”); 6. System.out.println(texto); 7. }
  • 122. Como saber o sistema de codificação correto?
  • 123. Exemplo Consultando uma página web por meio do protocolo HTTP
  • 124. 1. public static void main(String args[]) { 2. String url = “http://www.javamagazine.com.br”; 3. InputStream input = new URL(url).openStream(); 4. byte[] conteudo = new byte[input.available()]; 5. input.read(conteudo); 6. String html = new String(conteudo, “ISO-8859-1”); 7. System.out.println(html); 8. } Console: <html> <head> <title>DevMedia - Canal Java</title> <link rel="canonical" href="http://www.devmedia.com.br/java/" /> <link rel="shortcut icon" href="/favicon.ico"> <meta http-equiv="refresh" content="300"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> ...
  • 125. 1. public static void main(String args[]) { 2. String url = “http://www.javamagazine.com.br”; 3. InputStream input = new URL(url).openStream(); 4. byte[] conteudo = new byte[input.available()]; 5. input.read(conteudo); 6. String html = new String(conteudo, “ISO-8859-1”); 7. System.out.println(html); 8. } Console: <html> <head> <title>DevMedia - Canal Java</title> <link rel="canonical" href="http://www.devmedia.com.br/java/" /> <link rel="shortcut icon" href="/favicon.ico"> <meta http-equiv="refresh" content="300"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> ...
  • 126. Como descobrir o sistema de codificação correto?
  • 128.
  • 129.
  • 130.
  • 131. HTTP Request GET /javamagazine/ HTTP/1.1 Host: www.devmedia.com.br User-Agent: Mozilla/5.0 Gecko/20100101 Firefox/14.0.1 Accept: text/html Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate
  • 132. HTTP Response HTTP/1.1 200 OK Content-Type: text/html;charset=ISO-8859-1; Content-Encoding: gzip Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Wed, 15 Aug 2012 03:30:07 GMT
  • 133. HTTP Response HTTP/1.1 200 OK Content-Type: text/html;charset=ISO-8859-1; Content-Encoding: gzip Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Wed, 15 Aug 2012 03:30:07 GMT
  • 135. 1. @WebServlet(“/javamagazine”) 2. public class EnsaioServlet extends HttpServlet { 3. protected void doGet(HttpServletRequest req, HttpServletResponse res) { 4. String texto = “Maça”; 5. OutputStream output = response.getOutputStream(); 6. for(byte b : texto.getBytes(“ISO-8859-1”) { 7. output.write(b); 8. } 9. output.close(); 10. } 11. }
  • 136. HTTP Response HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Length: 4 Date: Sat, 18 Aug 2012 13:49:35 GMT
  • 137.
  • 138. Cada browser assume um sistema de codificação padrão
  • 139. Definindo o charset no HTTP Response
  • 140. 1. @WebServlet(“/javamagazine”) 2. public class EnsaioServlet extends HttpServlet { 3. protected void doGet(HttpServletRequest req, HttpServletResponse res) { 4. String texto = “Maça”; 5. OutputStream output = response.getOutputStream(); 6. for(byte b : texto.getBytes(“ISO-8859-1”) { 7. output.write(b); 8. } 9. output.close(); 10. } 11. }
  • 141. 1. @WebServlet(“/javamagazine”) 2. public class EnsaioServlet extends HttpServlet { 3. protected void doGet(HttpServletRequest req, HttpServletResponse res) { 4. String texto = “Maça”; 5. 6. OutputStream output = response.getOutputStream(); 7. for(byte b : texto.getBytes(“ISO-8859-1”) { 8. output.write(b); 9. } 10. output.close(); 11. } 12. }
  • 142. 1. @WebServlet(“/javamagazine”) 2. public class EnsaioServlet extends HttpServlet { 3. protected void doGet(HttpServletRequest req, HttpServletResponse res) { 4. String texto = “Maça”; 5. res.setContentType(“text/html;charset=ISO-8859-1”); 6. OutputStream output = response.getOutputStream(); 7. for(byte b : texto.getBytes(“ISO-8859-1”) { 8. output.write(b); 9. } 10. output.close(); 11. } 12. }
  • 143. Declarando a tag META no documento HTML
  • 145. Ordem de prioridade dada pelos browsers 1. Charset definido na propriedade Content-Type do cabeçalho do HTTP Response 2. Declaração da tag META com o atributo “http-equiv” no head do documento HTML 3. O atributo charset definido em elementos de importação de recursos externos como Javascript.
  • 146. Cuidado com a compilação dos arquivos fonte
  • 147. 1. public class TesteCompilacao { 2. public static void main(String[] args) { 3. String texto = “Maça”; 4. System.out.println(texto); 5. } 6. }
  • 148.
  • 149. 1. public class TesteCompilacao { 2. public static void main(String[] args) { 3. String texto = “Maça”; 4. System.out.println(texto); 5. } 6. } Console: javac TesteCompilacao.java –encoding ISO-8859-1 java TesteCompilacao Maça
  • 150. Cuidado com sistemas de codificação específicos como MacRoman e Cp1252!
  • 151. Dicas para evitar problemas de codificação • Defina um padrão na equipe • Evite sistemas de codificação específicos de um sistema operacional • Prefira o UTF-8 • Fique atento a compilação • Sempre defina o Content-Type • Declare a tag META http-equiv • Externalize as String’s • Evite resolver os problemas na base da tentativa e erro

Notas do Editor

  1. Desmistificando o Charset
  2. Palestralivre – Podemcopiarem http://www.slideshare.net/rodrigobranas
  3. Eujápasseivergonhaemapresentarcaracteresestranhos!
  4. Quemjápassouporisso?
  5. Exemplo de caracteresestranhos
  6. Qualé a forma maiscomum de resolver essetipo de problema?
  7. Resoluçãosempreenvolveciênciasesotéricas. Alterarparâmetrosquenão se sabeaocertoparaque serve, modificarimplementaçãooucriartratadoresestão entre as soluçõesmaisusadas.
  8. Tentativa e erro.Saialterandoqualquercoisaquepossua o nome charset paraqualquercoisadiferente do queestáquevaidarcerto.Nemsempre.
  9. Vamoscomeçar do início
  10. Telégrafo - 1836
  11. Nenhumainvençãorevolucionoumais o mundo de forma tãoespetacularquanto o telégrafo, capaz de levarmensagensatravés de mares e continentes.
  12. Como funciona um telégrafo?
  13. Transmissãoempulsoseletricos
  14. Como fazerparaentenderospulsoselétricos?
  15. Codigo Morse!
  16. Tabela do códigomorse
  17. Imaginemalguémna Russia, alfabetocirílico, tentando se comunicar com alguémnosestadosunidos?
  18. Seráquenaquelaépocanóstinhamosproblemas de charset? Comcerteza!
  19. Alfabetocirilico
  20. Na computaçãonãofoidiferente. Tambémestariamosreservadososmesmosproblemas.
  21. Tudoébaseadoemnúmerosbinários. Nossomeio de representaçãomudou.
  22. No início erabagunça. Cada um faz o seu.
  23. Antes de 1963, cadafabricantetinha o seupróprio charset, o quecausavaproblemas com a interoperabilidade entre diferentesfabricantes.
  24. Apenas a IBM possuia 9diferentestipos de charset
  25. Apenas a IBM possuia 9diferentestipos de charset
  26. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  27. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  28. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  29. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  30. Tabela ASCII
  31. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  32. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  33. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  34. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  35. Tabela ASCII
  36. Sentemfalta de algo? Porque 7 bits?Redução de custos!
  37. Tudobematétentarutlizar com idiomasquenãofossem o inglês
  38. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  39. Começou a sacanagemnovamente
  40. E se colocarmosmais 1 bit?
  41. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  42. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  43. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  44. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  45. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  46. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  47. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  48. Vamosverossabores
  49. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  50. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  51. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  52. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  53. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  54. O problema de certa formaaindaestavalonge de serresolvido. Com apenas 8 bits nãoépossívelrepresentar a maior parte dos idiomasorientaisquepossuemmuitosideogramasdiferentes
  55. O problema de certa formaaindaestavalonge de serresolvido. Com apenas 8 bits nãoépossívelrepresentar a maior parte dos idiomasorientaisquepossuemmuitosideogramasdiferentes
  56. A sacanagemvolta a tomarconta. E se colocarmosmais 8 bits? Charset com 16 bits. O problema da interoperabilidadeatacanovamente!
  57. Surgimento da tabelaASCII em 1963. Falar um poucosobre a história
  58. Para com essaporra!
  59. Surgimento do Unicode
  60. O queé o Unicode?
  61. O queé o Unicode?
  62. O queé o Unicode?
  63. O queé o Unicode?
  64. O queé o Unicode?
  65. O queé o Unicode?
  66. O queé o Unicode?
  67. Histórico das versões e a quantidade de code points alocados.
  68. Histórico das versões e a quantidade de code points alocados.
  69. Histórico das versões e a quantidade de code points alocados.
  70. O Unicode tem mais de 1 byte, dessa forma eleprecisa de um encoding paraserconvertidoem bytes.
  71. Como codificar o Unicode?
  72. Code points
  73. Code points
  74. Code points
  75. Code points
  76. Code points
  77. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  78. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  79. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  80. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  81. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  82. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  83. Algoritmos de codificaçãopara o Unicode. UTF e UCS
  84. Explicando o UTF. Algoritmo de codificaçãopara Unicode de tamanhovariável, porissoreduz a quantidade de espaçoocupado. UTF-8 écapaz de codificar de 1 a 4 bytes.
  85. Code points
  86. Code points
  87. Entrando no mundo do Java
  88. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  89. Como a classe String representaoscaracteres? Array de char.
  90. Detalhes do tipo char
  91. Detalhes do tipo char
  92. Detalhes do tipo char
  93. Detalhes do tipo char
  94. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  95. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  96. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  97. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  98. Formas de inicializarumavariável do tipo char
  99. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  100. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  101. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  102. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  103. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  104. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  105. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  106. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  107. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  108. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  109. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  110. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  111. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  112. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  113. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  114. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  115. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  116. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  117. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  118. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  119. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  120. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  121. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  122. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  123. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  124. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  125. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  126. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  127. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  128. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  129. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  130. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  131. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  132. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  133. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  134. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  135. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  136. Cuidado, cada browser assume um padrão
  137. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  138. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  139. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  140. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  141. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  142. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  143. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  144. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.
  145. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  146. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  147. Exemplo 1 – Extraindo o conteúdo de uma String na forma de um array de char
  148. Cuidado, cada browser assume um padrão
  149. Em Java utilizamosinstâncias da classe String paraarmazenarconteúdo.