2008-10-20 7 views
12

Mam sytuacji, gdzie chcę, aby utworzyć podpis struktury danych:Jak utworzyć powtarzalną sygnaturę struktury danych?

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

Celem powinno być, że jeśli zmiany struktury danych wówczas tak powinien podpis.

Czy istnieje ustalony sposób na zrobienie tego?

Odpowiedz

10

Najlepszym sposobem na to jest użycie głęboko serializowanego systemu serializacji, takiego jak Storable. Dwie struktury z tymi samymi danymi wytworzą taki sam obszar roboczy, który można zapisać, aby można je było porównać.

#!/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; 

... I udowodnić odwrotność:

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

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

Musisz ustawić $ Storable :: canonical na wartość true. To może nie mieć znaczenia w małych przykładach, ale ma to znaczenie w znacznie większych. –

0

Myślę, że słowo, którego szukasz, to "hashing".

Po prostu umieszczasz strukturę danych za pomocą funkcji, która generuje z nich dość unikalną wartość. Ta wartość byłaby twoim znakiem.

16

Myślę, że to, czego szukasz, to funkcja skrótu. Polecam podejścia takiego:

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

Funkcja skrótu może być dowolna funkcja skrótu, na przykład md5 funkcji z Digest::MD5

+0

hehe. dwie praktycznie identyczne odpowiedzi w mniej niż 2 minuty. – Rik

+0

Zrób to 3 w 3 minuty! Myślę, że może to tylko oznaczać, że mamy rację ;-) –

+1

Kluczem jest $ Storable :: canonical. Bez tego, Storable nie gwarantuje porządku elementów. –

-5

Czy nie można użyć obiektu zamiast struct? W ten sposób można zobaczyć, czy obiekt jest instancją typu bez konieczności porównywania skrótów itp.

+0

Struktury danych i obiekty są w dużej mierze wymienialne w Perlu 5 - obiekty są po prostu błogosławionymi odniesieniami do danych. Tak czy siak - chcę uzyskać podpis zawartości danych – EvdB

+0

Prawdziwym problemem z tym podejściem jest to, że on szuka danych. Ponieważ dane są używane do utrzymywania stanu na obiektach, będziesz musiał utworzyć instancję nowego obiektu za każdym razem, gdy zmieni się stan, tym samym negując to podejście. – Ovid

7

Użyj Storable :: nstore, aby przekształcić go w reprezentację binarną, a następnie obliczyć sumę kontrolną (na przykład za pomocą Digest moduł).

Oba moduły to podstawowe moduły.

+0

Właśnie zmontowałem mój kod, aby to dokładnie zrobić. Ty i ja znowu jesteśmy na tym samym torze! –

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