我在 c:\temp 目录下有一个名为 secure.txt 的文件。我想从命令行运行 Perl 命令以打印 secure.txt 的 SHA1 哈希值。我正在使用 ActivePerl 5.8.2。虽然我之前没有使用过 Perl,但它是目前最方便的选项。
我在 c:\temp 目录下有一个名为 secure.txt 的文件。我想从命令行运行 Perl 命令以打印 secure.txt 的 SHA1 哈希值。我正在使用 ActivePerl 5.8.2。虽然我之前没有使用过 Perl,但它是目前最方便的选项。
perl -MDigest::SHA1=sha1_hex -le "print sha1_hex <>" secure.txt
Perl的命令行选项在perlrun文档中有介绍。上面的命令从左到右依次是:
-MDigest::SHA1=sha1_hex
会在编译时加载Digest::SHA1模块并导入sha1_hex
,它以十六进制形式给出摘要。-l
自动在任何print
输出的末尾添加一个换行符。-e
引入要执行的Perl代码。奇怪的钻石符号是Perl的readline
操作符的特殊情况:
空文件句柄
<>
是特殊的:它可以用于模拟sed
和awk
的行为。来自<>
的输入既可以来自标准输入,也可以来自命令行上列出的每个文件。这是它的工作原理: 第一次评估<>
时,将检查@ARGV
数组,如果为空,则将$ARGV[0]
设置为"-"
,打开后给出标准输入。然后处理@ARGV
数组作为文件名列表。
因为secure.txt
是命令行中唯一命名的文件,所以它的内容成为了sha1_hex
的参数。
使用Perl 5.10或更高版本,您可以将上述单行命令缩短五个字符。
perl -MDigest::SHA=sha1_hex -E 'say sha1_hex<>' secure.txt
代码在所有版本的Perl中都可以省略可选的(空格)<>
,删除-l
并从-e
切换到-E
。say
,它使-l
变得不必要。
-E commandline
的行为与-e
完全相同,只是它会隐式启用所有可选功能(在主编译单元中)。参见feature
。
say FILEHANDLE LIST
say LIST
say
与print
完全相同,但会隐式附加换行符。say LIST
只是一个缩写。 { local $\ = "\n"; print LIST }
只有在启用say
功能时才能使用此关键字:请参见feature
。
如果您想将此代码放入一个方便的实用程序中,例如mysha1sum.pl
,请使用以下命令:
#! /usr/bin/perl
use warnings;
use strict;
use Digest::SHA;
die "Usage: $0 file ..\n" unless @ARGV;
foreach my $file (@ARGV) {
my $sha1 = Digest::SHA->new(1); # use 1 for SHA1, 256 for SHA256, ...
$sha1->addfile($file);
say($sha1->hexdigest, " $file");
}
这将为命令行上命名的每个文件计算一个摘要,输出格式与Unix sha1sum
实用程序兼容。
C:\> mysha1sum.pl mysha1sum.pl mysha1sum.pl
8f3a7288f1697b172820ef6be0a296560bc13bae mysha1sum.pl
8f3a7288f1697b172820ef6be0a296560bc13bae mysha1sum.pl
您并没有说您是否已经安装了Cygwin,但如果您已经安装了,sha1sum
是coreutils包的一部分。
C:\> perl -MDigest::SHA -e "print Digest::SHA->new(1)->addfile('secure.txt')->hexdigest"
截至本文撰写时,Strawberry Perl和ActiveState Perl都包含了Digest::SHA附带的shasum
命令。如果您在安装过程中选择了默认选项,则此命令已经在您的%PATH%
中。
如果您真的非常想要为Digest::SHA编写自己的包装器,那么这里的其他答案也很好。
如果您只是想要使用Perl来获取文件的SHA1哈希值,就像您已经拥有ActiveState Perl,并且它附带了shasum
命令行实用程序一样,那么只需简单地执行以下操作:
shasum secure.txt
默认的哈希算法是SHA1;如果您想要明确指定,可以添加-a1
(这不是一个坏主意)。
默认的输出格式是哈希值,两个空格,然后是文件名。这与sha1sum
和类似工具的格式相同,通常在Unix/Linux系统中找到。如果将其重定向到文件中,稍后可以将该文件名提供给shasum -c
,以验证之前已哈希的任何文件的完整性。
如果您真的,真的不想看到文件名,只想看到SHA1哈希值,可以使用以下任一方法截取文件名部分:
使用PowerShell:
shasum secure.txt | %{$_split()[0]}
使用命令提示符(老派批处理脚本):
for /f %i in ('shasum secure.txt') do echo %i
.cmd
或 .bat
文件中时,使用 %%i
而不是 %i
(两个位置都要修改)。使用 Digest::SHA1
的方法如下:
使用面向对象的策略:
#!/usr/bin/perl -w
use v5.10; # for 'say'
use strict;
require Digest::SHA1;
my $filename = 'secure.txt';
my $sha1 = Digest::SHA1->new->addfile($filename)->hexdigest;
say $sha1;
->hexdigest
会导致对象的状态清除,从而破坏它正在计算的当前摘要。此时,您可以重新使用$sha1
对象。sha1_hex
子程序:#!/usr/bin/perl -w
use strict;
use Digest::SHA1 qw/ sha1_hex /;
my $filename = "secure.txt";
# open file
open my $fhi, '<', $filename or die "Cannot open file '$filename' for reading: $!";
# slurp all the file contents
my $file_contents;
{local $/; $file_contents = <$fhi>;}
close $fhi;
print &sha1_hex($file_contents);
Digest::SHA
替代,其中 new()
接受算法作为参数(例如 SHA1 为 1,SHA256 为 256 等):require Digest::SHA;
my $sha1 = Digest::SHA->new(1)->addfile($filename)->hexdigest();
open my $in_data, '<', 'secure.txt' or die ...
- Ether
shasum
命令,如果你在安装过程中选择了默认选项,它应该已经是你的%PATH%
。如果你真的,_真的_想为Digest::SHA编写自己的包装器,那么这里的其他答案都非常好。但是,如果你宁愿使用一个“标准”Perl模块提供的命令行工具,那么请参阅我的下面的答案。 - TheDudeAbides