#!/usr/bin/perl # Edit the line above and line below for your perl path # eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' # if 0; #$running_under_some_shell # -------------------------------------------------------------------- # The software provided here is released by the National # Institute of Standards and Technology (NIST), an agency of # the U.S. Department of Commerce, Gaithersburg MD 20899, # USA. The software bears no warranty, either expressed or # implied. NIST does not assume legal liability nor # responsibility for a User's use of the software or the # results of such use. # # Please note that within the United States, copyright # protection, under Section 105 of the United States Code, # Title 17, is not available for any work of the United # States Government and/or for any works created by United # States Government employees. User acknowledges that this # software contains work which was created by NIST employees # and is therefore in the public domain and not subject to # copyright. The User may use, distribute, or incorporate # this software provided the User acknowledges this via an # explicit acknowledgment of NIST-related contributions to # the User's work. User also agrees to acknowledge, via an # explicit acknowledgment, that any modifications or # alterations have been made to this software before # redistribution. # -------------------------------------------------------------------- # douglas.white@nist.gov # # Usage : perl sha-family.pl [-h] [-u] -f Family_String filename [filename...] # # -h : will show help # -u : will display hash in uppercase (if allowed) # -f Family_String : comma separated list of output you want # e.g. "all" or "sha1_hex,sha1_b64,sha256_hex" # # updated 3/28/10 # -------------------------------------------------------------------- # Test this against the NIST FIPS data before you use it! # # http://csrc.nist.gov/ # http://www.nsrl.nist.gov/testdata/ # -------------------------------------------------------------------- use strict; use warnings; use vars qw( $opt_h $opt_u $opt_f %family $fileName ); use Getopt::Std ; use Digest::SHA ; # Deal with command line options. Give help if needed. getopts('huf:') or $opt_h=1; ($opt_f) or $opt_f='all'; (checkHashFamilies($opt_f)) or $opt_h=1; if ($opt_h) { showHelpAndExit(); } $fileName = shift; while($fileName) { hashAndPrint(); $fileName = shift; }; exit; #------------------------------------------ sub hashAndPrint { (-e "$fileName") or return(0); # file must exist (! -d "$fileName") or return(0); # must not be a directory # 2G file size limit for now - increase at your own risk/memory available. ((-s "$fileName") < (2 * 1024 * 1024 * 1024)) or return(0); use vars qw( @fks ); @fks = (sort keys %family); # # You need to delare a new() SHA object based on the algorithm, # so her I'm finding out which algorithms were requested. # for my $f (@fks) { if (($f =~ /sha1/ ) && ($family{$f})) { calcDigest(1); } if (($f =~ /sha224/ ) && ($family{$f})) { calcDigest(224); } if (($f =~ /sha256/ ) && ($family{$f})) { calcDigest(256); } if (($f =~ /sha384/ ) && ($family{$f})) { calcDigest(384); } if (($f =~ /sha512/ ) && ($family{$f})) { calcDigest(512); } } return(1); } #---------------------------------------------- sub calcDigest { my $mode = shift; my $inFile; if (!open ($inFile, '<', $fileName)) { print STDERR "$0 : cannot open file \"$fileName\"\n"; return 0; } binmode $inFile; my $dObj = Digest::SHA->new ($mode); my $digest; if ($family{"sha$mode"}) { $family{"sha$mode"} = 0; $dObj->addfile ($inFile); $digest = $dObj->digest; my $ps = unpack ("B*", $digest); my $l = $mode; if ($mode == 1) { $l = 160;} # SHA-1 (1) has 160 bits while (length ($ps) < $l) {$ps = "0$ps";} print "sha$mode($fileName)= $ps\n"; seek ($inFile, 0, 0); } if ($family{"sha${mode}_hex"}) { $family{"sha${mode}_hex"} = 0; $dObj->addfile ($inFile); $digest = lc ($dObj->hexdigest); if ($opt_u) {$digest = uc ($digest);} print "sha${mode}_hex($fileName)= $digest\n"; seek ($inFile, 0, 0); } if ($family{"sha${mode}_b64"}) { $family{"sha${mode}_b64"} = 0; $dObj->addfile ($inFile); $digest = $dObj->b64digest; while (length ($digest) % 4) {$digest .= '=';} print "sha${mode}_b64($fileName)= $digest\n"; } close ($inFile); } #---------------------------------------------- sub checkHashFamilies { my $f = shift; ($f) or return(0); %family = ( 'sha1' => 0, 'sha1_hex' => 0, 'sha1_b64' => 0, 'sha224' => 0, 'sha224_hex' => 0, 'sha224_b64' => 0, 'sha256' => 0, 'sha256_hex' => 0, 'sha256_b64' => 0, 'sha384' => 0, 'sha384_hex' => 0, 'sha384_b64' => 0, 'sha512' => 0, 'sha512_hex' => 0, 'sha512_b64' => 0 ); if ($f eq 'all') { for my $k (keys %family) { $family{$k} = 1; } return(1); } my @p = split(/,/,$f); for my $k (@p) { if (! defined $family{$k}) { return(0); } # tried using unknown family $family{$k} = 1; } return(1); } #---------------------------------------------- sub showHelpAndExit { print <