如何创建数据结构的可重复签名?

Evd*_*vdB 12 perl signature data-structures

我有一种情况,我想创建一个数据结构的签名:

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

目标应该是,如果数据结构发生变化,则签名也应如此.

有没有确定的方法来做到这一点?

Leo*_*ans 16

我认为你要找的是哈希函数.我会推荐这样的方法:

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

函数散列可以是任何散列函数,例如来自Digest :: MD5的函数md5


fri*_*edo 10

最好的方法是使用像Storable这样的深层结构序列化系统.具有相同数据的两个结构将产生相同的可存储输出blob,因此可以对它们进行比较.

#!/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;
Run Code Online (Sandbox Code Playgroud)

......并证明相反:

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

print "no match" if $one_s ne $two_s;
Run Code Online (Sandbox Code Playgroud)

  • 您需要将$ Storable :: canonical设置为true值.在小例子中它可能并不重要,但它在更大的例子中很重要. (4认同)

mor*_*itz 7

使用Storable :: nstore将其转换为二进制表示形式,然后计算校验和(例如使用Digest模块).

两个模块都是核心模块.


小智 5

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