Wie kann ich eine wiederholbare Signatur einer Datenstruktur erstellen?
-
03-07-2019 - |
Frage
Ich habe eine Situation, wo ich eine Signatur einer Datenstruktur erstellen möchten:
my $signature = ds_to_sig(
{ foo => 'bar',
baz => 'bundy',
boing => undef,
number => 1_234_567,
}
);
Das Ziel sollte sein, dass, wenn die Datenstruktur ändert dann soll so die Unterschrift.
Gibt es einen etablierten Weg, dies zu tun?
Lösung
Der beste Weg, dies zu tun, ist ein tief Struktur Serialisierung System zu verwenden, wie Storable . Zwei Strukturen mit den gleichen Daten den gleichen Blob der speicherbaren Ausgabe erzeugen, damit sie verglichen werden.
#!/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;
... Und das Inverse zu beweisen:
$one = [ 4, 5, 6 ];
$one_s = freeze $one;
print "no match" if $one_s ne $two_s;
Andere Tipps
Ich denke, was Sie suchen ist eine Hash-Funktion. Ich würde einen Ansatz wie folgt empfehlen:
use Storable;
$Storable::canonical = 1;
sub ds_to_sig {
my $structure = shift;
return hash(freeze $structure);
}
Die Hash-Funktion kann eine beliebige Hash-Funktion sein, zum Beispiel die Funktion md5 von Digest :: MD5
Verwenden Sie Storable :: nstore drehen sie in eine binäre Darstellung, und dann berechnen, eine Prüfsumme (zum Beispiel mit der Digest-Modul).
Beide Module sind Kernmodule.
Digest::MD5->new->add(
Data::Dumper->new([$structure])
->Purity(0)
->Terse(1)
->Indent(0)
->Useqq(1)
->Sortkeys(1)
->Dump()
)->b64digest();
Ich glaube, das Wort für Sie suchen ist "Hashing" .
Im Grunde setzen Sie Ihre Datenstruktur durch eine Funktion, die einen ziemlich eindeutigen Wert daraus erzeugt. Dieser Wert wäre Ihre signiture.
Können Sie nicht ein Objekt anstelle einer Struktur verwenden? Auf diese Weise konnte man sehen, ob ein Objekt eine Instanz von einem Typ ist ohne Hashes vergleichen mit, etc.