#!/usr/bin/perl -w # Perl script to CRC32 files and validate them # Useful for anime stuff... # # Copyright (c) 2007, ryan or # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the author nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS 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 ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # run with -h switch for usage instructions and help use constant VERSION => '0.2'; use Digest; use Switch; use File::Find; # Flags, and global declarations (don't change these, they're set by command line options) my $scanned = 0; # files scanned my $passed = 0; # if -v, files that are valid. my $vidonly = 0; # only hash/check video files. my $verify = 0; my $isfile = 0; my $isdir = 0; my $dirname = ""; my $filename = ""; my $outfile = ""; if( $#ARGV == -1 ) { &show_usage; exit; } for( my $i=-1; $i<$#ARGV; $i++ ) { my $cur = $ARGV[$i]; switch($cur) { case "-v" { $verify = 1; } case "-d" { if( $isfile || $isdir ) { last }; $isdir = 1; $dirname = $ARGV[++$i]; (-d $dirname) or die "Directory $dirname does not exist!\n"; } case "-f" { if( $isfile || $isdir ) { last }; $isfile = 1; $filename = $ARGV[++$i]; (-f $filename) or die "File $filename does not exist!\n"; } case "-h" { &show_usage; exit; } case "-o" { $outfile = $ARGV[++$i]; if( !(-e $outfile) ) { open( OUT, ">$outfile" ); close(OUT); } } case "-vid" { $vidonly = 1; } } } # Do the actual stuff here: if( $isfile ) { &check_file($filename); } elsif( $isdir ) { find(\&scan_directory, $dirname); &output("\n$scanned files hashed.\n"); ($verify && $scanned > 0) && &output("$passed/$scanned files are valid (" . ($passed/$scanned)*100 . "%)\n"); } ##### Subroutines for doing stuff ##### sub crc32 { my ($file) = @_; open( FILE, $file ); my $dig = Digest->new("CRC-32"); $dig->addfile(FILE); close FILE; return uc($dig->hexdigest()); } sub check_file { my ($file) = @_; return unless ((-f $file)); if( $vidonly && !($file =~ /(\.avi|\.mkv|\.ogm|\.mp4|\.wmv)$/i) ) { return; } &output("Hashing $file... "); my $hash = crc32($file); &output($hash); if( $verify && $file =~ /\[([0-9ABCDEF]{8})\]/ ) { &output (" ... "); if( $file =~ /\[$hash\]/i ) { &output ("OK!"); $passed++; } else { &output ("FAILED!"); } } &output( "\n" ); $scanned++; } sub scan_directory { my $arg = $_; if( !(-d $arg) ) { &check_file($arg); } elsif( -d $arg ) { &output ("\nStepping into " . $File::Find::name . "...\n"); } } sub show_usage { my $ver = VERSION; print < options: -f Get the CRC32 of a file -d Get the CRC32 of all files in a directory -v Verifies the CRC32 value by checking the filename for a match -vid Only check video files (avi, mkv, ogm, mp4, wmv) -o Output to file (appends) example: $0 -v -f [Conclave-Mendoi]_ef_-_a_tale_of_memories_05_[H264][1C06C6C4].mkv USAGE } sub output { my ($arg) = @_; if( $outfile ne "" ) { open( OUT, ">>$outfile" ); print OUT $arg; close(OUT); } else { print $arg; } }