quinta-feira, 3 de outubro de 2013

Como comparar JSON ou XML?

Quando se trata de comparações somos especialistas, sabemos distinguir facilmente um Fusca de uma Ferrari, mesmo se ambos forem da mesma cor, chega a ser impressionante nosso senso de observação, rs.

Comparar expressões numéricas ou texto também é simples, mas como comparar coisas mais complexas, como por exemplo dois xml´s, ou json, se estão exatamente iguais? Por incrível que pareça também é simples bastando um Hash, mas com um pequeno trabalho adicional.

Temos aqui um uso de encriptação em uma situação pouco comum e que traz resultados interessantes. Vamos a um exemplo.

Comparando Dois Textos


Em um Webpanel programamos um conteúdo tipo Json gerado no formato do tipo Messages, um SDT incluído automaticamente na Kb do Genexus.  Em seguida geramos um Hash que será utilizado para se comparar com um segundo texto que informamos livremente, e que utiliza a mesma chave e mecanismo de encriptação utilizado no primeiro texto, gerando um segundo hash.  Se forem diferentes ou iguais a respectiva mensagem será apresentada.

No primeiro teste utilizamos dois textos distintos e os valores calculados produzem resultados diferentes, (Hash e Hash2), devido aos valores em Original e Comparar Com.


Ao se copiar o conteúdo de Original , colando-o em Comparar Com, produzir-se-há hashs iguais, e o resultado será uma comparação positiva.


A programação é bem simples.

Event Start
 &message.Id    = "1"
 &message.Description  = 'Mensagem1'
 &messages.Add(&message)

 &message = new()
 &message.Id    = "2"
 &message.Description  = 'Mensagem1'
 &messages.Add(&message)

 &key=getsitekey()
 &original = &messages.ToJson()
 &hash = encrypt64(&original, &key)
Endevent


Event 'Comparar'
 &hash2 = encrypt64(&compararcom, &key)
 if &hash=&hash2
  msg('são iguais')
 else
  msg('são diferentes')
 endif
Endevent


Mais informações:


Sobre hashs tem um site bem interessante que gera encriptações com diferentes algoritmos que pode ser visto aqui.

O Xpz com o exemplo, para que você possa testar está aqui.

Duas conclusões:

  • Esse mesmo mecanismo poderia ser utilizado para comparar o conteúdo de um arquivo completo, aliás é isso que normalmente os sites sérios de download nos oferecem.
  • Qualquer pequena diferença (um espaço em branco, por exemplo) seria suficiente para tornar as duas strings diferentes.
Outra coisa que sabemos comparar com grande facilidade é a diferença de preço entre o tal Fusca e a tal Ferrari, veja como nosso senso de observação é apurado para coisas tão semelhantes...

2 comentários:

  1. Douglas, te paso algunos comentarios:

    Lo que devuelve encrypt64() no es usualmente reconocido como un hash, ya que devuelve la información encriptada (no hay pérdida de información). Un hash generalmente es el resultado de una operación mátemática y no se puede recuperar la información original.

    En principio me parece que encrypt64() es una operación "cara" para comparar strings o archivos, además de producir un string más largo que el original. Me parece que sería más óptimo comparar directamente los strings.

    Una operación mucho más "barata" sería calcular el CRC del string.
    La ventaja sería que puedo calcular una sola vez el string de referencia, guardar el resultado y utilizar muchas veces para comparar la nueva información.
    De todos modos podrían existir colisiones y si para estar seguros de que son iguales una vez que se comprueba un match, habría que comparar el texto entero para ver si efectivamente son iguales.

    ResponderExcluir
    Respostas
    1. Caro Pablo,

      Excelente suas colocações meu amigo, uma conceitual e outra técnica. Sim, temos o conceito teórico do Hash, e justamente optamos pelo encrypt64 pela sua fácil disponibilidade no Genexus, observe que não fizemos a operação decrypt64 para restaurar o valor original. Já postamos aqui um algoritmo de Hash com MD5, mas isso exigiria uma DLL externa no Ev1 e Ev2, (http://www.genexando.com/2013/06/md5-com-external-object.html) o que tornaria nosso exemplo mais difícil para todos, coisa que sempre buscamos evitar.

      Quanto ao preço, sim, com certeza aqui temos uma situação complexa, pois nossos programas web devem sempre buscar uma solução mais leve, pois temos a concentração de processamento em apenas uma única máquina (server) e muita concorrência pelos escassos recursos.

      Na verdade aqui você me deu duas idéias sensacionais, uma é discutir exatamente a questão da leveza do processamento dos scripts, já que todo mundo se preocupa apenas com a rapidez do acesso ao BD e também a discussão sobre o CRC. Que tal me ajudar a escrevê-las, rs...

      É sempre um prazer recebe-lo por aqui, grande abraço.

      Excluir