segunda-feira, 29 de dezembro de 2014

Regex para validação de moeda

Olá amigos leitores. O tema do post dessa semana foi escolhido por uma necessidade que tive muito tempo atrás. Quando me deparei com o problema aplicar máscaras monetárias (R$) em campos de texto, resolvi construir uma solução própria. Poderia ter usado soluções prontas ? Sim, poderia mas, eu não queria ficar amarrado à soluções de terceiros.

Para resolver o problema, não queria criar uma função grande e de complexidade elevada sendo que, uma regex poderia lidar com esse problema. Então, vamos lá !!

A regex construída:

 ^R\$(\d{1,3}(\.\d{3})*|\d+)(\,\d{2})?$  

Esta regex aceita estes valores:
  • R$2,00
  • R$20,00
  • R$2.000,00
  • R$20.000,00
  • R$200.000,00
  • R$2.000.000,00
Mas, não aceita esses:
  • 2,00
  • 2
  • R$aaa44,00
  • B$20,00
  • $100,00
Importante: Note que o caracter usado para separar os reais dos centavos é o vírgula (,) e não o ponto (.).

Agora, vamos às partes das explicações. Vamos destrinchar a regex.

Os caracteres ^ e $, respectivamente, no início e fim da expressão regular denotam um intervalo fechado, ou seja, o texto que for avaliado só pode conter o dado monetário.

O caracter representa o próprio R do R$. Então, até aí, nenhum mistério. O $ possui significado especial nas regex, logo precisamos de uma barra de escape (\$) para que ela adote a representação de cifrão ($).

Com (\d{1,3}(\.\d{3})*|\d+) definimos que teremos ou algo desse tipo: 2.000 ou 2000. Vamos melhorar isso.

\d{1,3} -> \d representa um dígito. O {1,3} representa no mínimo 1 e no máximo 3 ocorrências. Então, quando temos \d{1,3} estamos querendo dizer que, teremos um dígito que terá no mínimo 1 e no máximo 3 ocorrências.
(....) -> Os parênteses () são usados para definir um subconjunto.
\. -> A barra de escape é usada no ponto (.) para definir o separador de milhar.
\d{3} -> Representa um dígito que será repetido três vezes.
* -> Representa que algo será repetido 0 ou infinitas vezes.
| -> Representa uma operação de ou.
\d+ -> Representa que um dígito será repetido no mínimo 1 e no máximo infinitas vezes.

Agora, que já deciframos uma parte da regex, falta a outra parte: (\,\d{2})?
Essa parte define os centavos logo, algo assim será aceito: ,00.

\, -> Caracter vírgula (,) com barra de escape para assumir a representação de vírgula.
\d{2} -> Ver explicação acima.
(....) -> Ver explicação acima.
? -> Representa que algo será repetido 0 ou 1 vez.

Agora que já esmiuçamos toda a regex, já entendemos como ela funciona e como ela aceita os valores descritos acima. É só pegar e usar.

Sugestões ? Críticas ? Elogios ? Deixe aí embaixo nos comentários ou, na página do facebook.

Página do facebook: https://www.facebook.com/precisoestudarsempre/
Leia Mais ››

terça-feira, 23 de dezembro de 2014

Listas encadeadas em Java

Olá caros leitores do blog Preciso Estudar Sempre, o tópico desta semana será sobre listas encadeadas. Escolhi esse tema porque acredito que é importante e porque não me lembro de ter falado sobre tal antes.

O conhecimento deste assunto é de grande importância no desenvolvimento de software pois, as listas encadeadas possuem uma estrutura bem diferente das listas tradicionais. Tal estrutura que pode nos ajudar em certas situações.

Antes que você se impressione com o assunto, eu já digo: "Fique tranquilo". Este tema é de fácil entendimento. Porém, é necessário de um pouco de conhecimento de programação.

Para os que já conhecem o assunto ou que já ouviram falar, já aviso que não falarei sobre listas duplamente encadeadas ou listas circulares porque senão o post ficará muito extenso e massante.

No Java, já existem estruturas prontas para listas encadeadas. Estou falando da LinkedList, clique aqui para ver a documentação. Mas, nesse post iremos criar nossa própria estrutura de lista encadeada.

Para realizar este estudo não é necessário ter uma IDE super moderna. Se você quiser usar o notepad não tem problema.

Primeiro, vamos entender o conceito das listas encadeadas. As listas tradicionais tem suas células organizadas todas juntas e posicionadas uma atrás da outra. Isso lhes garante velocidade em buscas e acesso randômico, ou seja, eu posso acessar qualquer posição que eu queira. Porém, existe uma desvantagem nesta estrutura. Quando eu preciso inserir ou remover elementos no meio da lista, o trabalho para reconstruir a lista com todos elementos é muito grande visto que, eu preciso remover os elementos que virão após o novo/removido elemento e depois recolocá-los, formando assim uma lista maior/menor.

http://voidexception.weebly.com/uploads/1/1/9/4/11944659/4652147_orig.jpg

Com as listas encadeadas não existe este problema porque suas células são organizadas de forma diferente. Nas listas tradicionais, cada elemento não tem conhecimento do próximo elemento ou do anterior porque estão todas juntas dentro da estrutura. Nas lista encadeadas, não. Cada elemento está "solto" na memória. Então, agora, você fica com aquela dúvida.

"Se os elementos estão soltos, como a lista é montada ? "

A resposta é simples, cada elemento possui uma referência somente para o próximo elemento. Como se formassem uma corrente, como se estivessem ligados (daí que vem o nome Linked List). Na figura abaixo, temos um exemplo perfeito de como é essa lista.

http://www.ime.usp.br/~pf/algoritmos/xfig/lista2a.gif

Os elos da lista são formados por ponteiros que possuem a referência para o próximo elemento. Quando não existe a referência para o próximo elemento, o ponteiro assume o valor nulo. Abaixo, temos uma relação de vantagens e desvantagens dessa estrutura.

Vantagens:
  • Linked lists são estruturas de dados dinâmicos que alocam a memória necessária enquanto o programa está funcionando.
  • Operações de inserir e deletar células (nodes) são facilmente implementadas.
  • Estruturas de dados lineares tais como, pilhas e filas são facilmente executadas com uma lista encadeada.
  • Eles podem reduzir o tempo de acesso e podem aumentar em tempo real sem overhead de memória.
Desvantagens:
  • Tem tendência de desperdiçar memória pelo fato dos ponteiros pediram novo espaço de armazenamento.
  • Nós em uma lista encadeada devem ser lidos do início.
  • Dificuldades surgem em listas encadeadas quando se tente percorrê-la de trás para frente. Tal tarefa é extremamente complicado. Adicionar um backpointer (ponteiro de ré) causa desperdício de memória.
Agora que já sabemos como a lista encadeada funciona, vamos ao exemplo prático. Nós criaremos uma lista encadeada que representa uma escala de indicação de empregos, ou seja, uma pessoa indica a outra para uma vaga de emprego mas, ela só pode indicar 1 pessoa e só conhece a pessoa que indicou.

Crie a classe Pessoa. Esta classe representa a pessoa.

 package pkg;  

 public class Pessoa { 
      private Integer id; 
      private String nome; 
      private String email; 
      public Pessoa() { 

      } 

      public Pessoa(Integer id, String nome, String email) { 
           this.id = id; 
           this.nome = nome; 
           this.email = email; 
      } 

      public Integer getId() { 
           return id; 
      } 

      public void setId(Integer id) { 
           this.id = id; 
      } 

      public String getNome() { 
           return nome; 
      } 

      public void setNome(String nome) { 
           this.nome = nome; 
      } 

      public String getEmail() { 
           return email; 
      } 

      public void setEmail(String email) { 
           this.email = email; 
      } 

      @Override 
      public String toString() { 
           return "Pessoa [id=" + id + ", nome=" + nome + ", email=" + email + "]"; 
      } 
 } 

Crie a classe Celula. Esta classe representa a célula (posição ou node) da lista. Como vimos acima, cada célula precisa da referência do próximo e isso é feito através do atributo proximo.

 package pkg;  

 public class Celula { 
      private Celula proximo; 
      private Pessoa valor; 
      public Celula getProximo() { 
           return proximo; 
      } 

      public void setProximo(Celula proximo) { 
           this.proximo = proximo; 
      } 

      public Pessoa getValor() { 
           return valor; 
      } 

      public void setValor(Pessoa valor) { 
           this.valor = valor; 
      } 
 } 

Crie a classe ListaEncadeada. Esta classe representa a lista encadeada. Note que ela não guarda suas células em nenhum tipo de array ou vetor. As únicas referências que ela tem para suas células são os atributos primeiro e ultimo. A partir deste dois atributos, será realizada as operações na lista. O atributo posicaoAtual é usado para as operações iteração e recuperação do objeto do laço.

 package pkg;  
 public class ListaEncadeada { 
      private Celula primeiro; 
      private Celula ultimo; 
      private Celula posicaoAtual; 
      /** 
       * Adiciona uma pessoa no fim da lista. 
       * @param valor 
       */ 
      public void adicionar(Pessoa valor){ 
           Celula celula = new Celula(); 
           celula.setValor(valor); 
           if(primeiro == null && ultimo == null){ 
                primeiro = celula; 
                ultimo = celula; 
           } else { 
                ultimo.setProximo(celula); 
                ultimo = celula; 
           } 
      } 
      /** 
       * Remove uma pessoa do fim da lista. 
       */ 
      public void remover(){ 
           if(primeiro.getProximo() != null){ 
                Celula celula = this.recuperarPenultimo(this.primeiro); 
                ultimo = celula; 
                celula.setProximo(null); 
           } else { 
                primeiro = ultimo = null; 
           } 
      } 
      /** 
       * Recupera o penultimo elemento da lista 
       * @param celula 
       * @return 
       */ 
      private Celula recuperarPenultimo(Celula celula){ 
           if(celula.getProximo().equals(ultimo)){ 
                return celula; 
           } 
           return recuperarPenultimo(celula.getProximo()); 
      } 
      public boolean temProximo(){ 
           if(primeiro == null){ 
                return false; 
           } else if (posicaoAtual == null){ 
                posicaoAtual = primeiro; 
                return true; 
           } else { 
                boolean temProximo = posicaoAtual.getProximo() != null ? true : false; 
                posicaoAtual = posicaoAtual.getProximo(); 
                return temProximo; 
           } 
      } 
      public Celula getPosicaoAtual(){ 
           return this.posicaoAtual; 
      } 
 } 

Agora, crie a classe Principal. Esta classe contém o método main e a partir dele, chamamos os método da lista.

 package pkg;  
 public class Principal { 
      public static void main(String[] args) { 
           ListaEncadeada listaEncadeada = new ListaEncadeada(); 
           Principal principal = new Principal(); 
           principal.adicionarPessoa(listaEncadeada); 
           principal.remover(listaEncadeada); 
           while(listaEncadeada.temProximo()){ 
                System.out.println(listaEncadeada.getPosicaoAtual().getValor()); 
           } 
      } 
      private void adicionarPessoa(ListaEncadeada listaEncadeada){ 
           Pessoa p1 = new Pessoa(1, "João", "jp@gmail.com"); 
           Pessoa p2 = new Pessoa(2, "Maria", "maria@gmail.com"); 
           Pessoa p3 = new Pessoa(3, "Bruno", "bruno@gmail.com"); 
           Pessoa p4 = new Pessoa(4, "José", "jose@gmail.com"); 
           Pessoa p5 = new Pessoa(5, "Mário", "mario@gmail.com"); 
           Pessoa p6 = new Pessoa(6, "Eduardo", "dudu@gmail.com"); 
           listaEncadeada.adicionar(p1); 
           listaEncadeada.adicionar(p2); 
           listaEncadeada.adicionar(p3); 
           listaEncadeada.adicionar(p4); 
           listaEncadeada.adicionar(p5); 
           listaEncadeada.adicionar(p6); 
      } 
      private void remover(ListaEncadeada listaEncadeada){ 
           listaEncadeada.remover(); 
           listaEncadeada.remover(); 
           listaEncadeada.remover(); 
      } 
 } 

Não entrei muito a fundo nas operações que são possíveis realizar em uma lista encadeada porque, eu ficaria um mês todo escrevendo este post e no fim disponibilizaria uma API muito extensa. O meu intuito com esse post é apenas dar um guia introdutório do assunto visando, dar insumos suficientes para que os leitores possa andar "pelas suas próprias pernas".

Para baixar o projeto completo, clique aqui.

Sugestões ? Críticas ? Elogios ? Deixe aí nos comentários ou na página do facebook.

https://www.facebook.com/precisoestudarsempre/

Referências:
http://www.ime.usp.br/~pf/algoritmos/aulas/lista.html
http://en.wikipedia.org/wiki/Linked_list
http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
Leia Mais ››

quarta-feira, 17 de dezembro de 2014

Entendendo o SMTP

Eu sempre tive bastante dúvida sobre esse assunto. Como funcionam os protocolos de email ? Como a troca de mensagens é realizada ? Na faculdade, esse tema é abordado mas, de uma forma muito superficial logo, isso não me deixou satisfeito.

Então, o post dessa semana será: "Entendendo o SMTP".

Acredito que a melhor fonte de pesquisa para este assunto seja sua RFC (Request for Comment), a RFC 5321.

De acordo com a RFC, para realizar uma transferência de mensagem para um servidor SMTP, um SMTP client estabelece uma canal de transmissão de duas vias para um servidor. Um SMTP client determina o endereço de um determinado servidor SMTP pela resolução de um domínio de destino para um servidor de Mail eXchanger ou um servidor final.

Um servidor SMTP pode ser ou o destino final ou um destino intermediário (pode assumir o papel de um SMTP client após receber a mensagem) ou um gateway (pode transportar a mensagem à frente usando algum protocolo diferente do SMTP). Os comandos SMTP são gerados pelo SMTP Client e enviados ao servidor SMTP. Respostas SMTP são enviadas do servidor para o cliente em resposta aos comandos.


Em outras palavras, transferência de mensagens podem ocorrer em uma única conexão entre o original SMTP-remetente e o final SMTP-destinário, ou podem ocorrer em uma série de pulos através de sistemas intermediários. Em outros casos, uma vez que o servidor publicou uma resposta de sucesso no fim do dado da mensagem, uma transferência de responsabilidade pela mensagem ocorre: o protocolo requer que o servidor deve aceitar a responsabilidade de também entregar mensagem ou reportar apropriadamente a falha da entrega, caso ocorra (veja seções 6.1, 6.2 e 7.8 da RFC).

Uma vez que o canal de transmissão foi estabelecido e o inicial handshaking é feito, o SMTP Client, normalmente, inicia uma transação de mensagem. Tal transação consiste em um série de comandos para especificar o remetente e destinatário da mensagem e transmissão do conteúdo da mesma (incluindo qualquer linha na seção de cabeçalho ou outra estrutura). Quando a mesma mensagem é enviada para vários recipientes, este protocolo encoraja a transmissão de uma única cópia dos dados para todos os recipientes do mesmo servidor de destino (ou servidor retransmissor intermediário).

O servidor responde com uma resposta para cada comando. Respostas podem indicar que o comando foi aceito, que comandos adicionais são esperados, ou que um condição de erro temporário ou permanente existe. Comandos que especifiquem o remetente ou recipientes pode incluir requisições de extensão de serviço SMTP server-permitted (ver seção 2.2 da RFC). O diálogo é propositalmente lock-step (trava e faço), one-at-a-time (um de cada vez), embora isso possa ser modificado por um acordo mútuo a partir de requisições de extensão tais como comandos de pipelining.

Uma vez que dada mensagem foi transmitida, o client pode ou pedir que a conexão seja encerrada ou iniciar outra transação. Mais adiante, um SMTP Client pode usar uma conexão para um servidor SMTP para serviços auxiliares tais como verificação de endereços de email ou recuperação de endereços dos participantes da mailing list.

Como dito acima, este protocolo provê mecanismos para a transmissão de mensagens. Historicamente, esta transmissão normalmente ocorria diretamente do servidor remetente para o servidor destinatário quando os dois estavam conectados ao mesmo serviço de transporte. Quando eles não estão conectados ao mesmo serviço de transporte, a transmissão ocorre via um ou mais servidor de retransmissão SMTP. Um caso muito comum na internet, atualmente, envolve submissão da mensagem original para um intermediário, servidor de submissão de mensagem, o qual é similar a uma retransmissão mas possui algumas propriedades adicionais. Um servidor intermediário que atue como ou um retransmissor SMTP ou como um gateway em alguns ambientes de transmissão é geralmente selecionado através do uso do mecanismo Mail eXchanger DNS.

É isso galera, espero ter trazido este conteúdo da RFC de forma bem clara e explicativa.

Dúvidas, sugestões ou críticas ? Deixe aí embaixo nos comentários ou pelo facebook do Preciso Estudar Sempre.

https://www.facebook.com/precisoestudarsempre/
   

Referência: http://tools.ietf.org/html/rfc5321#page-7
Leia Mais ››

quinta-feira, 4 de dezembro de 2014

Entendendo o SSL

Este assunto sempre me deixou bastante intrigado pois, eu sempre me perguntava o que era aquele https, na barra de endereço do meu browser. Então, decidi criar esse post para que, as pessoas possam ter um entendimento maior sobre esse assunto.

Hoje, nossa "aulinha" será mais teórica. Então, você que está ávido por alguma classe Java ou algum SQL, se acalme por favor. É importante citar que, para que você possa entender o assunto abordado, é de extrema necessidade que você entenda a arquitetura cliente-servidor.

Caso não conheça, clique aqui e leia sobre o assunto.

Na minha incansável procura pelo significado do https, notei que sera sempre levado pelas minhas fontes para textos que abordavam o protocolo de segurança SSL. Então, concluí que, eu precisava primeiro aprender mais sobre o protocolo para assim, entender consequentemente o que significa o tal https.

O SSL, abreviação para Secured Socket Layer, é um protocolo de segurança, conforme dito acima, que permite que aplicativos cliente/servidor possam trocar informações em total segurança, protegendo a integridade e a veracidade do conteúdo que trafega na Internet. Tal segurança só é possível através da autenticação das partes envolvidas na troca de informações.

Seu funcionamento é bastante simples. Quando você abre seu browser, digita algum site na barra de endereço e aperta Enter, uma requisição de acesso é realizada. Essa requisição verifica se existe algum certificado digital. Caso exista, é solicitado o envio deste certificado (tome como idéia este certificado como se fosse um documento de identidade). Após recebido é verificado se o certificado é confiável, válido e se está relacionado com o site que o enviou.

Caso o certificado seja confiável, uma chave pública é enviada pelo browser para o servidor. No momento que esta chave é recebida, o servidor compara a chave pública com sua chave particular. Caso sejam compatíveis, uma comunicação segura é iniciada. Uma mensagem que tenha sido criptografada com uma chave pública somente poderá ser decifrada com a sua chave privada (simétrica) correspondente.

A imagem abaixo foi retirada deste link e exemplifica bem o que estou dizendo. Com ela é possível um total entendimento de como o SSL funciona entre o browser e o servidor.


Agora sabemos o que se trata o nosso https, ele é nada mais, nada menos que uma requisição http segura onde, o s significa secured.

Espero ter ajudado e esclarecido este conceito na mente de vocês.

Sugestões ? Críticas ? Melhorias ? Deixe aí embaixo nos comentários ou comente também na página do facebook.

Preciso Estudar Sempre: https://www.facebook.com/precisoestudarsempre/

Referências:
http://www.techtudo.com.br/artigos/noticia/2012/01/o-que-e-ssl.html
http://www.tecmundo.com.br/seguranca/1896-o-que-e-ssl-.htm
http://www.webopedia.com/TERM/S/SSL.html
Leia Mais ››