如何使用 Perl 从 Windows 命令行获取文件的 SHA1 哈希?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2812153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:26:36  来源:igfitidea点击:

How can I use Perl to get a SHA1 hash of a file from the Windows command line?

windowsperlcommand-linesha1

提问by Jim

I have a file called secure.txtin c:\temp. I want to run a Perl command from the command line to print the SHA1 hash of secure.txt. I'm using ActivePerl 5.8.2. I have not used Perl before, but it's the most convenient option available right now.

我在c:\temp 中有一个名为secure.txt的文件。我想从命令行运行 Perl 命令来打印secure.txt的 SHA1 哈希值。我正在使用 ActivePerl 5.8.2。我以前没有使用过 Perl,但它是目前可用的最方便的选项。

回答by Greg Bacon

perl -MDigest::SHA1=sha1_hex -le "print sha1_hex <>" secure.txt

The command-line options to Perl are documented in perlrun. Going from left to right in the above command:

Perl 的命令行选项记录在perlrun 中。在上面的命令中从左到右:

  • -MDigest::SHA1=sha1_hexloads the Digest::SHA1module at compile time and imports sha1_hex, which gives the digest in hexadecimal form.
  • -lautomatically adds a newline to the end of any print
  • -eintroduces Perl code to be executed
  • -MDigest::SHA1=sha1_hex在编译时加载Digest::SHA1模块并导入sha1_hex,它以十六进制形式给出摘要。
  • -l自动在任何末尾添加换行符 print
  • -e介绍要执行的 Perl 代码

The funny-looking diamond is a special case of Perl's readlineoperator:

看起来很有趣的菱形是 Perlreadline运算符的一个特例:

The null filehandle <>is special: it can be used to emulate the behavior of sedand awk. Input from <>comes either from standard input, or from each file listed on the command line. Here's how it works: the first time <>is evaluated, the @ARGVarray is checked, and if it is empty, $ARGV[0]is set to "-", which when opened gives you standard input. The @ARGVarray is then processed as a list of filenames.

空文件句柄<>是特殊的:它可以用来模仿的行为sedawk。输入来自<>标准输入或命令行上列出的每个文件。这是它的工作原理:第一次<>计算时,@ARGV检查数组,如果它为空,$ARGV[0]则设置为"-",打开时为您提供标准输入。@ARGV然后将该数组作为文件名列表进行处理。

Because secure.txtis the only file named on the command line, its contents become the argument to sha1_hex.

因为secure.txt是命令行上命名的唯一文件,所以它的内容成为sha1_hex.

With Perl version 5.10 or later, you can shorten the above one-liner by five characters.

使用 Perl 5.10 或更高版本,您可以将上述一行代码缩短五个字符。

perl -MDigest::SHA=sha1_hex -E 'say sha1_hex<>' secure.txt

The code drops the optional (with all versions of Perl) whitespace before <>, drops -l, and switches from -eto -E.

代码删除了之前的可选(所有版本的 Perl)空格<>,删除-l并从 切换-e-E

  • -E commandline

    behaves just like -e, except that it implicitly enables all optional features (in the main compilation unit). See feature.

  • -E commandline

    行为就像-e,除了它隐式启用所有可选功能(在主编译单元中)。见feature

One of those optional features is say, which makes -lunnecessary.

这些可选功能之一是say,这使得-l不必要。

  • say FILEHANDLE LIST
  • say LIST
  • say

    Just like print, but implicitly appends a newline. say LISTis simply an abbreviation for

    { local $\ = "\n"; print LIST }
    

    This keyword is only available when the sayfeature is enabled: see feature.

  • say FILEHANDLE LIST
  • say LIST
  • say

    就像print,但隐式附加一个换行符。say LIST只是一个缩写

    { local $\ = "\n"; print LIST }
    

    此关键字仅在say启用该功能时可用:请参阅feature

If you'd like to have this code in a convenient utility, say mysha1sum.pl, then use

如果您想在方便的实用程序中mysha1sum.pl使用此代码,例如,然后使用

#! /usr/bin/perl

use warnings;
use strict;

use Digest::SHA1;

die "Usage: 
C:\> mysha1sum.pl mysha1sum.pl mysha1sum.pl 
8f3a7288f1697b172820ef6be0a296560bc13bae  mysha1sum.pl
8f3a7288f1697b172820ef6be0a296560bc13bae  mysha1sum.pl
file ..\n" unless @ARGV; foreach my $file (@ARGV) { my $fh; unless (open $fh, $file) { warn "
C:\> perl -MDigest::SHA -e "print Digest::SHA->new(1)->addfile('secure.txt')->hexdigest"
: open $file: $!"; next; } my $sha1 = Digest::SHA1->new; $sha1->addfile($fh); print $sha1->hexdigest, " $file\n"; close $fh; }

This will compute a digest for each file named on the command line, and the output format is compatible with that of the Unix sha1sumutility.

这将为命令行上命名的每个文件计算一个摘要,并且输出格式与 Unixsha1sum实用程序的格式兼容。

shasum secure.txt

You didn't say whether you have Cygwin installed, but if you do, sha1sumis part of the coreutils package.

您没有说是否安装了 Cygwin,但如果安装了,它sha1sum就是 coreutils 包的一部分。

回答by Robert Wohlfarth

Try the Digest::SHAmodule.

试试Digest::SHA模块。

shasum secure.txt | %{$_split()[0]}

回答by TheDudeAbides

As of this writing, both Strawberry Perland ActiveState Perlinclude the shasumcommand that comes with Digest::SHA. If you chose the default options during setup, this will already be in your %PATH%.

在撰写本文时,Strawberry PerlActiveState Perlshasum都包含Digest::SHA附带的命令。如果您在安装过程中选择了默认选项,这将已经在您的%PATH%.

If you really, really wantto write your own wrapper for Digest::SHA, the other answers here are great.

如果您真的非常为 Digest::SHA 编写自己的包装器,那么这里的其他答案都很棒。

If you just want to "use Perl" to get the SHA1 hash for a file, in the sense that you haveActiveState Perl, and it comes with the shasumcommand-line utility, it's as simple as:

如果您只是想“使用 Perl”来获取文件的 SHA1 哈希值,从某种意义上说,您拥有ActiveState Perl,并且它带有shasum命令行实用程序,那么它很简单:

for /f %i in ('shasum secure.txt') do echo %i

The default hashing algorithm is SHA1; add -a1if you want to be explicit (not a bad idea).

默认的哈希算法是 SHA1;添加,-a1如果你想是明确的(不是一个坏主意)。

The default output format is the hash, two spaces, then the filename. This is the same format as sha1sumand similar utilities, commonly found on Unix/Linux systems. If redirected into a file, that filename can be given to shasum -clater in order to verify the integrity whatever files you had hashed previously.

默认输出格式是散列,两个空格,然后是文件名。这是与sha1sumUnix/Linux 系统上常见的类似实用程序的格式相同。如果重定向到文件中,则可以稍后提供该文件名shasum -c,以验证您之前散列的任何文件的完整性。

If you really, reallydon't want to see the filename, just the SHA1 hash, either of these will chop off the filename part:

如果您真的,真的不想看到文件名,只想看到 SHA1 哈希值,那么它们中的任何一个都会切断文件名部分:

Using Powershell:

使用 Powershell:

#!/usr/bin/perl -w
use strict;

use Digest::SHA1    qw/ sha1_hex /;

# open file
open IN_DATA, "<secure.txt" or die "cannot open file secure.txt for reading: $!";
# read in all file contents
my $file_contents;
{local $/; $file_contents = <IN_DATA>;}
# close file
close IN_DATA;
print &sha1_hex($file_contents);

Using Command Prompt (old-school batch scripting):

使用命令提示符(老式批处理脚本):

##代码##

For the second one, make sure you use %%iinstead of %i(both places) if you're putting that in a .cmdor .batfile.

对于第二个,如果你把它放在一个或文件中,请确保你使用%%i而不是%i(两个地方)。.cmd.bat

回答by amphetamachine

Use Digest::SHA1like so:

Digest::SHA1像这样使用:

##代码##

Edit: Why the down vote? Does this code not work? Is this not an appropriate solution to the problem?

编辑:为什么投反对票?这段代码不起作用吗?这不是解决问题的适当方法吗?