Comment créer une signature répétable d'une structure de données?
-
03-07-2019 - |
Question
Je souhaite créer la signature d'une structure de données:
my $signature = ds_to_sig(
{ foo => 'bar',
baz => 'bundy',
boing => undef,
number => 1_234_567,
}
);
L’objectif devrait être que, si la structure de données change, la signature aussi.
Existe-t-il un moyen établi de le faire?
La solution
La meilleure façon de procéder consiste à utiliser un système de sérialisation à structure profonde tel que Storable . Deux structures avec les mêmes données produiront le même blob de sortie Storable, afin de pouvoir les comparer.
#!/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;
... Et pour prouver l'inverse:
$one = [ 4, 5, 6 ];
$one_s = freeze $one;
print "no match" if $one_s ne $two_s;
Autres conseils
Je pense que vous recherchez une fonction de hachage. Je recommanderais une approche comme celle-ci:
use Storable;
$Storable::canonical = 1;
sub ds_to_sig {
my $structure = shift;
return hash(freeze $structure);
}
La fonction hash peut être toute fonction de hachage, par exemple la fonction md5 de Digest :: MD5
Utilisez Storable :: nstore pour le transformer en une représentation binaire, puis calculez somme de contrôle (par exemple avec le module Digest).
Les deux modules sont des modules de base.
Digest::MD5->new->add(
Data::Dumper->new([$structure])
->Purity(0)
->Terse(1)
->Indent(0)
->Useqq(1)
->Sortkeys(1)
->Dump()
)->b64digest();
Je pense que le mot que vous recherchez est " hachage & ; .
En gros, vous soumettez votre structure de données à une fonction qui en génère une valeur assez unique. Cette valeur serait votre signature.
Ne pouvez-vous pas utiliser un objet au lieu d'une structure? De cette façon, vous pouvez voir si un objet est une instance d'un type sans avoir à comparer des hachages, etc.