TeamViterbi has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I found a code on the internet that I thought would help me do a checksum on a binary file that I have. However, I do not know where to put my file path in this code. The code is as follows:
#!/usr/bin/perl use String::CRC32; scalar(@AGVB) || die "Usage: crc32 [file]\n"; for my $file (@AGVB) { open(SOMEFILE, "<$file") || die "Couldn't open $file: $!\n"; $crc = crc32(*SOMEFILE); close(SOMEFILE); print sprintf('%08x',$crc) . " $file (" . sprintf('%08x', (0xffffffff +- $crc)) . ")\n"; }
Thanks for all your help!

Replies are listed 'Best First'.
Re: Checksum Help
by jethro (Monsignor) on Jul 07, 2009 at 20:37 UTC
    @AGVB should be @ARGV. Then you could call the script with your filename as parameter. If you want to have a fixed filename in the script, just replace $file in the open statement with your file path and remove the loop and the line before the loop.
      Hi Jethro, Thanks for the quick response. When you say "remove the loop and the line before the loop" are you referring to the for loop and the line beginning with scalar? Sorry for the confusion, I am still very new to perl and programming in general, but I'm making headway in learning!

        Yes, the line before the loop checks whether the script got any parameters when it was called (the parameters are automatically stored in the array @ARGV when the script is started). If not, it gives a helpful message how to call the script and stops. If the script has parameters it loops through all the parameters and opens each one of them and prints the crc of each file

        So if you only want one fixed file checked, you obviously don't need the loop and don't need to check for any parameters. Otherwise just keep the script and call it with the file paths as parameter

Re: Checksum Help
by graff (Chancellor) on Jul 07, 2009 at 21:49 UTC
    I would have written that like this, keeping (and clarifying in the "Usage" message) the intention to allow multiple files to be done in one run. (Note -- on unix/linux/macosx for sure, don't know about "cmd.exe" -- when your command line is  prog_name *.txt or whatever, the shell does file name expansion, replacing "*.txt" with the list of all matching file names, before invoking the script, so @ARGV has that many elements in it.)
    #!/usr/bin/perl use strict; use String::CRC32; my $Usage = "Usage: $0 file.name ...\n"; @ARGV or die $Usage; for my $file ( @ARGV ) { open( my $fh, "<", $file ) or die "Unable to open $file: $!\n"; my $crc = crc32( $fh ); close $fh; printf( "%08x ( %08x ) %s\n", $crc, 0xffffffff - $crc, $file ); }

    I don't understand the relevance of 0xffffffff - $crc, but if it's useful at all, it helps to have fixed-width fields to the left of variable-width fields.

      Graff, so i tried using what you gave me, and i placed the file name where you have "file.name" However, whenever i run the script, terminal only prints out "Usage: file.name" and not the checksum. Any suggestions?
        If you have saved the script to a file called (let's say) "mycrc.pl", then you should see the following when you run it:
        mycrc.pl Usage: mycrc.pl file.name ... mycrc.pl * [list of all files in the current directory, with their crc values..]
        The same should happen if you run it like this:
        perl mycrc.pl perl mycrc.pl *
Re: Checksum Help
by toolic (Bishop) on Jul 07, 2009 at 21:46 UTC
    Give this a try:
    $ cat ./crc32.pl #!/usr/bin/env perl use strict; use warnings; use String::CRC32; die "Usage: crc32.pl file\n" unless @ARGV; for my $file (@ARGV) { open my $fh, '<', $file or die "can not open file $file: $!"; my $crc = crc32($fh); close $fh; printf "%08x %s (%08x)\n", $crc, $file, (0xffff_ffff - $crc); } $ ls *.txt data.txt file.txt golf.txt $ ./crc32.pl *.txt d13bcbe6 data.txt (2ec43419) 0b8c331a file.txt (f473cce5) 5f20086b golf.txt (a0dff794) $
      Hey toolic, Thanks for helping me out with this. I've got a few questions about this code though, mainly cause I dont fully understand perl yet, bare with me if you dont mind. I read that "#!/usr/bin/env perl" should always go first in the code. What is $cat? I also dont understand what is going on with the .txt near the bottom. What are the numbers in () and why are they there? and can this program work with .bin files? Thanks so much for helping me out. I really appreciate it.
        What is $cat?
        The '$' is the command line prompt conventionally used for the Unix Bourne shell. cat is a unix command which shows the contents of a file. There is a space between '$' and 'cat'. When I saw #!/usr/bin/perl in your code, I assumed you were on a unix-like operating system. What OS are you on?

        I used cat to show you the contents of the Perl program file that I adapted from your code. I named the file 'crc32.pl'. I then used the ls unix command to show you the listing of files in my directory which have a 'txt' extension. The output of ls shows 3 files.

        Finally, I ran the Perl program, and you can see 3 lines of output, 1 for each plain text input file.

        What are the numbers in () and why are they there?
        They are the results of the difference between 0xffffffff and the CRC values, expressed in hexadecimal notation.
        and can this program work with .bin files?
        I don't know what you mean by .bin file. Does the String::CRC32 documentation mention what file types are supported by the module?