2008-10-20 14 views
12

Tengo una situación donde quiero crear una firma de una estructura de datos:¿Cómo puedo crear una firma repetible de una estructura de datos?

my $signature = ds_to_sig(
    { foo => 'bar', 
    baz => 'bundy', 
    boing => undef, 
    number => 1_234_567, 
    } 
); 

El objetivo debería ser que si los cambios en la estructura de datos a continuación, así que si la firma.

¿Existe alguna manera establecida de hacerlo?

Respuesta

10

La mejor manera de hacerlo es utilizar un sistema de serialización de estructura profunda como Storable. Dos estructuras con los mismos datos producirán la misma cantidad de salida Almacenable, por lo que se pueden comparar.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Storable ('freeze'); 

$Storable::canonical = 1; 

my $one = { foo => 42, bar => [ 1, 2, 3 ] }; 
my $two = { foo => 42, bar => [ 1, 2, 3 ] }; 

my $one_s = freeze $one; 
my $two_s = freeze $two; 

print "match\n" if $one_s eq $two_s; 

... Y para demostrar el inverso:

$one = [ 4, 5, 6 ]; 
$one_s = freeze $one; 

print "no match" if $one_s ne $two_s; 
+4

Debe establecer $ Storable :: canonical en un valor verdadero. Puede que no importe en pequeños ejemplos, pero sí en otros mucho más grandes. –

0

Creo que la palabra que estás buscando es "hashing".

Básicamente, usted pone su estructura de datos a través de una función que genera un valor bastante único de ella. Este valor sería tu firma.

16

Creo que lo que estás buscando es una función hash. Yo recomendaría un enfoque como este:

use Storable; 
$Storable::canonical = 1; 
sub ds_to_sig { 
    my $structure = shift; 
    return hash(freeze $structure); 
} 

La función hash puede ser cualquier función hash, por ejemplo, la función MD5 de Digest::MD5

+0

Jeje. dos respuestas virtualmente idénticas en menos de 2 minutos. – Rik

+0

¡Haga eso 3 en 3 minutos! Supongo que eso solo puede significar que lo tenemos bien ;-) –

+1

La clave es $ Storable :: canonical. Sin eso, Storable no garantiza el orden de los elementos. –

-5

¿No puedes usar un objeto en lugar de una estructura? De esta forma, podría ver si un objeto es una instancia de un tipo sin tener que comparar hashes, etc.

+0

las estructuras de datos y los objetos son en gran medida intercambiables en Perl 5; los objetos son realmente referencias de datos bendecidas. De cualquier manera, quiero obtener una firma de los contenidos de los datos – EvdB

+0

El verdadero problema con este enfoque es que él está detrás de los datos. Dado que los datos se utilizan para mantener el estado de los objetos, tendría que instanciar un nuevo objeto cada vez que cambia el estado, lo que anularía este enfoque. – Ovid

7

Use Storable :: nstore para convertirlo en una representación binaria y luego calcule una suma de comprobación (por ejemplo, con el Resumen módulo).

Ambos módulos son módulos principales.

+0

Acababa de editar mi código para hacer exactamente eso. ¡Tú y yo estamos en la misma pista otra vez! –

5
Digest::MD5->new->add(
    Data::Dumper->new([$structure]) 
    ->Purity(0) 
    ->Terse(1) 
    ->Indent(0) 
    ->Useqq(1) 
    ->Sortkeys(1) 
    ->Dump() 
)->b64digest(); 
Cuestiones relacionadas