2

I used crc32 to compare some files with a backup of them. Out of 3556 files, 11 were reported as 'BAD' as in the following example:

9be46354        ./9836Feeding_the_dog_.mpeg   BAD 9be46354 != 9836Feed

However, the files are not bad, but for some reason crc32 has compared the checksum it calculated with part of the filename.

I then tried an experiment:

$ echo 12345 > 9836Feeding_the_dog_.mpeg
$ crc32 9836Feeding_the_dog_.mpeg
261dafe6

So this time crc32 appears not to have compared the checksum with the filename, and the file is not 'BAD'.

What is happening here? Does this happen to other checksums?

2

The crc32 executable that you are using is a Perl script distributed together with the Archive::Zip Perl module.

The crc32 Perl script is quite short, and has this little thing in it:

if ( $file =~ /[^[:xdigit:]]([[:xdigit:]]{8})[^[:xdigit:]]/ ) {
    my $filenameCrc = $1;
    if ( lc($filenameCrc) eq lc($fileCrc) ) {
        print("\tOK")
    } else {
        print("\tBAD $fileCrc != $filenameCrc");
    }
}

That is, if the pathname of the file contains eight consecutive hexadecimal digits, preceded and followed by at least one non-hexadecimal digit, this hexadecimal number is compared with the CRC32 checksum of the file.

In your case, you're running crc32 on ./9836Feeding_the_dog_.mpeg. This pathname contains some non-hexadecimal digits (./) followed by exactly eight hexadecimal digits (9836Feed) and then something non-hexadecimal again. 9836Feed is not the CRC32 checksum of the file, so it complains.

Example that triggers this behaviour that is "not BAD":

$ cat 261dafe6_file
12345
$ crc32 ./261dafe6_file
261dafe6        OK

Recreating your test, and provoking the "BAD" response by adding ./ in front of the pathname of the file:

$ echo 12345 >9836Feeding_the_dog_.mpeg
$ crc32 9836Feeding_the_dog_.mpeg
261dafe6

$ crc32 ./9836Feeding_the_dog_.mpeg
261dafe6        BAD 261dafe6 != 9836Feed

Since the crc32 executable is undocumented, obviously somewhat quirky, and not widely used (I didn't know about it and had to track it down, but that may not say much) I would suggest using some other tool for calculating the checksums of files. The md5sum tool from GNU coreutils is widely used, and on BSD systems you may use md5. There are also utilities for calculating stronger hashes (SHA1, SHA256 and SHA512 and others are supported by readily available utilities).


(By "non-hexadecimal digit" I mean "something that is not a hexadecimal digit")

  • Thanks. Please can you explain why crc32 ./9836Feeding_the_dog_.mpeg results in BAD... but crc32 9836Feeding_the_dog_.mpeg doesn't? – EmmaV Nov 11 '18 at 21:31
  • 1
    @EmmaV The code of crc32 takes the ./ at the start of the filename into account when finding the hexadecimal number in the in the filename. Without ./, the regular expression does not match (since the 8-digit hex number is then not preceded by a non-hex digit) so that piece of the code that I quoted is not triggered. It's silly, really. Use another tool if you're able to. – Kusalananda Nov 11 '18 at 21:34
  • 1
    I'll change to md5sum. – EmmaV Nov 11 '18 at 21:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.