<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-24218106</id><updated>2011-07-07T18:09:43.434-03:00</updated><category term='básico'/><category term='java'/><title type='text'>&lt;java/&gt;</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thingol-guj.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-24218106.post-3775372399979160495</id><published>2010-09-10T23:07:00.001-03:00</published><updated>2010-09-10T23:07:58.483-03:00</updated><title type='text'>Automatic Resource Management - Parte 2</title><content type='html'>Joe Darcy indicou hoje que conseguiu convencer o pessoal que cuida do JDBC 4.1 a aderir ao "try-with-resources". ( &lt;a href="http://blogs.sun.com/darcy/entry/project_coin_jdbc_4_1"&gt;Project Coin: JDBC 4.1 and try-with-resources&lt;/a&gt; )&lt;br /&gt;&lt;br /&gt;Portanto, será possível você fechar automaticamente uma conexão ou um ResultSet, por exemplo, usando um simples "try". Isso ainda não está disponível no build 109 do JDK 7 (o mais recente), mas estará em versões futuras. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;(Não posto ainda um exemplo; quando o build que implementar o JDBC 4.1 estiver disponivel, irei atualizar este post.)&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-3775372399979160495?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/3775372399979160495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/3775372399979160495'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/09/automatic-resource-management-parte-2.html' title='Automatic Resource Management - Parte 2'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-3948766697871213389</id><published>2010-08-16T00:28:00.000-03:00</published><updated>2010-08-16T00:28:14.749-03:00</updated><title type='text'>Java 7: Automatic Resource Management</title><content type='html'>A partir do Java 7 build 105 (disponível em http://download.java.net/jdk7/ ) é possível escrever código que feche automaticamente alguns tipos de recursos, como arquivos. A classe deve implementar a interface AutoCloseable.&lt;br /&gt;Para a especificação, consulte http://blogs.sun.com/darcy/entry/project_coin_updated_arm_spec&lt;br /&gt;Exemplo:&lt;br /&gt;&lt;pre&gt;import java.io.*;&lt;br /&gt;&lt;br /&gt;class TesteTryWithResources {&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        // Exemplo simples&lt;br /&gt;        try (PrintWriter pw = new PrintWriter ("test.txt")) {&lt;br /&gt;            pw.println ("Hello, world!");&lt;br /&gt;        } catch (FileNotFoundException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Exemplo um pouco mais complexo, que&lt;br /&gt;        // envolve 2 arquivos&lt;br /&gt;        try (BufferedOutputStream bos = new BufferedOutputStream (&lt;br /&gt;                new FileOutputStream ("copy.of.file"));&lt;br /&gt;             BufferedInputStream bis = new BufferedInputStream (&lt;br /&gt;                new FileInputStream ("original.file"))) {&lt;br /&gt;            byte[] buffer = new byte[10240];&lt;br /&gt;            for (int nBytes = bis.read (buffer); nBytes &gt; 0;&lt;br /&gt;                    nBytes = bis.read (buffer)) {&lt;br /&gt;                bos.write (buffer, 0, nBytes); &lt;br /&gt;            }&lt;br /&gt;        } catch (final FileNotFoundException | IOException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-3948766697871213389?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/3948766697871213389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/3948766697871213389'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/08/java-7-automatic-resource-management.html' title='Java 7: Automatic Resource Management'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-495490997089539121</id><published>2010-06-09T23:19:00.000-03:00</published><updated>2010-06-09T23:19:34.397-03:00</updated><title type='text'>Tratamento de exceções - Java 7</title><content type='html'>No Java 7 será possível tratar vários tipos de exceções em um mesmo bloco "catch". Isso elimina algum código repetitivo. Vou dar um exemplo com o método "verify" de java.security.cert.Certificate, que lança "apenas" 5 tipos de exceções. O método verify1 abaixo está codificado da maneira antiga (uma cláusula catch para cada tipo). O método verify2 está codificado à la Java 7, ou seja, as exceções podem ser agrupadas usando-se a sintaxe:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;catch (final Excecao1 | Excecao2 | Excecao3 ... | ExcecaoN ex)&lt;/pre&gt;&lt;br /&gt;O motivo de se exigir "final" é que a variável ex tem um tipo que é da superclasse de todas as exceções citadas, e essa variável não pode ser alterada, por exemplo, atribuindo-se a ela uma exceção de uma outra classe qualquer. Em vez disso, para simplificar, os projetistas da linguagem escolheram impor que se usasse "final". &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import java.security.PublicKey;&lt;br /&gt;import java.security.NoSuchAlgorithmException;&lt;br /&gt;import java.security.InvalidKeyException;&lt;br /&gt;import java.security.NoSuchProviderException;&lt;br /&gt;import java.security.SignatureException;&lt;br /&gt;import java.security.cert.Certificate;&lt;br /&gt;import java.security.cert.CertificateException;&lt;br /&gt;&lt;br /&gt;class TesteExcecoes {&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;// Código pré-Java 7 &lt;/pre&gt;&lt;pre&gt;public static void verify1 () {&lt;br /&gt;        Certificate cert = null;&lt;br /&gt;        PublicKey key = null;&lt;br /&gt;        &lt;br /&gt;        try {&lt;br /&gt;            cert.verify (key);&lt;br /&gt;        } catch (CertificateException ex) {&lt;br /&gt;            System.out.println ("Certificado inválido");&lt;br /&gt;        } catch (NoSuchAlgorithmException ex) {&lt;br /&gt;            System.out.println ("Não pode ocorrer");&lt;br /&gt;        } catch (InvalidKeyException ex) {&lt;br /&gt;            System.out.println ("Erro na chave ou na assinatura");&lt;br /&gt;        } catch (NoSuchProviderException ex) {&lt;br /&gt;            System.out.println ("Não pode ocorrer");&lt;br /&gt;        } catch (SignatureException ex) {&lt;br /&gt;            System.out.println ("Erro na chave ou na assinatura");&lt;br /&gt;        }&lt;br /&gt;    }&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;// Código Java 7 - note o uso de "final" e "|" &lt;/pre&gt;&lt;pre&gt;public static void verify2 () {&lt;br /&gt;        Certificate cert = null;&lt;br /&gt;        PublicKey key = null;&lt;br /&gt;        try {&lt;br /&gt;            cert.verify (key);&lt;br /&gt;        } catch (CertificateException ex) {&lt;br /&gt;            System.out.println ("Certificado inválido");&lt;br /&gt;        } catch (final NoSuchAlgorithmException | NoSuchProviderException ex) {&lt;br /&gt;            System.out.println ("Não pode ocorrer");&lt;br /&gt;        } catch (final InvalidKeyException | SignatureException ex) {&lt;br /&gt;            System.out.println ("Erro na chave ou na assinatura");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        verify1();&lt;br /&gt;        verify2();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Usei o build 95 do Java 7. Pegue o build mais recente, disponível em http://download.java.net/jdk7/ .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-495490997089539121?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/495490997089539121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/495490997089539121'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/06/tratamento-de-excecoes-java-7.html' title='Tratamento de exceções - Java 7'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-9132232946276451552</id><published>2010-03-09T14:27:00.001-03:00</published><updated>2010-03-09T14:28:29.283-03:00</updated><title type='text'>Switch com Strings no Java 7</title><content type='html'>Uma coisa que existe em quase todas as linguagens, exceto Java e C++, é a facilidade de você usar um "switch" com o tipo String. Isso será adicionado ao Java 7.&lt;br /&gt;Peço permissão ao Entanglement para postar um &lt;a href="http://www.guj.com.br/posts/list/197846.java#993081"&gt;programa&lt;/a&gt; que ele mostrou no GUJ:&lt;br /&gt;&lt;pre&gt;class TesteSwitch {&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        String s = "desprezível";&lt;br /&gt;        switch (s) {&lt;br /&gt;        case "desprezível":&lt;br /&gt;            System.out.println ("despicable"); break;&lt;br /&gt;        case "auréola":&lt;br /&gt;            System.out.println ("halo"); break;&lt;br /&gt;        case "fungo":&lt;br /&gt;            System.out.println ("fungus"); break;&lt;br /&gt;        case "fujão":&lt;br /&gt;            System.out.println ("fugitive"); break;&lt;br /&gt;        case "abstruso":&lt;br /&gt;            System.out.println ("abstruse"); break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Sendo que esse programa foi transformado pelo compilador para o equivalente a:&lt;br /&gt;&lt;pre&gt;class TesteSwitch {&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        String s = "desprezível";&lt;br /&gt;        int hashCode = s.hashCode();&lt;br /&gt;        int i = -1;&lt;br /&gt;        switch (hashCode) {&lt;br /&gt;        case -644512679: if (s.equals ("auréola")) i = 1; &lt;br /&gt;                         else if (s.equals("desprezível") i = 0; &lt;br /&gt;                         break;&lt;br /&gt;        case 97793703: if (s.equals ("fujão") i = 3; &lt;br /&gt;                       else if (s.equals("fungo") i = 2; &lt;br /&gt;                       break; &lt;br /&gt;        case 1732918561: if (s.equals ("abstruso") i = 4; &lt;br /&gt;                         break;&lt;br /&gt;        default: break;&lt;br /&gt;        }&lt;br /&gt;        switch (i) {&lt;br /&gt;        case 0: System.out.println ("despicable"); break;&lt;br /&gt;        case 1: System.out.println ("halo"); break;&lt;br /&gt;        case 2: System.out.println ("fungus"); break;&lt;br /&gt;        case 3: System.out.println ("fugitive"); break;&lt;br /&gt;        case 4: System.out.println ("abstruse"); break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;O compilador transforma 1 switch em 2, porque é mais fácil tratar de certos casos (como "fallthrough" e strings que têm exatamente o mesmo hash code). Por exemplo, no caso acima, "auréola" e "desprezível" têm o mesmo hash code, assim como "fujão" e "fungo". E é por isso que o switch checa se o hash code E a string são os mesmos do caso. Se o switch tiver muitos casos, essa implementação é mais rápida que simplesmente ir comparando com "ifs" encadeados.&lt;br /&gt;&lt;br /&gt;Obviamente, assim como no caso do "switch" com inteiros, é necessário ver se o seu problema não poderia ser resolvido com hierarquias de classes ou então com enums.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-9132232946276451552?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/9132232946276451552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/9132232946276451552'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/03/switch-com-strings-no-java-7.html' title='Switch com Strings no Java 7'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-4961674186915645806</id><published>2010-03-09T14:12:00.000-03:00</published><updated>2010-03-09T14:12:32.722-03:00</updated><title type='text'>Usando literais binários e separadores de milhar em Java 7</title><content type='html'>Em Java 7, poderemos usar números binários (embora sejam um pouco extensos), o que facilita a quem precisa codificar máscaras de bits.&lt;br /&gt;&lt;br /&gt;Além disso, uma coisa bem mais útil é que podemos agora pôr separadores de dígitos dentro de constantes numéricas.&lt;br /&gt;&lt;br /&gt;É bem mais fácil conferir pi = 3.141_592_653_589_793_238_462_643_383_279_5 em vez de 3.1415926535897932384626433832795.&lt;br /&gt;&lt;br /&gt;Entretanto, esse suporte a separadores de milhar vale só para o compilador; as rotinas (como Integer.parseInt ou DecimalFormat.parse) não entendem o "_". Isso, provavelmente, é para garantir compatibilidade com programas já existentes.&lt;br /&gt;&lt;br /&gt;Uma coisa que sempre me incomodou é que números octais são iniciados por um simples zero, tal como em C/C++. Isso é muito confuso; seria preferível que houvesse um indicador de base (como, digamos, a letra Q. Por exemplo, em vez de 0377, teríamos a constante 0Q377.). Como isso já é uma "pegadinha" antiga da linguagem, eu sugiro que se use sempre um separador, para você tomar cuidado com esse zero inicial. Em vez de usar o número 0377, deveríamos usar 0_377. Mas não sei se uma convenção dessas ajudaria muito ou não. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import java.text.*;&lt;br /&gt;&lt;br /&gt;// Requer Java 7 para ser compilada&lt;br /&gt;class NovosLiterais {&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        int cafeBabe = -889275714;&lt;br /&gt;        assert (cafeBabe == 0xCAFEBABE); // hexadecimal&lt;br /&gt;        assert (cafeBabe == 031277535276); // octal&lt;br /&gt;        // 0b introduz um número em notação binária&lt;br /&gt;        assert (cafeBabe == 0b11001010111111101011101010111110); // binário&lt;br /&gt;        // "_" separa os dígitos.&lt;br /&gt;        assert (cafeBabe == 0b1100_1010_1111_1110_1011_1010_1011_1110); // binário&lt;br /&gt;        // Pode-se usar separadores de dígitos em qualquer base&lt;br /&gt;        assert (cafeBabe == 0xCAFE_BABE);&lt;br /&gt;        assert (cafeBabe == -889_275_714);&lt;br /&gt;        assert (cafeBabe == 0_31_277_535_276);&lt;br /&gt;        // Não é preciso pôr os separadores de 3 em 3 ou de 4 em 4. &lt;br /&gt;        long cnpj = 65_497_745_0001_53L;&lt;br /&gt;        // É possível usar separadores de dígitos mesmo com números de ponto-flutuante&lt;br /&gt;        double pi = 3.141_592_653_589_793_238_462_643_383_279_5;&lt;br /&gt;        double avogadro_constant = 6.022_141_79E+23;&lt;br /&gt;        // Você não pode usar o "_" no início de uma constante, porque aí teríamos&lt;br /&gt;        // um identificador. Ele só pode ser usado dentro de uma constante.&lt;br /&gt;        double _42; // isto é um identificador, não uma constante&lt;br /&gt;        // .parseInt, .parseLong não suportam "_"&lt;br /&gt; try { &lt;br /&gt;            long x = Long.parseLong ("CAFEBABE", 16); &lt;br /&gt;            x = Long.parseLong ("CAFE_BABE", 16);&lt;br /&gt;        } catch (NumberFormatException ex) { ex.printStackTrace(); }&lt;br /&gt; try { &lt;br /&gt;            int x = Integer.parseInt ("11001010", 2); &lt;br /&gt;            x = Integer.parseInt ("1100_1010", 2);&lt;br /&gt;        } catch (NumberFormatException ex) { ex.printStackTrace(); }&lt;br /&gt;        // DecimalFormat.parse também não suporta "_"&lt;br /&gt;        NumberFormat df = DecimalFormat.getInstance();&lt;br /&gt;        try { Number n = df.parse ("123_456"); &lt;br /&gt;            System.out.println (n); // imprime "123", o que indica que ele não consegue ver além do "_"&lt;br /&gt;        }  catch (ParseException ex) { ex.printStackTrace(); }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-4961674186915645806?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/4961674186915645806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/4961674186915645806'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/03/usando-literais-binarios-e-separadores.html' title='Usando literais binários e separadores de milhar em Java 7'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-1895856858569002973</id><published>2010-03-05T20:01:00.002-03:00</published><updated>2010-03-05T20:05:03.598-03:00</updated><title type='text'>Usando &lt;&gt; em Java 7</title><content type='html'>Em Java 7 é possível agora abreviarmos a chamada a um construtor se o tipo tiver parâmetros. &lt;br /&gt;Em vez de termos de repetir todos os tipos parametrizados, é suficiente usarmos &amp;lt;&amp;gt;. Na documentação isso é chamado de "diamond" (losango), em alusão à forma do novo operador.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// Requer Java 7&lt;br /&gt;import java.util.*;&lt;br /&gt;&lt;br /&gt;class TesteNotacaoAbreviada {&lt;br /&gt;    public static void listMap (Map&amp;lt;String, String&amp;gt; map) {&lt;br /&gt;        for (Map.Entry&amp;lt;String, String&amp;gt; entry : map.entrySet()) {&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    public static void main (String[] args) {&lt;br /&gt;        // Note que não é necessário escrever "new HashMap&amp;lt;String, String&amp;gt;()"&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;Map&amp;lt;String, String&amp;gt;&lt;/span&gt; traducao =&lt;span style="color: blue;"&gt; new HashMap&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/b&gt;        // Nem aqui é preciso escrever "new TreeMap&amp;lt;String, String&amp;gt;()"&lt;br /&gt;        &lt;b&gt;traducao = &lt;span style="color: blue;"&gt;new TreeMap&amp;lt;&amp;gt;()&lt;/span&gt;;&lt;/b&gt;&lt;br /&gt;        // A notação abreviada funciona também para passagem de parâmetros, mas&lt;br /&gt;        // é bem mais difícil fazê-la funcionar adequadamente. No caso abaixo, &lt;br /&gt;        // o compilador acha que o tipo que está sendo passado é new TreeMap&amp;lt;Object,Object&amp;gt;&lt;br /&gt;        // e emite um erro de compilação. &lt;br /&gt;        &lt;b&gt;listMap (&lt;span style="color: #cc0000;"&gt;n&lt;/span&gt;&lt;span style="background-color: white; color: #cc0000;"&gt;ew TreeMap&amp;lt;&amp;gt;()&lt;/span&gt;);&lt;/b&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;span style="background-color: white;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-1895856858569002973?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/1895856858569002973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/1895856858569002973'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/03/usando-em-java-7.html' title='Usando &lt;&gt; em Java 7'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-1699631982167557309</id><published>2010-03-05T16:24:00.000-03:00</published><updated>2010-03-05T16:24:49.082-03:00</updated><title type='text'>Da série "Para eu não me esquecer mais..."</title><content type='html'>Estou tendo de usar o Compuware DevPartner Studio 9.0.1 (versão de demonstração) para resolver uns problemas de desempenho em um programa em C++, e sempre me esqueço que é necessário arranjar um arquivo chamado wcore-4.9.6658.0.zip, abri-lo, copiar o arquivo wcore.dll para o diretório C:\Program Files\Common Files\Compuware\NMShared\4.9 e reiniciar os serviços do DevPartner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-1699631982167557309?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/1699631982167557309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/1699631982167557309'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/03/da-serie-para-eu-nao-me-esquecer-mais.html' title='Da série &quot;Para eu não me esquecer mais...&quot;'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-846241480755703599</id><published>2010-03-04T14:13:00.001-03:00</published><updated>2010-03-04T14:16:00.784-03:00</updated><title type='text'>Identificadores com espaços no Java 7</title><content type='html'>Se você baixou uma versão recente do JDK 7 (veja &lt;a href="http://download.java.net/jdk7"&gt;http://download.java.net/jdk7&lt;/a&gt; ), pode tentar compilar o seguinte programa.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;b&gt;class&lt;/b&gt; #"Teste Identificadores Com Espacos" {&lt;br /&gt;    &lt;b&gt;public&lt;/b&gt; &lt;b&gt;static void main&lt;/b&gt; (#"String"[] #"argumentos de linha de comando") {&lt;br /&gt;        System.#"out".#"println" ("Os argumentos de linha de comando passados para este programa são:");&lt;br /&gt;        &lt;b&gt;for&lt;/b&gt; (#"String" #"argumento" : #"argumentos de linha de comando") {&lt;br /&gt;            System.out.printf ("%s %n", argumento); &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Isso foi introduzido pelo John Rose, um pouco "por debaixo dos panos" (já que ele é um dos committers do Sun JDK), e comunicado "after the fact" em: &lt;a href="http://wikis.sun.com/display/mlvm/ProjectCoinProposal"&gt;http://wikis.sun.com/display/mlvm/ProjectCoinProposal&lt;/a&gt;. &lt;br /&gt;Quem se lembra daqueles identificadores de colunas no SQL (que são cercados por aspas, se contiverem caracteres especiais ou espaços) vai imediatamente reconhecer a utilidade de tais identificadores malucos. O funcionamento é mais ou menos o mesmo: se houver um caracter que não for letra, número, cifrão ou "underscore" em um identificador, você pode "forçar a barra" usando o #"".&lt;br /&gt;Você pode até forçar um pouco mais a barra, e criar uma classe com um nome que é uma palavra reservada do Java.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;b&gt;class&lt;/b&gt; #"int" {&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Só que os seguintes caracteres ainda não são aceitos*, porque são importantes para a JVM distinguir pacotes, nomes de classes, arrays de objetos, e métodos construtores: &lt;br /&gt;. / ; [ ] &amp;lt; &amp;gt;&lt;br /&gt;* Segundo a especificação, bastaria usar um "\\" antes deles, mas o javac não deixa usar esses caracteres mesmo com "\\". Pois é...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-846241480755703599?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/846241480755703599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/846241480755703599'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/03/identificadores-com-espacos-no-java-7.html' title='Identificadores com espaços no Java 7'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-4943794115762674086</id><published>2010-01-12T10:44:00.000-02:00</published><updated>2010-01-12T11:26:10.538-02:00</updated><title type='text'>A classe java.util.BitSet</title><content type='html'>A classe &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/BitSet.html"&gt;java.util.BitSet&lt;/a&gt; é muito útil para alguns problemas que exigem você saber se um determinado elemento está presente ou não com rapidez e eficiência de memória.&lt;br /&gt;Em vez de usar um byte ou 4 bytes para cada elemento booleano (como você poderia esperar em um boolean[] ou então em um ArrayList&lt;boolean&gt;), BitSet usa apenas um bit.&lt;br /&gt;Infelizmente, java.util.BitSet não implementa java.util.Set nem java.util.List. Mas ela tem métodos bem interessantes, como &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/BitSet.html#cardinality%28%29"&gt;cardinality&lt;/a&gt; (que conta quantos elementos "true" existem no conjunto, mas de maneira muito eficiente), &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/BitSet.html#nextSetBit%28int%29"&gt;nextSetBit&lt;/a&gt; e &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/BitSet.html#nextClearBit%28int%29"&gt;nextClearBit&lt;/a&gt; (que procuram qual é o próximo elemento "true" ou "false" respectivamente. Em algumas versões da JVM, esses métodos também são implementados com instruções especiais do processador.&lt;br /&gt;Vou dar um exemplo de uso dessa classe, implementando o Crivo de Eratóstenes (para achar os números primos). Para simplificar, não vou efetuar a otimização de indicar no crivo apenas os números ímpares.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.util.*;&lt;br /&gt;class Sieve {&lt;br /&gt;    private BitSet bs;&lt;br /&gt;    public void findPrimes (int n) {&lt;br /&gt;        bs = new BitSet (n+1);&lt;br /&gt;        int sq = (int) Math.sqrt (n);&lt;br /&gt;        // Ao final desta rotina, todos os bits marcados serão primos, e os&lt;br /&gt;        // bits desmarcados serão números compostos.&lt;br /&gt;        bs.set (0, n - 1, true); // marcando todos os bits como primos...&lt;br /&gt;        // Agora vamos achar o primeiro bit primo, e desmarcar todos os bits&lt;br /&gt;        // que são múltiplos dele. Vamos começar por 3&lt;br /&gt;        int x = 2;&lt;br /&gt;        while (x &lt;= sq) {&lt;br /&gt;            for (int i = x + x; i &lt;= n; i += x) {&lt;br /&gt;                bs.clear (i);&lt;br /&gt;            }&lt;br /&gt;            // Devemos achar o próximo bit setado que seja maior que x&lt;br /&gt;            x = bs.nextSetBit (x + 1);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    public boolean isPrime (int n) {&lt;br /&gt;        return bs.get (n);&lt;br /&gt;    }&lt;br /&gt;    public int nextPrime (int n) {&lt;br /&gt;        return bs.nextSetBit (n + 1); // -1 se não houver um próximo&lt;br /&gt;    }&lt;br /&gt;    public long sumPrimes () {&lt;br /&gt;        int n = 1;&lt;br /&gt;        long sum = 0;&lt;br /&gt;        while ((n = bs.nextSetBit (n + 1)) &gt; 0) {&lt;br /&gt;            sum += n;&lt;br /&gt;        }&lt;br /&gt;        return sum;&lt;br /&gt;    }&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        Sieve s = new Sieve();&lt;br /&gt;        s.findPrimes (10);&lt;br /&gt;        System.out.println (s.sumPrimes());&lt;br /&gt;        s.findPrimes (100);&lt;br /&gt;        System.out.println (s.sumPrimes());&lt;br /&gt;        s.findPrimes (2000000);&lt;br /&gt;        System.out.println (s.sumPrimes());&lt;br /&gt;        long n = 600851475147L; // =  3 * 7^2 * 11 * 163 * 2279657&lt;br /&gt;        int sqrtN = (int) Math.sqrt (n);&lt;br /&gt;       &lt;br /&gt;        int factor = 2;&lt;br /&gt;        int nFactors = 0;&lt;br /&gt;        while (n &gt; 1) {&lt;br /&gt;            int exponent = 0;&lt;br /&gt;            while (n % factor == 0) {&lt;br /&gt;                exponent++;&lt;br /&gt;                n /= factor;&lt;br /&gt;            }&lt;br /&gt;            if (exponent != 0) {&lt;br /&gt;                System.out.printf ("%d^%d . ", factor, exponent);&lt;br /&gt;                nFactors++;&lt;br /&gt;            }&lt;br /&gt;            factor = s.nextPrime (factor);&lt;br /&gt;            if (factor == -1) {&lt;br /&gt;                if (n != 1)&lt;br /&gt;                    System.out.printf ("%d^%d . ", n, 1);&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        System.out.println ();&lt;br /&gt;        System.out.println (nFactors);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/boolean&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-4943794115762674086?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/4943794115762674086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/4943794115762674086'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2010/01/classe-javautilbitset.html' title='A classe java.util.BitSet'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-2599398782214795635</id><published>2008-06-06T14:22:00.000-03:00</published><updated>2008-06-06T14:32:56.941-03:00</updated><title type='text'>Ordenar palavras ignorando acentos</title><content type='html'>Volta e meia você quer ordenar palavras ignorando a caixa (minúscula/maiúscula) e os acentos e cedilhas; a reação normal é criar um método que passe tudo para minúsculas e remova acentos e cedilhas. Embora isso seja necessário às vezes, é melhor usar um recurso do Java chamado "Collators". Exemplo:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.util.*;&lt;br /&gt;import java.text.*;&lt;br /&gt;&lt;br /&gt;class ExemploCollator {&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        // Vamos comparar duas strings ignorando os acentos.&lt;br /&gt;        String st1 = &amp;quot;Gisele da Conceição Zózima Bündchen&amp;quot;;&lt;br /&gt;        String st2 = &amp;quot;Gisele da Conceicao Zozima Bundchen&amp;quot;;&lt;br /&gt;        String st3 = &amp;quot;GISELE DA CONCEICAO ZÓZIMA BUNDCHEN&amp;quot;;&lt;br /&gt;        String st4 = &amp;quot;Gisele da Conceicao Zozimo Bundchen&amp;quot;; // note que esta string é diferente&lt;br /&gt;        Collator collator = Collator.getInstance (new Locale (&amp;quot;pt&amp;quot;, &amp;quot;BR&amp;quot;));&lt;br /&gt;    collator.setStrength(Collator.PRIMARY); // importante!&lt;br /&gt;        if (collator.compare (st1, st2) == 0) {&lt;br /&gt;            System.out.println (&amp;quot;As duas Giseles são a mesma pessoa, só diferem pelos acentos&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        if (collator.compare (st1, st3) == 0) {&lt;br /&gt;            System.out.println (&amp;quot;As duas Giseles são a mesma pessoa, só diferem pelos acentos e pela diferença de &lt;br /&gt;&lt;br /&gt;caixa&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        if (collator.compare (st1, st4) != 0) {&lt;br /&gt;            System.out.println (&amp;quot;As duas Giseles não são a mesma pessoa&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Agora vamos mostrar um exemplo de ordenação ignorando os acentos.&lt;br /&gt;        String[] dados = {&lt;br /&gt;            &amp;quot;José Aparecido&amp;quot;,&lt;br /&gt;            &amp;quot;João Simões&amp;quot;,&lt;br /&gt;            &amp;quot;Jó Abedenego&amp;quot;&lt;br /&gt;        };&lt;br /&gt;        // Não usando &amp;quot;collator&amp;quot;&lt;br /&gt;        SortedSet&amp;lt;String&amp;gt; s1 = new TreeSet&amp;lt;String&amp;gt;();&lt;br /&gt;        for (String d : dados) {&lt;br /&gt;            s1.add (d);&lt;br /&gt;        }&lt;br /&gt;        // Deve imprimir [José Aparecido, João Simões, Jó Abedenego], que é &lt;br /&gt;        // ao contrário das regras da língua portuguesa&lt;br /&gt;        System.out.println (s1);&lt;br /&gt;        // Usando &amp;quot;collator&amp;quot;, segue as regras:&lt;br /&gt;        // imprime &amp;quot;[Jó Abedenego, João Simões, José Aparecido]&amp;quot;&lt;br /&gt;        final Collator coll = Collator.getInstance (new Locale (&amp;quot;pt&amp;quot;, &amp;quot;BR&amp;quot;));&lt;br /&gt;        SortedSet&amp;lt;String&amp;gt; s2 = new TreeSet&amp;lt;String&amp;gt;(new Comparator&amp;lt;String&amp;gt;() {&lt;br /&gt;            public int compare (String o1, String o2) {&lt;br /&gt;                return coll.compare (o1, o2);&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;        for (String d : dados) {&lt;br /&gt;            s2.add (d);&lt;br /&gt;        }&lt;br /&gt;        System.out.println (s2);&lt;br /&gt;        // O código abaixo é equivalente e mais simples, &lt;br /&gt;        // porque Collator implementa Comparator.&lt;br /&gt;        s2 = new TreeSet&amp;lt;String&amp;gt;(coll);&lt;br /&gt;        System.out.println (s2);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-2599398782214795635?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/2599398782214795635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/2599398782214795635'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2008/06/ordenar-palavras-ignorando-acentos.html' title='Ordenar palavras ignorando acentos'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-8809263650554747222</id><published>2008-05-30T17:17:00.000-03:00</published><updated>2008-05-30T18:23:06.398-03:00</updated><title type='text'>Criptografia RSA</title><content type='html'>Posto abaixo um programa que escrevi faz alguns anos para servir de exemplo de uso das APIs de criptografia do Java. Dei uma reformatada (com o bom e velho Eclipse) e incluí alguns javadocs. Não é o jeito "correto" de usar as APIs, mas muita gente precisa de algo parecido com isso para trabalhos de escola, portanto divirtam-se!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.FileInputStream;&lt;br /&gt;import java.io.FileOutputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.ObjectInputStream;&lt;br /&gt;import java.io.ObjectOutputStream;&lt;br /&gt;import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;import java.security.InvalidKeyException;&lt;br /&gt;import java.security.KeyPair;&lt;br /&gt;import java.security.KeyPairGenerator;&lt;br /&gt;import java.security.KeyStoreException;&lt;br /&gt;import java.security.NoSuchAlgorithmException;&lt;br /&gt;import java.security.PrivateKey;&lt;br /&gt;import java.security.PublicKey;&lt;br /&gt;import java.security.cert.CertificateException;&lt;br /&gt;import java.security.spec.RSAKeyGenParameterSpec;&lt;br /&gt;&lt;br /&gt;import javax.crypto.BadPaddingException;&lt;br /&gt;import javax.crypto.Cipher;&lt;br /&gt;import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;import javax.crypto.KeyGenerator;&lt;br /&gt;import javax.crypto.NoSuchPaddingException;&lt;br /&gt;import javax.crypto.SecretKey;&lt;br /&gt;import javax.crypto.spec.IvParameterSpec;&lt;br /&gt;import javax.crypto.spec.SecretKeySpec;&lt;br /&gt;&lt;br /&gt;// Exemplo de criptografia RSA.&lt;br /&gt;//&lt;br /&gt;// Para criptografar um bloco de dados com RSA, gera-se uma chave aleatória para&lt;br /&gt;// usar com um algoritmo simétrico (como o AES), e então criptografa-se essa chave&lt;br /&gt;// com o algoritmo RSA usando-se a chave pública do destinatário.&lt;br /&gt;//&lt;br /&gt;// Para o destinatário decifrar os dados, ele deve decifrar a chave recebida com sua&lt;br /&gt;// chave privada, e então usar a chave decifrada para decifrar os dados.&lt;br /&gt;//&lt;br /&gt;// Note que o modo correto de fazer isso é usar um formato padronizado, como o PKCS#7&lt;br /&gt;// (ou CMS), e usar o BouncyCastle. Só faço isto para exemplificar as APIs do Java.&lt;br /&gt;//&lt;br /&gt;/**&lt;br /&gt;* Efetua a parte da criptografia&lt;br /&gt;*/&lt;br /&gt;class Cifrador {&lt;br /&gt; /**&lt;br /&gt;  * Cifra um bloco de dados com a chave pública.&lt;br /&gt;  *&lt;br /&gt;  * @param pub&lt;br /&gt;  *            A chave pública.&lt;br /&gt;  * @param textoClaro&lt;br /&gt;  *            O bloco de dados a ser cifrado.&lt;br /&gt;  * @return Dois arrays de bytes, sendo que o primeiro é o bloco cifrado, e o&lt;br /&gt;  *         segundo é a chave gerada e cifrada. Não jogue fora nenhum deles.&lt;br /&gt;  * @throws NoSuchAlgorithmException&lt;br /&gt;  *             Algoritmo (AES) não disponível na sua versão do JDK.&lt;br /&gt;  * @throws NoSuchPaddingException&lt;br /&gt;  *             Padding (PKCS5Padding) não disponível na sua versão do JDK.&lt;br /&gt;  * @throws InvalidKeyException&lt;br /&gt;  *             Se a chave pública for inválida.&lt;br /&gt;  * @throws IllegalBlockSizeException&lt;br /&gt;  *             Não deve ocorrer.&lt;br /&gt;  * @throws BadPaddingException&lt;br /&gt;  *             Não deve ocorrer.&lt;br /&gt;  * @throws InvalidAlgorithmParameterException&lt;br /&gt;  *             Não deve ocorrer.&lt;br /&gt;  */&lt;br /&gt; public byte[][] cifra(PublicKey pub, byte[] textoClaro)&lt;br /&gt;   throws NoSuchAlgorithmException, NoSuchPaddingException,&lt;br /&gt;   InvalidKeyException, IllegalBlockSizeException,&lt;br /&gt;   BadPaddingException, InvalidAlgorithmParameterException {&lt;br /&gt;  byte[] textoCifrado = null;&lt;br /&gt;  byte[] chaveCifrada = null;&lt;br /&gt;&lt;br /&gt;  // -- A) Gerando uma chave simétrica de 128 bits&lt;br /&gt;  KeyGenerator kg = KeyGenerator.getInstance("AES");&lt;br /&gt;  kg.init(128);&lt;br /&gt;  SecretKey sk = kg.generateKey();&lt;br /&gt;  byte[] chave = sk.getEncoded();&lt;br /&gt;  // -- B) Cifrando o texto com a chave simétrica gerada&lt;br /&gt;  Cipher aescf = Cipher.getInstance("AES/CBC/PKCS5Padding");&lt;br /&gt;  IvParameterSpec ivspec = new IvParameterSpec(new byte[16]);&lt;br /&gt;  aescf.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(chave, "AES"),&lt;br /&gt;      ivspec);&lt;br /&gt;  textoCifrado = aescf.doFinal(textoClaro);&lt;br /&gt;  // -- C) Cifrando a chave com a chave pública&lt;br /&gt;  Cipher rsacf = Cipher.getInstance("RSA");&lt;br /&gt;  rsacf.init(Cipher.ENCRYPT_MODE, pub);&lt;br /&gt;  chaveCifrada = rsacf.doFinal(chave);&lt;br /&gt;&lt;br /&gt;  return new byte[][] { textoCifrado, chaveCifrada };&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Efetua a parte da decifração&lt;br /&gt;*/&lt;br /&gt;class Decifrador {&lt;br /&gt; /**&lt;br /&gt;  * Decifra o bloco de dados e a chave cifrada usando a chave privada do destinatário.&lt;br /&gt;  * @param pvk A chave privada.&lt;br /&gt;  * @param textoCifrado Os dados cifrados.&lt;br /&gt;  * @param chaveCifrada A chave cifrada.&lt;br /&gt;  * @return Os dados decifrados.&lt;br /&gt;  * @throws NoSuchAlgorithmException Algoritmo AES não disponível na sua versão do JDK.&lt;br /&gt;  * @throws NoSuchPaddingException PKCS5Padding não disponível na sua versão do JDK.&lt;br /&gt;  * @throws InvalidKeyException Se a chave passada for inválida.&lt;br /&gt;  * @throws IllegalBlockSizeException Não deve ocorrer.&lt;br /&gt;  * @throws BadPaddingException Se houver um erro de decifração (chave incorreta ou texto&lt;br /&gt;  * cifrado incorreto, por exemplo)&lt;br /&gt;  * @throws InvalidAlgorithmParameterException Não deve ocorrer.&lt;br /&gt;  */&lt;br /&gt; public byte[] decifra(PrivateKey pvk, byte[] textoCifrado,&lt;br /&gt;   byte[] chaveCifrada) throws NoSuchAlgorithmException,&lt;br /&gt;   NoSuchPaddingException, InvalidKeyException,&lt;br /&gt;   IllegalBlockSizeException, BadPaddingException,&lt;br /&gt;   InvalidAlgorithmParameterException {&lt;br /&gt;  byte[] textoDecifrado = null;&lt;br /&gt;&lt;br /&gt;  // -- A) Decifrando a chave simétrica com a chave privada&lt;br /&gt;  Cipher rsacf = Cipher.getInstance("RSA");&lt;br /&gt;  rsacf.init(Cipher.DECRYPT_MODE, pvk);&lt;br /&gt;  byte[] chaveDecifrada = rsacf.doFinal(chaveCifrada);&lt;br /&gt;  // -- B) Decifrando o texto com a chave simétrica decifrada&lt;br /&gt;  Cipher aescf = Cipher.getInstance("AES/CBC/PKCS5Padding");&lt;br /&gt;  IvParameterSpec ivspec = new IvParameterSpec(new byte[16]);&lt;br /&gt;  aescf.init(Cipher.DECRYPT_MODE,&lt;br /&gt;    new SecretKeySpec(chaveDecifrada, "AES"), ivspec);&lt;br /&gt;  textoDecifrado = aescf.doFinal(textoCifrado);&lt;br /&gt;&lt;br /&gt;  return textoDecifrado;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* Serve para carregar a chave pública de um arquivo. Não é o melhor jeito&lt;br /&gt;* de guardar a chave (é melhor e mais seguro usar um keystore),&lt;br /&gt;* mas faço isso só para simplificar.&lt;br /&gt;*/&lt;br /&gt;class CarregadorChavePublica {&lt;br /&gt; /**&lt;br /&gt;  * Carrega a chave pública serializada de um arquivo.&lt;br /&gt;  * @param fPub O arquivo com a chave pública serializada.&lt;br /&gt;  * @return A chave pública&lt;br /&gt;  * @throws IOException Se não achar o arquivo, ou se houver algum problema&lt;br /&gt;  * ao efetuar a des-serialização.&lt;br /&gt;  * @throws ClassNotFoundException O objeto contido no arquivo é de uma classe não presente&lt;br /&gt;  * neste projeto.&lt;br /&gt;  */&lt;br /&gt; public PublicKey carregaChavePublica(File fPub) throws IOException,&lt;br /&gt;   ClassNotFoundException {&lt;br /&gt;  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fPub));&lt;br /&gt;  PublicKey ret = (PublicKey) ois.readObject();&lt;br /&gt;  ois.close();&lt;br /&gt;  return ret;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Serve para carregar a chave privada de um arquivo. Não é o melhor jeito&lt;br /&gt;* de guardar a chave (é melhor e mais seguro usar um keystore),&lt;br /&gt;* mas faço isso só para simplificar.&lt;br /&gt;*/&lt;br /&gt;class CarregadorChavePrivada {&lt;br /&gt; /**&lt;br /&gt;  * Carrega a chave privada serializada de um arquivo.&lt;br /&gt;  * @param fPvk O arquivo com a chave privada serializada.&lt;br /&gt;  * @return A chave privada.&lt;br /&gt;  * @throws IOException Se não achar o arquivo, ou se houver algum problema&lt;br /&gt;  * @throws ClassNotFoundException O objeto contido no arquivo é de uma classe não presente&lt;br /&gt;  * neste projeto.&lt;br /&gt;  */&lt;br /&gt; public PrivateKey carregaChavePrivada(File fPvk) throws IOException,&lt;br /&gt;   ClassNotFoundException {&lt;br /&gt;  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fPvk));&lt;br /&gt;  PrivateKey ret = (PrivateKey) ois.readObject();&lt;br /&gt;  ois.close();&lt;br /&gt;  return ret;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Gera um par de chaves e as guarda em formato serializado.&lt;br /&gt;* (não é o formato mais seguro - seria melhor usar um keystore, que pode ser protegido&lt;br /&gt;* por senha), mas faço isto para simplificar a compreensão.&lt;br /&gt;*/&lt;br /&gt;class GeradorParChaves {&lt;br /&gt; private static final int RSAKEYSIZE = 1024;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Gera um par de chaves e as guarda em formato serializado em arquivos.&lt;br /&gt;  * @param fPub O arquivo que irá conter a chave pública.&lt;br /&gt;  * @param fPvk O arquivo que irá conter a chave privada.&lt;br /&gt;  * @throws IOException Problemas de acesso/gravação do arquivo.&lt;br /&gt;  * @throws NoSuchAlgorithmException RSA não disponível nesta versão do JDK.&lt;br /&gt;  * @throws InvalidAlgorithmParameterException Não deve ocorrer.&lt;br /&gt;  * @throws CertificateException Não deve ocorrer.&lt;br /&gt;  * @throws KeyStoreException Não deve ocorrer.&lt;br /&gt;  */&lt;br /&gt; public void geraParChaves(File fPub, File fPvk) throws IOException,&lt;br /&gt;   NoSuchAlgorithmException, InvalidAlgorithmParameterException,&lt;br /&gt;   CertificateException, KeyStoreException {&lt;br /&gt;&lt;br /&gt;  KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");&lt;br /&gt;  kpg.initialize(new RSAKeyGenParameterSpec(RSAKEYSIZE,&lt;br /&gt;    RSAKeyGenParameterSpec.F4));&lt;br /&gt;  KeyPair kpr = kpg.generateKeyPair();&lt;br /&gt;  PrivateKey priv = kpr.getPrivate();&lt;br /&gt;  PublicKey pub = kpr.getPublic();&lt;br /&gt;&lt;br /&gt;  // -- Gravando a chave pública em formato serializado&lt;br /&gt;  ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(&lt;br /&gt;    fPub));&lt;br /&gt;  oos.writeObject(pub);&lt;br /&gt;  oos.close();&lt;br /&gt;&lt;br /&gt;  // -- Gravando a chave privada em formato serializado&lt;br /&gt;  // -- Não é a melhor forma (deveria ser guardada em um keystore, e&lt;br /&gt;  // protegida por senha),&lt;br /&gt;  // -- mas isto é só um exemplo&lt;br /&gt;  oos = new ObjectOutputStream(new FileOutputStream(fPvk));&lt;br /&gt;  oos.writeObject(priv);&lt;br /&gt;  oos.close();&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* A classe a seguir cifra a decifra a string "Hello, world!".&lt;br /&gt;*/&lt;br /&gt;class ExemploCriptografia {&lt;br /&gt; /**&lt;br /&gt;  * Mostra um array de bytes como um "dump".&lt;br /&gt;  * @param b O array de bytes que deve ser mostrado em formato dump.&lt;br /&gt;  */&lt;br /&gt; static void printHex(byte[] b) {&lt;br /&gt;  if (b == null) {&lt;br /&gt;   System.out.println("(null)");&lt;br /&gt;  } else {&lt;br /&gt;   for (int i = 0; i &amp;lt; b.length; ++i) {&lt;br /&gt;    if (i % 16 == 0) {&lt;br /&gt;     System.out.print(Integer&lt;br /&gt;       .toHexString((i &amp;amp; 0xFFFF) | 0x10000)&lt;br /&gt;       .substring(1, 5)&lt;br /&gt;       + " - ");&lt;br /&gt;    }&lt;br /&gt;    System.out.print(Integer.toHexString((b[i] &amp;amp; 0xFF) | 0x100)&lt;br /&gt;      .substring(1, 3)&lt;br /&gt;      + " ");&lt;br /&gt;    if (i % 16 == 15 || i == b.length - 1) {&lt;br /&gt;     int j;&lt;br /&gt;     for (j = 16 - i % 16; j &amp;gt; 1; --j)&lt;br /&gt;      System.out.print("   ");&lt;br /&gt;     System.out.print(" - ");&lt;br /&gt;     int start = (i / 16) * 16;&lt;br /&gt;     int end = (b.length &amp;lt; i + 1) ? b.length : (i + 1);&lt;br /&gt;     for (j = start; j &amp;lt; end; ++j)&lt;br /&gt;      if (b[j] &amp;gt;= 32 &amp;amp;&amp;amp; b[j] &amp;lt;= 126)&lt;br /&gt;       System.out.print((char) b[j]);&lt;br /&gt;      else&lt;br /&gt;       System.out.print(".");&lt;br /&gt;     System.out.println();&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;   System.out.println();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * O programa principal&lt;br /&gt;  * @param args Os argumentos são ignorados.&lt;br /&gt;  * @throws Exception Lanço uma Exception para não poluir muito o código de demonstração&lt;br /&gt;  * com tratamento de exceções. Em um programa "de verdade" você deveria&lt;br /&gt;  * tratar corretamente as exceções.&lt;br /&gt;  */&lt;br /&gt; public static void main(String[] args) throws Exception {&lt;br /&gt;  // -- Gera o par de chaves, em dois arquivos (chave.publica e&lt;br /&gt;  // chave.privada)&lt;br /&gt;  GeradorParChaves gpc = new GeradorParChaves();&lt;br /&gt;  gpc.geraParChaves(new File("chave.publica"), new File("chave.privada"));&lt;br /&gt;&lt;br /&gt;  // -- Cifrando a mensagem "Hello, world!"&lt;br /&gt;  byte[] textoClaro = "Hello, world!".getBytes("ISO-8859-1");&lt;br /&gt;  CarregadorChavePublica ccp = new CarregadorChavePublica();&lt;br /&gt;  PublicKey pub = ccp.carregaChavePublica(new File("chave.publica"));&lt;br /&gt;  Cifrador cf = new Cifrador();&lt;br /&gt;  byte[][] cifrado = cf.cifra(pub, textoClaro);&lt;br /&gt;  printHex(cifrado[0]);&lt;br /&gt;  printHex(cifrado[1]);&lt;br /&gt;&lt;br /&gt;  // -- Decifrando a mensagem&lt;br /&gt;  CarregadorChavePrivada ccpv = new CarregadorChavePrivada();&lt;br /&gt;  PrivateKey pvk = ccpv.carregaChavePrivada(new File("chave.privada"));&lt;br /&gt;  Decifrador dcf = new Decifrador();&lt;br /&gt;  byte[] decifrado = dcf.decifra(pvk, cifrado[0], cifrado[1]);&lt;br /&gt;  // System.out.println (new String (textoClaro, "ISO-8859-1"));&lt;br /&gt;  printHex(decifrado);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-8809263650554747222?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/8809263650554747222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/8809263650554747222'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2008/05/criptografia-rsa.html' title='Criptografia RSA'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-343676249995294249</id><published>2008-05-27T10:43:00.001-03:00</published><updated>2008-05-27T11:33:04.780-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='básico'/><title type='text'>Formatação de Números</title><content type='html'>Se você deseja converter um &lt;span style="font-family: courier new;"&gt;double &lt;/span&gt;ou um &lt;span style="font-family: courier new;"&gt;BigDecimal &lt;/span&gt;de/para uma string em formato monetário - R$ 12.345.678,90 por exemplo - então use &lt;span style="font-family: courier new;"&gt;java.util.NumberFormat&lt;/span&gt; , método &lt;span style="font-family: courier new;"&gt;getCurrencyInstance&lt;/span&gt;. Isso economiza um monte de tempo tentando tirar e pôr pontos, vírgulas e outras coisas ineficientes (e que podem estar erradas também).&lt;br /&gt;Exemplo:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;pre&gt;import java.math.BigDecimal;&lt;br /&gt;import java.text.DecimalFormat;&lt;br /&gt;import java.text.NumberFormat;&lt;br /&gt;import java.text.ParseException;&lt;br /&gt;import java.util.Locale;&lt;br /&gt;&lt;br /&gt;class NumberFormatComMoeda {&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        NumberFormat nf = NumberFormat.getCurrencyInstance (new Locale ("pt", "BR"));&lt;br /&gt;        double d = 12345678.90;&lt;br /&gt;        String s = nf.&lt;span style="font-weight: bold;"&gt;format&lt;/span&gt; (d);&lt;br /&gt;        System.out.println (s); // deve imprimir "R$ 12.345.678,90"&lt;br /&gt;        // Para os que preferem double:&lt;br /&gt;        try {&lt;br /&gt;            double d1 = nf.&lt;span style="font-weight: bold;"&gt;parse&lt;/span&gt; (s).doubleValue();&lt;br /&gt;            System.out.println (d1); // imprime "1.23456789E7"&lt;br /&gt;        } catch (ParseException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;        // Para os que preferem BigDecimal:&lt;br /&gt;        ((DecimalFormat) nf).&lt;span style="font-weight: bold;"&gt;setParseBigDecimal&lt;/span&gt;(true);&lt;br /&gt;        try {&lt;br /&gt;            BigDecimal bd = (BigDecimal) (nf.parse(s));&lt;br /&gt;            System.out.println (bd); // imprime "12345678.90"&lt;br /&gt;        } catch (ParseException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-343676249995294249?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/343676249995294249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/343676249995294249'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2008/05/formatao-de-nmeros.html' title='Formatação de Números'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-5083326301921557378</id><published>2008-04-23T16:12:00.000-03:00</published><updated>2008-04-23T16:17:50.629-03:00</updated><title type='text'>Cliff Click's NonBlocking HashTable</title><content type='html'>Cliff Click has made available his new brainchild, the NonBlocking HashTable.&lt;br /&gt;&lt;br /&gt;He claims that it is faster than java.util.concurrent.ConcurrentHashMap.&lt;br /&gt;&lt;br /&gt;Check: &lt;a href="http://blogs.azulsystems.com/cliff/2007/04/nonblocking_has.html"&gt;http://blogs.azulsystems.com/cliff/2007/04/nonblocking_has.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/high-scale-lib"&gt;http://sourceforge.net/projects/high-scale-lib&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-5083326301921557378?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/5083326301921557378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/5083326301921557378'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2008/04/cliff-clicks-nonblocking-hashtable.html' title='Cliff Click&apos;s NonBlocking HashTable'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-6573723848909048975</id><published>2008-04-23T16:02:00.000-03:00</published><updated>2008-05-27T13:53:14.998-03:00</updated><title type='text'>DecimalFormat, SimpleDateFormat - Threading Issues</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: georgia;"&gt;The classes java.text.&lt;/span&gt;&lt;span style="font-weight: bold; font-family: georgia;"&gt;DecimalFormat&lt;/span&gt;&lt;span style="font-family: georgia;"&gt; and java.text.&lt;/span&gt;&lt;span style="font-weight: bold; font-family: georgia;"&gt;SimpleDateFormat &lt;/span&gt;&lt;span style="font-family: georgia;"&gt;are very useful, but Sun's implementation is not thread-safe. It means that if you want to have a static instance of any of these classes in your EJB, Servlet or JSP page, you can have sporadic problems with incorrect formatting.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: georgia;"&gt;You'll need to use a &lt;/span&gt;&lt;span style="font-weight: bold; font-family: georgia;"&gt;ThreadLocal&lt;/span&gt;&lt;span style="font-family: georgia;"&gt;, or use a local object.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: georgia;"&gt;ThreadLocal sample usage:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;pre&gt;private static ThreadLocal&lt;format&gt; defaultCurrencyFormat  = new ThreadLocal&lt;format&gt;() {&lt;br /&gt;    protected synchronized Format initialValue() {&lt;br /&gt;        return new DecimalFormat ("0.00",&lt;br /&gt;            new DecimalFormatSymbols (new Locale ("pt", "BR")));&lt;br /&gt;    }&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;String s = defaultCurrencyFormat.get().format (123.45);&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;You'll need to use an additional "get".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-6573723848909048975?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/6573723848909048975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/6573723848909048975'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2008/04/decimalformat-simpledateformat.html' title='DecimalFormat, SimpleDateFormat - Threading Issues'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-24218106.post-114306246319023496</id><published>2006-03-22T18:11:00.000-03:00</published><updated>2006-03-22T18:21:03.200-03:00</updated><title type='text'>Recommended reading for Bouncy Castle users</title><content type='html'>If you're interested in using the &lt;a href="http://www.bouncycastle.org"&gt;Bouncy Castle&lt;/a&gt; JCE Library, you'll need to check this book:&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0764596330/002-4731092-7692051?v=glance&amp;amp;n=283155"&gt;Beginning Cryptography with Java&lt;/a&gt;, by David Hook.&lt;br /&gt;&lt;br /&gt;You can download the &lt;a href="http://media.wiley.com/product_ancillary/30/07645963/DOWNLOAD/beg_crypto_examples.zip"&gt;examples&lt;/a&gt; of the book, if you just want to have a test suite for Bouncy Castle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24218106-114306246319023496?l=thingol-guj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/114306246319023496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24218106/posts/default/114306246319023496'/><link rel='alternate' type='text/html' href='http://thingol-guj.blogspot.com/2006/03/recommended-reading-for-bouncy-castle.html' title='Recommended reading for Bouncy Castle users'/><author><name>Thingol</name><uri>http://www.blogger.com/profile/05546945690981058809</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
