内容

名称

Digest::MD5 - Perl 接口到 MD5 算法

概要

# Functional style
use Digest::MD5 qw(md5 md5_hex md5_base64);

$digest = md5($data);
$digest = md5_hex($data);
$digest = md5_base64($data);

# OO style
use Digest::MD5;

$ctx = Digest::MD5->new;

$ctx->add($data);
$ctx->addfile($file_handle);

$digest = $ctx->digest;
$digest = $ctx->hexdigest;
$digest = $ctx->b64digest;

描述

Digest::MD5 模块允许您在 Perl 程序中使用 RSA Data Security Inc. MD5 消息摘要算法。该算法将任意长度的消息作为输入,并将输入的 128 位“指纹”或“消息摘要”作为输出。

请注意,MD5 算法不再像以前那么强大了。自 2005 年以来,很容易生成产生相同 MD5 摘要的不同消息。生成产生给定摘要的消息似乎仍然很困难,但对于依赖摘要来唯一标识消息的应用程序,最好改用更强大的算法。

Digest::MD5 模块提供了一个过程化接口,用于简单使用,以及一个面向对象接口,该接口可以处理任意长度的消息,并且可以直接读取文件。

函数

Digest::MD5 模块提供了以下函数。默认情况下,不会导出这些函数。

md5($data,...)

此函数将连接所有参数,计算此“消息”的 MD5 摘要,并以二进制形式返回。返回的字符串长度为 16 个字节。

md5("a", "b", "c") 的结果将与 md5("abc") 的结果完全相同。

md5_hex($data,...)

与 md5() 相同,但将以十六进制形式返回摘要。返回的字符串长度为 32,且仅包含此集合中的字符:“0”..“9”和“a”..“f”。

md5_base64($data,...)

与 md5() 相同,但将摘要作为 base64 编码字符串返回。返回的字符串长度为 22,且仅包含此集合中的字符:“A”..“Z”、“a”..“z”、“0”..“9”、“+”和“/”。

请注意,返回的 base64 编码字符串未填充为 4 个字节的倍数。如果你希望与其他 base64 编码 md5 摘要互操作,则可能希望将冗余字符串“==”附加到结果中。

METHODS

本部分描述了 Digest::MD5 的面向对象接口。创建 Digest::MD5 对象后,你将向其中添加数据,最后以合适的格式请求摘要。单个对象可用于计算多个摘要。

提供了以下方法

$md5 = Digest::MD5->new

构造函数返回一个新的 Digest::MD5 对象,它封装了 MD5 消息摘要算法的状态。

如果作为实例方法调用(即 $md5->new),它将仅将对象的状态重置为新创建的对象的状态。在此情况下,不会创建新对象。

$md5->reset

这只是 $md5->new 的别名。

$md5->clone

这是 $md5 对象的副本。当你不希望破坏摘要状态,但需要摘要的中间值时,这很有用,例如在连续数据流上迭代计算摘要时。示例

    my $md5 = Digest::MD5->new;
    while (<>) {
	$md5->add($_);
	print "Line $.: ", $md5->clone->hexdigest, "\n";
    }
$md5->add($data,...)

作为参数提供的 $data 将附加到我们计算其摘要的消息中。返回值是 $md5 对象本身。

所有这些行对 $md5 对象的状态都会产生相同的影响

$md5->add("a"); $md5->add("b"); $md5->add("c");
$md5->add("a")->add("b")->add("c");
$md5->add("a", "b", "c");
$md5->add("abc");
$md5->addfile($io_handle)

$io_handle 将读取到 EOF,其内容将附加到我们计算摘要的消息中。返回值是 $md5 对象本身。

如果由于某些原因无法读取数据,addfile() 方法将 croak()。如果它 croaks,则 $md5 对象的状态将是不可预测的。在失败之前,addfile() 方法可能已经能够部分读取文件。如果发生这种情况,最好丢弃或重置 $md5 对象。

在大多数情况下,您需要确保在将 $io_handle 作为参数传递给 addfile() 方法之前,它处于 binmode 中。

$md5->add_bits($data, $nbits)
$md5->add_bits($bitstring)

由于 MD5 算法是面向字节的,因此您可能只能以 8 的倍数添加位,因此您可能只想使用 add()。提供 add_bits() 方法是为了与其他摘要实现兼容。有关 add_bits() 采用的参数的说明,请参见 Digest

$md5->digest

返回消息的二进制摘要。返回的字符串将长 16 个字节。

请注意,digest 操作实际上是一个破坏性的、一次性读取操作。一旦执行此操作,Digest::MD5 对象将自动reset,并且可以用于计算另一个摘要值。如果您想在不重置摘要状态的情况下计算摘要,请调用 $md5->clone->digest。

$md5->hexdigest

与 $md5->digest 相同,但将以十六进制形式返回摘要。返回的字符串的长度将为 32,并且它将只包含来自此集合的字符:'0'..'9' 和 'a'..'f'。

$md5->b64digest

与 $md5->digest 相同,但将摘要作为 base64 编码字符串返回。返回的字符串的长度将为 22,并且它将只包含来自此集合的字符:'A'..'Z', 'a'..'z', '0'..'9', '+' 和 '/'。

返回的 base64 编码字符串未填充为 4 个字节的倍数。如果您想与其他 base64 编码 md5 摘要互操作,您可能希望将字符串 "==" 附加到结果中。

@ctx = $md5->context
$md5->context(@ctx)

保存或恢复内部状态。当不带任何参数调用时,返回一个列表:已处理的块数、一个 16 字节的内部状态缓冲区,然后在有未处理数据的情况下最多有 63 个字节的未处理数据。当传递这些相同的参数时,恢复状态。这仅对专门操作有用。

示例

使用此库的最简单方法是导入 md5_hex() 函数(或其同类函数之一)

use Digest::MD5 qw(md5_hex);
print "Digest is ", md5_hex("foobarbaz"), "\n";

上述示例将打印出消息

Digest is 6df23dc03f9b54cc38a0fc1483df6e21

相同的校验和也可以以 OO 样式计算

use Digest::MD5;

$md5 = Digest::MD5->new;
$md5->add('foo', 'bar');
$md5->add('baz');
$digest = $md5->hexdigest;

print "Digest is $digest\n";

使用 OO 样式,您可以任意中断消息。这意味着我们不再受限于在内存中为整个消息保留空间,即我们可以处理任何大小的消息。

在计算文件的校验和时,这非常有用

use Digest::MD5;

my $filename = shift || "/etc/passwd";
open (my $fh, '<', $filename) or die "Can't open '$filename': $!";
binmode($fh);

$md5 = Digest::MD5->new;
while (<$fh>) {
    $md5->add($_);
}
close($fh);
print $md5->b64digest, " $filename\n";

或者我们可以使用 addfile 方法更有效地读取文件

use Digest::MD5;

my $filename = shift || "/etc/passwd";
open (my $fh, '<', $filename) or die "Can't open '$filename': $!";
binmode ($fh);

print Digest::MD5->new->addfile($fh)->hexdigest, " $filename\n";

由于 MD5 算法仅针对字节字符串定义,因此不能用于包含序数高于 255 的字符的字符串(Unicode 字符串)。如果您尝试向 MD5 函数和方法提供此类输入数据,它们将发出警告

use Digest::MD5 qw(md5_hex);

my $str = "abc\x{300}";
print md5_hex($str), "\n";  # croaks
# Wide character in subroutine entry

您可以计算此类字符串的 UTF-8 表示形式的 MD5 校验和。这是通过通过 encode_utf8() 函数过滤字符串来实现的

use Digest::MD5 qw(md5_hex);
use Encode qw(encode_utf8);

my $str = "abc\x{300}";
print md5_hex(encode_utf8($str)), "\n";
# 8c2d46911f3f5a326455f0ed7a8ed3b3

另请参阅

DigestDigest::MD2Digest::SHADigest::HMAC

md5sum(1)

RFC 1321

http://en.wikipedia.org/wiki/MD5

Xiaoyun Wang 和 Hongbo Yu 的论文“如何破解 MD5 和其他哈希函数”。

版权

此库是免费软件;您可以在与 Perl 本身相同的条款下重新分发和/或修改它。

Copyright 1998-2003 Gisle Aas.
Copyright 1995-1996 Neil Winton.
Copyright 1991-1992 RSA Data Security, Inc.

MD5 算法在 RFC 1321 中定义。此实现源自 RFC 1321 中的参考 C 代码,该代码受以下版权声明保护

此版权不禁止在 GNU 或 Artistic 许可条款下分发包含此扩展的任何版本的 Perl。

作者

原始MD5接口由 Neil Winton([email protected])编写。

Digest::MD5模块由 Gisle Aas <[email protected]> 编写。