#! /bin/bash
# vim: set filetype=bash:

# filehash.sh: Print various hash digests and filesizes for the specified files
# or subsets of those files (just like filehash)

# Copyright (C) 2020-2026 by Brian Lindholm.  This file is part of the
# littleutils utility set.
#
# The filehash.sh utility is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# The filehash.sh utility is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# the littleutils.  If not, see <https://www.gnu.org/licenses/>.

# get command-line options
MD5='n'
SHA1='n'
SHA224='n'
SHA256='n'
SHA384='n'
SHA512='n'
B2_256='n'
B2_512='n'
COUNT=''
SKIP=''
while getopts 12345678chn:o: opts ; do
  case $opts in
    1) MD5='y' ;;
    2) SHA1='y' ;;
    3) SHA224='y' ;;
    4) SHA256='y' ;;
    5) SHA384='y' ;;
    6) SHA512='y' ;;
    7) B2_256='y' ;;
    8) B2_512='y' ;;
    h) echo 'filehash.sh LU_VERSION'
       echo 'usage: filehash.sh [-1(MD5)] [-2(SHA1)] [-3(SHA224)] [-4(SHA256)]'
       echo '         [-5(SHA384)] [-6(SHA512)] [-7(BLAKE2B_256)] [-8(BLAKE2B_256)]'
       echo '         [-h(elp)] [-n byte_count] [-o byte_offset] file...'
       exit 0 ;;
    n) COUNT="count=$OPTARG" ;;
    o) SKIP="skip=$OPTARG" ;;
    *) echo 'filehash.sh LU_VERSION'
       echo 'usage: filehash.sh [-1(MD5)] [-2(SHA1)] [-3(SHA224)] [-4(SHA256)]'
       echo '         [-5(SHA384)] [-6(SHA512)] [-7(BLAKE2B_256)] [-8(BLAKE2B_256)]'
       echo '         [-h(elp)] [-n byte_count] [-o byte_offset] file...'
       exit 1 ;;
  esac
done
shift $((${OPTIND}-1))

# compute hashes as requested
if [ "X$COUNT" = 'X' -a "X$SKIP" = 'X' ]; then
  for IDX in "$@" ; do
    if [ "$MD5" = 'y' ]; then md5sum "$IDX" ; fi
    if [ "$SHA1" = 'y' ]; then sha1sum "$IDX" ; fi
    if [ "$SHA224" = 'y' ]; then sha224sum "$IDX" ; fi
    if [ "$SHA256" = 'y' ]; then sha256sum "$IDX" ; fi
    if [ "$SHA384" = 'y' ]; then sha384sum "$IDX" ; fi
    if [ "$SHA512" = 'y' ]; then sha512sum "$IDX" ; fi
    if [ "$B2_256" = 'y' ]; then b2sum -l 256 "$IDX" ; fi
    if [ "$B2_512" = 'y' ]; then b2sum -l 512 "$IDX" ; fi
  done
else
  for IDX in "$@" ; do
    if [ "$MD5" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | md5sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$SHA1" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | sha1sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$SHA224" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | sha224sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$SHA256" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | sha256sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$SHA384" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | sha384sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$SHA512" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | sha512sum | sed -e "s/-$/$IDX/" ; fi
    if [ "$B2_256" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | b2sum -l 256 | sed -e "s/-$/$IDX/" ; fi
    if [ "$B2_512" = 'y' ]; then dd status=none if="$IDX" bs=1 $COUNT $SKIP | b2sum -l 512 | sed -e "s/-$/$IDX/" ; fi
  done
fi
