Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a file called secure.txt in 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.

like image 535
Jim Avatar asked May 11 '10 15:05

Jim


People also ask

Where can I find SHA1 hash of a file?

How to get the SHA-1 of a file. To get the SHA-1 of a file pass the path of a file to the sha1sum command. The SHA-1 will be printed to standard output printing first the SHA-1 checksum then the name of the file.

What is digest SHA1?

The Digest::SHA1 module allows you to use the NIST SHA-1 message digest algorithm from within Perl programs. The algorithm takes as input a message of arbitrary length and produces as output a 160-bit "fingerprint" or "message digest" of the input.


2 Answers

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:

  • -MDigest::SHA1=sha1_hex loads the Digest::SHA1 module at compile time and imports sha1_hex, which gives the digest in hexadecimal form.
  • -l automatically adds a newline to the end of any print
  • -e introduces Perl code to be executed

The funny-looking diamond is a special case of Perl’s readline operator:

The null filehandle <> is special: it can be used to emulate the behavior of sed and 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 @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames.

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

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

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 -e to -E.

  • -E commandline

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

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

  • say FILEHANDLE LIST

  • say LIST

  • say

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

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

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

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

#! /usr/bin/perl

use warnings;
use strict;

use Digest::SHA1;

die "Usage: $0 file ..\n" unless @ARGV;

foreach my $file (@ARGV) {
  my $fh;
  unless (open $fh, $file) {
    warn "$0: 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 sha1sum utility.

C:\> mysha1sum.pl mysha1sum.pl mysha1sum.pl 
8f3a7288f1697b172820ef6be0a296560bc13bae  mysha1sum.pl
8f3a7288f1697b172820ef6be0a296560bc13bae  mysha1sum.pl

You didn’t say whether you have Cygwin installed, but if you do, sha1sum is part of the coreutils package.

like image 184
Greg Bacon Avatar answered Nov 04 '22 12:11

Greg Bacon


Try the Digest::SHA module.

C:\> perl -MDigest::SHA -e "print Digest::SHA->new(1)->addfile('secure.txt')->hexdigest"
like image 45
Robert Wohlfarth Avatar answered Nov 04 '22 12:11

Robert Wohlfarth