perl Digest add addfile 计算不同的 SHA1 摘要

标签 perl sha1 digest

perl Digest模块为 add 计算不同的 SHA1 摘要和 addfile职能。
我使用 /dev/urandom 创建了二进制随机数据

在 ubuntu 上运行

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.1 LTS
Release:        12.04
Codename:       precise

$ perl -v
This is perl 5, version 14, subversion 2 (v5.14.2) built for i686-linux-gnu-thread-multi-64int

脚本的输出
$ perl t.pl sha1 a.tmp
doesntwork      da39a3ee5e6b4b0d3255bfef95601890afd80709
works           ee49451434cffe001a568090c86f16f076677af5
$ openssl dgst -sha1 a.tmp
SHA1(a.tmp)= ee49451434cffe001a568090c86f16f076677af5

按照我的代码
use strict;
use warnings;
use Switch;
use Digest;

sub doesntwork {
    my ($datafile, $hashfun) = @_;
    open(my $fh, "<", $datafile ) or die "error: Can't open '$datafile', $!\n";
    binmode($fh);
    read($fh, my $data, -s $datafile);
    close($fh);

    $hashfun->add($data);
    my $hashval = $hashfun->digest();

    return unpack('H*', $hashval);
}

sub works {
    my ($datafile, $hashfun) = @_;
    open(my $fh, "<", $datafile ) or die "error: Can't open '$datafile', $!\n";
    binmode($fh);

    $hashfun->addfile($fh);
    my $hashval = $hashfun->digest();

    close($fh);

    return unpack('H*', $hashval);
}

###############################################################################
(@ARGV >= 2) or die "usage: perl $0 algo datafile\n";
my ($algo, $datafile) = @ARGV;

my $hashfun;
switch($algo) {
    case "md5"    {$hashfun = Digest->new("MD5"    );}
    case "sha1"   {$hashfun = Digest->new("SHA-1"  );}
    case "sha256" {$hashfun = Digest->new("SHA-256");}
    case "sha512" {$hashfun = Digest->new("SHA-512");}
    else          {die "error: invalid algorithm '$algo'\n"}
}

print "doesntwork\t", doesntwork( $datafile, $hashfun ), "\n";
print "works     \t", works     ( $datafile, $hashfun ), "\n";

我要 add函数工作,因为我想在缓冲数据上计算它,而不是从文件数据。可能add将数据视为文本,而对于 addfile , binmod在文件句柄上使它使用二进制数据,如果是这样,我该如何制作 add将缓冲区视为二进制数据。

编辑帖子以打印读取数据的大小-
    $ stat -c "%n %s" a.tmp
    a.tmp 671088640

    $ openssl dgst -sha1 a.tmp
    SHA1(a.tmp)= 7dfcced1b0c8864e6a20b2daa63de7ffc1cd7a26

    #### Works
    $ perl -W -MDigest -e 'open(my $fh, "<", "a.tmp") or die "cant open $!\n";
    > binmode($fh);
    > my $hf = Digest->new("SHA-1");
    > $hf->addfile($fh);
    > print unpack("H*", $hf->digest()),"\n";
    > close($fh);'
    7dfcced1b0c8864e6a20b2daa63de7ffc1cd7a26

    #### Doesnt Work
    $ perl -W -MDigest -e 'open(my $fh, "<", "a.tmp") or die "cant open $!\n";
    > binmode($fh);
    > read($fh, my $data, -s "a.tmp") or die "cant read $!\n";
    > close($fh);
    > printf("## data.length=%d,file.length=%d\n",length($data),-s "a.tmp");
    > length($data)==(-s "a.tmp") or die "couldnt read all the data";
    > my $hf = Digest->new("SHA-1");
    > $hf->add($data);
    > print unpack("H*", $hf->digest()),"\n";'
    ## data.length=671088640,file.length=671088640
    9eecafd368a50fb240e0388e3c84c0c94bd6cc2a

根据弗雷德的回答也试过了
    $ perl -W -MDigest -e '
    > open(my $fh, "<", "a.tmp") or die "cant open $!\n";
    > binmode($fh);
    > my $size = -s "a.tmp";
    > my $got = read($fh, my $data, $size) or die "cant read $!\n";
    > print "##read $got bytes, size=$size\n";
    > my $done = $size - $got;
    > print "done=$done, size=$size, got=$got\n";
    > until(!$done) {
    >   $got   = read($fh, my $newdata, $done);
    >   $done -= $got ;
    >   $data .= $newdata;
    >   print "##read1 $got bytes, size=$size, done=$done\n";
    > }
    > close($fh);
    > printf("## data.length=%d,file.length=%d\n",length($data),-s "a.tmp");
    > length($data)==(-s "a.tmp") or die "couldnt read all the data";
    > my $hf = Digest->new("SHA-1");
    > $hf->add($data);
    > print unpack("H*", $hf->digest()),"\n";'
    ##read 671088640 bytes, size=671088640
    done=0, size=671088640, got=671088640
    ## data.length=671088640,file.length=671088640
    9eecafd368a50fb240e0388e3c84c0c94bd6cc2a

最佳答案

您尚未提供产生问题的数据,但我无法使用 Perl 脚本作为输入来复制您的问题。

这是 addfile 的定义:

sub addfile {
    my ($self, $handle) = @_;

    my $n;
    my $buf = "";

    while (($n = read($handle, $buf, 4*1024))) {
        $self->add($buf);
    }
    unless (defined $n) {
    require Carp;
    Carp::croak("Read failed: $!");
    }

    $self;
}

您声称 addfile作品和add没有多大意义。我想在处理长字符串时模块中可能存在错误,但您更有可能将不同的输入传递给模块。

关于perl Digest add addfile 计算不同的 SHA1 摘要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21764293/

相关文章:

java - HMC SHA1 哈希 - Java 生成与 C# 不同的哈希输出

http - 每个请求的 Apache HTTP 客户端 4.3 凭据

perl - 如果要测试的模块不可用,我应该如何终止 perl 测试脚本?

perl - ffmpeg 不能从 php 脚本工作,但可以从命令行工作

java - 将加密方法从 Java 移植到 Python

c - 对于 128MB 字符串缓冲区,是否有任何校验和算法仅花费 sha1 时间的 1%?

security - HTTP 摘要认证

perl - 在 Perl 中循环字符

java - 创建 JSON 格式输出

ssl - 如何在 windows 2012R2 上为 IIS 网站制作 SHA2 CSR 文件?