Check the SHA checksum using shell script.

The issue

Many times the SHA checksum is provided as is, checksum file contains only a checksum.

$ ls -l
total 2728
-rw-rw-r-- 1 milosz milosz 2788190 Feb  7 16:15 starship-x86_64-unknown-linux-gnu.tar.gz
-rw-rw-r-- 1 milosz milosz      65 Feb 23 01:34 starship-x86_64-unknown-linux-gnu.tar.gz.sha256
$ cat starship-x86_64-unknown-linux-gnu.tar.gz.sha256 
d99fda409e1be96b07a8687bdbb1162e75c4a3c4301e7bf853dfd01dcb34a33

This creates a problem for standard utilities.

$ shasum --check starship-x86_64-unknown-linux-gnu.tar.gz.sha256 
shasum: starship-x86_64-unknown-linux-gnu.tar.gz.sha256: no properly formatted SHA checksum lines found

As these expect a filename associated with given checksum using GNU or BSD format.

$ shasum --algorithm 1 starship-x86_64-unknown-linux-gnu.tar.gz | tee starship-x86_64-unknown-linux-gnu.tar.gz.sha1
3abb968ef9afc057cd51af32f38fe398701421e1  starship-x86_64-unknown-linux-gnu.tar.gz
$ shasum --tag --algorithm 1 starship-x86_64-unknown-linux-gnu.tar.gz | tee starship-x86_64-unknown-linux-gnu.tar.gz.sha1
SHA1 (starship-x86_64-unknown-linux-gnu.tar.gz) = 3abb968ef9afc057cd51af32f38fe398701421e1

Such checksum can be verified without any issues.

$ shasum --check starship-x86_64-unknown-linux-gnu.tar.gz.sha1
starship-x86_64-unknown-linux-gnu.tar.gz: OK

The solution

The solution is to create a simple shell script that will perform additional steps to verify SHA checksum.

#!/bin/bash
# verify file checksum from a file

# checksum algorithms
algorithms=( 1 224 256 384 512 512224 512256 )

# file to check
file="$1"

# execute when there is one parameter
if [ "$#" -eq "1" ]; then
  # check if file exist
  if [ -f "${file}" ]; then
    # find checksum file
    for algorithm in "${algorithms[@]}"; do
      if [ -f "${file}.sha${algorithm}" ]; then
        echo "Found SHA${algorithm} checksum"
        words="$(wc -w < ${file}.sha${algorithm})"
        # verify checksum and pass the exit code
        if [ "$words" == "1" ]; then
          shasum --algorithm $algorithm --check <(echo $(cat ${file}.sha${algorithm})\ \ $file)
          exit $?
        elif [ "$words" == "2" ] || [ "$words" == "4" ]; then
          shasum --algorithm $algorithm --check ${file}.sha${algorithm}
          exit $?
        fi
      fi
    done
  fi
fi

This will automatically check SHA checksum (GNU or BSD style).

$ chkfile starship-x86_64-unknown-linux-gnu.tar.gz
Found SHA1 checksum
starship-x86_64-unknown-linux-gnu.tar.gz: OK

It will also work with a file that contains only checksum.

$ chkfile starship-x86_64-unknown-linux-gnu.tar.gz
Found SHA256 checksum
starship-x86_64-unknown-linux-gnu.tar.gz: OK

You will be informed in case of trouble.

$ chkfile starship-x86_64-unknown-linux-gnu.tar.gz
Found SHA256 checksum
starship-x86_64-unknown-linux-gnu.tar.gz: FAILED
shasum: WARNING: 1 computed checksum did NOT match

You can extend it a bit to return different exit code when a file or its checksum is not found. I leave it to you.

ko-fi