Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

md5sum for PPT

by idnopheq (Chaplain)
on Apr 13, 2001 at 01:35 UTC ( #72205=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility Scripts
Author/Contact Info idnopheq
Description: md5sum computes a 128-bit checksum (or fingerprint or message-digest) for each specified file. If a file is specified as `-' or if no files are given md5sum computes the checksum for the standard input. md5sum can also determine whether a file and checksum are consistent.

For each file, `md5sum' outputs the MD5 checksum, a flag indicating a binary or text input file, and the filename. If file is omitted or specified as `-', standard input is read.

I added functionallity from BSD md5 and some other md5sum ports (MS-DOS, etc.) for compatibility. FSF md5sum is the default.

#!/usr/bin/perl -wT
#-*-perl-*-
#  $rcs = ' $Id: md5sum,v 1.5 2001/04/12 07:12:12 idnopheq Exp idnophe
+q $ ' ; 

use strict;
use FileHandle;
use Digest::MD5;
use Getopt::Mixed 1.006, "nextOption";
use vars qw ( %option );

my ($VERSION) = '$Revision: 1.5 $' =~ /([.\d]+)/;

my $warnings = 0;

# Print a usage message on a unknown option.
# Requires abigail's patch to Getopt::Std of 25 Feb 1999.

$SIG {__WARN__} = sub {
    if (substr ($_ [0], 0, 14) 
 eq "Unknown option") {
      die "Usage"
    };
    require File::Basename;
    $0 = File::Basename::basename ($0);
    $warnings = 1;
    warn "$0: @_";
};

$SIG {__DIE__} = sub {
    require File::Basename;
    $0 = File::Basename::basename ($0);
    if (substr ($_ [0], 0,  7) eq "Version") {
      die <<VER;
$0 (Perl bin utils) $VERSION

VER
      }
    elsif (substr ($_ [0], 0,  5) eq "Usage") {
        die <<EOF;
$0 (Perl bin utils) $VERSION
$0 [-bBcpqrtwvV] [-s string] [file ...]
EOF
      }
    elsif (substr ($_ [0], 0,  4) eq "Help") {
        die <<HELP;
$0 (Perl bin utils) $VERSION
$0 [-bBcpqrtwvV] [-s string] [file ...]

  -b, --binary   binary file mode
  -B, --bsd      FreeBSD, maybe OpenBSD?, format
  -c, --check    check manifest file
  -p,            print from stdin. Does nothing, included for FreeBSD
  -q, --quiet    only the MD5 sum is printed out
  -r, --reverse  Reverses the format of the output like FSF but no bin
+ary *
  -s, --string   Print a checksum of the given string
  -t, --text     text file mode (default)
  -v,            does nothing, included for Win32
  -h, --help     display this help and exit
  -V, --version  output version information and exit

The following two options are useful only when verifying checksums:
      --status   don't output anything, status code shows success
  -w, --warn     warn about improperly formated MD5 checksum lines

The sums are computed as described in RFC 1321.  When checking, the in
+put
should be a former default output of this program.  The default mode i
+s to
print a line with checksum, a character indicating type ('*' for binar
+y, ' '
for text), and name for each FILE.

HELP
    }
    die "$0: @_";
};

# Get the options.

Getopt::Mixed::init ( 
       "binary",        # binary file mode
       "b>binary",      # -b an alias for --binary
       "bsd",           # FreeBSD, maybe OpenBSD?, format
       "B>bsd",         # -B an alias for --bsd
       "check",         # check manifest file
       "c>check",       # -c an alias for --check
       "help",          # more detailed help
       "?>help",        # -? an alias for --help
       "h>help",        # -h an alias for --help
       "p",             # does nothing, included for FreeBSD
       "quiet",         # only the MD5 sum is printed out
       "q>quiet" ,      # -q an alias for --quiet
       "reverse",       # Reverses the format of the output
                                      #  like FSF but no binary *
       "r>reverse",     # -r an alias for --reverse
       "status",        # return 0 on ok, non-0 on badness
                                      #  only useful w/ -c or --check
       "string=s",      # Print a checksum of a given string
       "s>string",      # -s an alias for --string
       "text",          # text mode (default)
       "t>text",        # -t an alias for --text
       "v",             # does nothing, included for Win32
       "version",       # print the version number and exit
       "V>version",     # -V an alias for --version
       "warn",          # show # of ok and bad checksums
                        #  only useful w/ -c or --check
       "w>warn",        # -w an alias for --warn
      );

# process the options and gently place them in a hash for easy access

while ( 
       my (
    $option,
    $value,
    $asEntered
   )           = nextOption () 
      ) {

  $option{$option}    = $value || 1;
}

# cleanup options

Getopt::Mixed::cleanup();

# *** BEGGING FOR SWITCH CONSTRUCT

die "Version"
  if $option{'version'};

die "Help"
  if $option{'help'};

# if the 'string' option was presented, $option{'string'} will hold th
+at
# string, so hash it & print & outta here

if ( $option{'string'} ) {
  my $inMD5           = Digest::MD5->new;
  $inMD5->add ( $option{'string'} );
  print outputHash( 
     $option{'string'},
     $inMD5->hexdigest,
     ' '
     );
  exit;
}

# if we are checking file from a manifest file, the do it and bye!

if ( $option{'check'} ) {
  checkManifest ( $ARGV[0] );
  exit;
}

# figure out if we're working binary via OS and a 'text' override

$option{'binary'}   ||= $^O =~ /MSWin32/;
undef $option{'binary'}
  if $option{'text'};

$ARGV[0]            ||= "-";

# here endeth the begging ***

# MAIN, if you will
# parse each remaining option and treat it as a file to hash

foreach my $file ( @ARGV ) {
  chomp $file;
  my (
      $md5Digest,
      $binary
     ) = MD5 ( $file );
  print &outputHash ( 
      $file, 
      $md5Digest,
      $binary
     );
}

sub MD5 {
  my $file            = shift;
  my $prefix          = ' ';
  my $inFile          = new FileHandle;
  my $inMD5           = Digest::MD5->new;
  unless (-e $file) {
    warn "$file: No such file or directory\n";
    return;
  }
  unless ( $inFile->open ( "<$file" ) ) {
    warn "Could not open $file:$!\n"; 
    return;
  }
  binmode ( $inFile ) && ( $prefix = '*' )
    if $option{'binary'};
  $inMD5->addfile ( $inFile );
  $inFile->close;                  # being tidy
  return $inMD5->hexdigest, $prefix;
}

sub checkManifest {
  my $file = shift;
  my $inFile          = new FileHandle;
  unless (-e $file) {
    warn "$file: No such file or directory\n";
    return;
  }
  $inFile->open ( "<$file" )
    or die "Could not open $file:$!\n";
  my $ok = my $failed = 0;

  while ( <$inFile> ) {
    next
      if /^#/;                     # skip comments
    # our manifest file ~should be~ in a fixed format if sane
    my (
 $md5Hash,
 $binary,
 $fileName
       )              = unpack "a32 a2 A*", $_;
    warn "$fileName: No such file or directory\n" && next
      unless -e $fileName;
    my $karma = verifyHash ( 
       $md5Hash,
       $fileName
      );
  KARMA: {
      unless ( $karma && -e $fileName ) { 
 warn "$fileName: No such file or directory\n";
 $failed++;
 return;
 return;
      }
      unless ( $karma ) {
 warn "$fileName: Improperly formatted MD5 checksum line\n";
 $failed++;
 next;
 return;
      }
      bless $inFile;
    }
    my $md5 = ( MD5 ( $fileName ) )[0]
      or return;
    $option{'binary'} = ( $binary =~ /\*/ ) || undef;
    if ( $md5Hash eq $md5 ) {
      print $fileName , ": OK\n"
 unless $option{'status'};
      $ok++;
    }
    else {
      print $fileName , ": FAILED\n"
 unless $option{'status'};
      $failed++;
    }
  }
  if ( $option{'status'} ) {
      if ( $failed > 0 ) { return 1; };
      return 0;
  }
  $= = $ok+$failed;
  warn "WARNING: $failed of ", $=, " computed checksums did NOT match\
+n"
      if ( $failed > 0 && $option{'warn'} ); 
}

sub verifyHash {
  my (
      $hash,
      $file
      )              = @_;
  if ( length $hash != 32 ) { return }
  elsif ( ! -e $file )      { return 2 }
  return 1;
}

sub onError {
  require File::Basename;
  return File::Basename::basename ($0);
}

sub outputHash {
  my (
     $file,
     $md5Hash,
     $bin
     )               = @_;
  return
    unless $md5Hash;

  if ( ( defined $option{'bsd'} ) 
       + ( defined $option{'quiet'} ) 
       + ( defined $option{'reverse'} ) 
       > 1 ) {
    warn "Too many output options defined. Setting to default (FSF) st
+yle.\n";
    undef $option{'bsd'};
    undef $option{'quiet'};
    undef $option{'reverse'};
  }

 OUTPUT: {
    $option{'bsd'}     && do { 
      return onError() , " ($file) = $md5Hash\n"; 
      last OUTPUT; 
    };
    $option{'quiet'}   && do { 
      return "$md5Hash\n"; 
      last OUTPUT; 
    };
    $option{'reverse'} && do { 
      return "$md5Hash $file\n"; 
      last OUTPUT; 
    };
    return "$md5Hash $bin$file\n";
  }
}
__DATA__

=pod

=head1 NAME

md5sum - Print or check message-digests

=head2 SYNOPSIS

md5sum [option]... [file]...
md5sum [option]... --check [file]

=head2 DESCRIPTION

md5sum computes a 128-bit checksum (or fingerprint or message-digest) 
+for each specified file. If a file is specified as `-' or if no files
+ are given md5sum computes the checksum for the standard input. md5su
+m can also determine whether a file and checksum are consistent. Syno
+pses:

For each file, `md5sum' outputs the MD5 checksum, a flag indicating a 
+binary or text input file, and the filename. If file is omitted or sp
+ecified as `-', standard input is read.

=head2 OPTIONS

The program accepts the following options.

=item -b --binary        Treat all input files as binary.

This option has no effect on Unix systems, since they don't distinguis
+h between binary and text files. This option is useful on systems tha
+t have different internal and external character representations. On 
+MS-DOS and MS-Windows, this is the default. 

=item -B --bsd           Provide FreeBSD default output

Like the md5 command of the BSD-derrivitives.  This output will not wo
+rk with the check feature.

=item -c --check

Read filenames and checksum information from the single file (or from 
+stdin if no file was specified) and report whether each named file an
+d the corresponding checksum data are consistent.

The input to this mode of md5sum is usually the output of a prior, che
+cksum-generating run of `md5sum'. Each valid line of input consists o
+f an MD5 checksum, a binary/text flag, and then a filename. Binary fi
+les are marked with `*', text with ` '. For each such line, md5sum re
+ads the named file and computes its MD5 checksum. Then, if the comput
+ed message digest does not match the one on the line with the filenam
+e, the file is noted as having failed the test. Otherwise, the file p
+asses the test. 

By default, for each valid line, one line is written to standard outpu
+t indicating whether the named file passed the test. After all checks
+ have been performed, if there were any failures, a warning is issued
+ to standard error. Use the `--status' option to inhibit that output.
+ If any listed file cannot be opened or read, if any valid line has a
+n MD5 checksum inconsistent with the associated file, or if no valid 
+line is found, md5sum exits with nonzero status. Otherwise, it exits 
+successfully. 

=item -p                 Echo stdin to stdout and appends the MD5 sum 
+to stdout

(Default w/o options, so ignorred).  For *BSD boxen.

=item -q --quiet         Quiet mode

Only the MD5 sum is printed out.  Overrides the -r option.

=item -r --reverse       Reverses the format of the output

This helps with visual diffs, if you're on a *BSD box.  Simillar to de
+fault output, but w/o the binary star '*' prepending binary files.  T
+his may be important if you're on a Win32 boxen.

=item --status

This option is useful only when verifying checksums. When verifying ch
+ecksums, don't generate the default one-line-per-file diagnostic and 
+don't output the warning summarizing any failures. Failures to open o
+r read a file still evoke individual diagnostics to standard error. I
+f all listed files are readable and are consistent with the associate
+d MD5 checksums, exit successfully. Otherwise exit with a status code
+ indicating there was a failure. 

=item -s --string        Print the MD5 checksum of the string

This option overrides most options, and requires you to provide text a
+s an argument to the option.  Based on your shell, you will likely wa
+nt to single quote ' the text on both ends.

=item -t --text          Treat all input files as text files

This is the reverse of `--binary'.

=item -v                 Verbose output

(Default w/o options, so ignorred).  For MS-DOS-derrived boxen.

=item -w --warn

This option is useful only when verifying checksums. When verifying ch
+ecksums, warn about improperly formatted MD5 checksum lines. This opt
+ion is useful only if all but a few lines in the checked input are va
+lid. 

=head2 SEE ALSO

I dunno?  Some man pages, like md5sum and md5?

=head2 ACKNOWLEDGEMENTS

RSA Data Security probably think they get some credit.  I'd like to th
+ank the Academy, all those people who I love, and of course the Perl 
+Monks, especially abigail.

=head2 LICENSE

# Copyright (c) 2001
#      Dexter Coffin.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in t
+he
#    documentation and/or other materials provided with the distributi
+on.
#
# THIS SOFTWARE IS PROVIDED BY DEXTER COFFIN AND CONTRIBUTORS ``AS IS'
+' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH
+E
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR P
+URPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL DEXTER COFFIN OR CONTRIBUTORS BE 
+LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQU
+ENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GO
+ODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION
+)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AN
+Y WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF
# SUCH DAMAGE.
#


=cut

Comment on md5sum for PPT
Download Code

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://72205]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2015-08-31 20:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The oldest computer book still on my shelves (or on my digital media) is ...













    Results (364 votes), past polls