Md5, sha1 and sha2 for Caja context menu

This is a little script I made for Caja.

  • Calculates MD5, SHA-1, and SHA-2 checksums
  • can handle multiple files (creates a checksum file)
  • has a progress bar

Requirements: zenity, pv
xsel (optional)
Install the script in /home/username/.config/caja/scripts/ and make executable (chmod 755)

#!/bin/bash
# Purpose:   Caja Custom Action. Calculates hashes.
# Version:   1.3  (January 2017) - Misko_2083
# Licence:   GPLv2

if ! hash zenity &>/dev/null ; then
   echo "zenity is not installed!"
   echo "please install zenity"
   exit 1
fi

if ! hash pv &>/dev/null ; then
   echo "pv is not installed!"
   echo "please install pv"
   zenity --error --text="pv is not installed\nplease install pv"
   exit 1
fi

MD5=(`echo "" | awk '{print "TRUE","MD5", $0}'`)
SHA1=(`echo "" | awk '{print "FALSE","SHA-1", $0}'`)
SHA224=(`echo "" | awk '{print "FALSE","SHA-224", $0}'`)
SHA256=(`echo "" | awk '{print "FALSE","SHA-256", $0}'`)
SHA384=(`echo "" | awk '{print "FALSE","SHA-384", $0}'`)
SHA512=(`echo "" | awk '{print "FALSE","SHA-512", $0}'`)

progressbar(){
     read PIPED_PID
     zenity --progress --title="${1} Checksum" \
            --text="Calculating ${1} for:\n${file##*/}" --auto-close \
     || (kill $PIPED_PID; rm $sum_temp)
}

do_md5(){
    ((pv -n "$file" | md5sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "MD5"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "MD5"
}

do_sha1(){
    ((pv -n "$file" | sha1sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "SHA-1"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "SHA-1"
}

do_sha224(){
    ((pv -n "$file" | sha224sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "SHA-224"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "SHA-224"
}

do_sha256(){
    ((pv -n "$file" | sha256sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "SHA-256"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "SHA-256"
}

do_sha384(){
    ((pv -n "$file" | sha384sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "SHA-384"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "SHA-384"
}

echo $selection | grep "SHA-512" > /dev/null
do_sha512(){
    ((pv -n "$file" | sha512sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) 2>&1 \
     | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo $!) 2>&1 \
     | progressbar "SHA-512"

    # If Cancel is clicked then exit
    if [[ ! -f "$sum_temp" ]]; then
       exit 0
    fi

    show_results "SHA-512"
}

show_results(){
    sum=`cat $sum_temp`
    if zenity --question --title="$1" \
    --text="$1 : $sum\nFile :          ${file##*/}\n
If you have a correct checksum on clipboard you can compare it with this one.
Do you want to compare?" --no-wrap
       then
       # Compare with clipboard
          sum_paste="$(zenity --entry --title="Compare sum" \
                              --text="If xsel is installed it will paste into text entry box automatically.Enter the sum to compare:" \
                              --entry-text="$(xsel -b -o 2>/dev/null || echo "Paste Here")"
                     )"
          if [ $? = 0 ]; then
             if [ "$sum_paste" == "$(cat $sum_temp)" ];then
                 zenity --info --title="${1}" --text="Checksums are IDENTICAL!" --icon-name="gtk-yes"
             else
                 zenity --info --title="${1}" --text="Checksums are DIFFERENT!" --icon-name="gtk-no"
             fi
          fi

    fi
}

selection_dialog(){
    selection=$(zenity --list --radiolist --height=300 \
                       --title="Checksum" --text="File:  <b>${file##*/}</b>\nPick the hash function." \
                       --column="Pick" --column="Hash" \
                       "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")

    # If Cancel is clicked then exit
    if [ "${PIPESTATUS[0]}" -ne "0" ]; then
        exit 0
    fi

    # Create a temp file
    sum_temp=$(mktemp /tmp/sum.XXXXXXXX)

case "${selection}" in
    "MD5") do_md5 ;;
    "SHA-1") do_sha1 ;;
    "SHA-224") do_sha224 ;;
    "SHA-256") do_sha256 ;;
    "SHA-384") do_sha384 ;;
    "SHA-512") do_sha512 ;;
esac
}

multi_checksum(){
case "${1}" in
    "MD5") md5sum "${2}" >> md5.checksum ;;
    "SHA-1") sha1sum "${2}" >> sha1.checksum ;;
    "SHA-224") sha224sum "${2}" >> sha224.checksum ;;
    "SHA-256") sha256 "${2}" >> ha256.checksum ;;
    "SHA-384") sha384sum "${2}" >> sha384.checksum ;;
    "SHA-512") sha512 "${2}" >> sha512.checksum ;;
esac
}

do_multi(){
   if zenity --question --title="${1} Checksumsum" --no-wrap \
             --text="Multiple files selected.\nThis will create/overwrite a file named <b>${2}.checksum</b>
in the directory where the selected files are stored.
Proceed?"
       then
           > ${2}.checksum
           i=0
           TOTAL="$counter"

           while read -r line || [[ -n "$line" ]]; do
                ((++i))
                PERCENT=$(($i*100/${TOTAL}))
                echo "#${2} $i/$TOTAL: $line"
                multi_checksum "${1}" "${line}" >&1
                echo "$PERCENT"
           done < "$LST" | zenity --progress --title="${1}" --auto-close

           exo-open "${2}.checksum" 2>/dev/null || zenity --text-info --title="${1} checksums" < ${2}.checksum
   fi
}

selection_dialog_multi(){
    selection=$(zenity --list --radiolist --height=300 \
                       --title="Checksum" --text="Pick the hash function." \
                       --column="Pick" --column="Hash" \
                       "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")

    # If Cancel is clicked then exit
    if [ "${PIPESTATUS[0]}" -ne "0" ]; then
        exit 0
    fi

case "${selection}" in
    "MD5") do_multi "MD5" "md5" ;;
    "SHA-1") do_multi "SHA-1" "sha1" ;;
    "SHA-224") do_multi "SHA-224" "sha224" ;;
    "SHA-256") do_multi "SHA-256" "sha256" ;;
    "SHA-384") do_multi "SHA-384" "sha384" ;;
    "SHA-512") do_multi "SHA-512" "sha512" ;;
esac
}

LST=$(mktemp /tmp/XXXXXX)
> $LST
for arg
 do
   if [[ -f "${arg}" ]]; then
      echo ${arg} >> $LST
   fi
done

counter="$(wc -l "$LST" | cut -d' ' -f1)"

case "${counter}" in
   ""|0) zenity --error --text="Nothing to calculate!" ;;
   1) file="$@"; selection_dialog ; rm $sum_temp;;
   *) selection_dialog_multi ;;
esac

rm $LST

#End of script
6 Likes

Hallo Misko

Well you can do things that I can’t! I’m sure some people are going to find that useful. :slight_smile:

I’d just like to point out to those who aren’t already aware - Md5 and sha1 are no longer considered to be “safe”, i.e. they can be “compromised”. :robot: This does not mean that everything that comes with a Md5 or sha1 checksum is dangerous - but you should be aware that there is an element of risk. As always, think-before-you-click-before-you-install. :+1:

The Ubuntu-Mate downloads use sha2. :relaxed:

Hola, disculpa, podrĂ­as indicarme como usarlo, no pude hacerlo funcionar.
Tengo las dependencias listas.
Estoy usando Debian 10. Gracias,

Sorry, I don't understand.
I see that the formating is all messed up, probably with the website update, and I can't edit the pos above.
You need pv, zenity and xsel is optional.

#!/bin/bash
#Purpose: Caja Custom Action. Calculates hashes.
#Version: 1.3 (January 2017) - Misko_2083
#Licence: GPLv2

if ! hash zenity &>/dev/null ; then
  echo "zenity is not installed!"
  echo "please install zenity"
  exit 1
fi

if ! hash pv &>/dev/null ; then
  echo "pv is not installed!"
  echo "please install pv"
  zenity --error --text="pv is not installed\nplease install pv"
  exit 1
fi

MD5=($(echo "" | awk '{print "TRUE","MD5", $0}'))
SHA1=($(echo "" | awk '{print "FALSE","SHA-1", $0}'))
SHA224=($(echo "" | awk '{print "FALSE","SHA-224", $0}'))
SHA256=($(echo "" | awk '{print "FALSE","SHA-256", $0}'))
SHA384=($(echo "" | awk '{print "FALSE","SHA-384", $0}'))
SHA512=($(echo "" | awk '{print "FALSE","SHA-512", $0}'))

progressbar() {
  read PIPED_PID
zenity --progress --title="${1} Checksum" \
  --text="Calculating ${1} for:\n${file##*/}" \
  --auto-close || (kill "$PIPED_PID"; rm "$sum_temp")
}

do_md5() {
  ( (pv -n "$file" | md5sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1<=99) print $1; else print 99; fflush(stdout)}' )& echo "$!") 2>&1 \
  | progressbar "MD5"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "MD5"

}

do_sha1(){
  ( (pv -n "$file" | sha1sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}' )& echo "$!" ) 2>&1 \
  | progressbar "SHA-1"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "SHA-1"

}

do_sha224(){
  ( (pv -n "$file" | sha224sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo "$!") 2>&1 \
  | progressbar "SHA-224"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "SHA-224"

}

do_sha256(){
  ( (pv -n "$file" | sha256sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo "$!") 2>&1 \
  | progressbar "SHA-256"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "SHA-256"

}

do_sha384(){
  ( (pv -n "$file" | sha384sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo "$!") 2>&1 \
  | progressbar "SHA-384"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "SHA-384"

}

do_sha512(){
  ( (pv -n "$file" | sha512sum 2>&1 | tee >(cut -d ' ' -f1 > "$sum_temp") 2>&1 \
  | awk '{if ($1 <=99) print $1; else print 99; fflush(stdout)}')& echo "$!") 2>&1 \
  | progressbar "SHA-512"

# If Cancel is clicked then exit
if [[ ! -f "$sum_temp" ]]; then
   exit 0
fi

show_results "SHA-512"

}

show_results(){
sum="$(cat "$sum_temp")"
if zenity --question --title="$1" \
    --text="$1 : $sum\nFile : ${file##*/}\nIf you have a correct checksum on clipboard you can compare it with this one.Do you want to compare?" \
    --no-wrap
then
   # Compare with clipboard
   sum_paste="$(zenity --entry --title="Compare sum" \
                 --text="If xsel is installed it will paste into text entry box automatically.Enter the sum to compare:" \
                 --entry-text="$(xsel -b -o 2>/dev/null || echo "Paste Here")" )"
    if [ $? = 0 ]; then
        if [ "$sum_paste" == "$(cat "$sum_temp")" ];then
            zenity --info --title="${1}" --text="Checksums are IDENTICAL!" --icon-name="gtk-yes"
         else
             zenity --info --title="${1}" --text="Checksums are DIFFERENT!" --icon-name="gtk-no"
        fi
    fi
fi

}

selection_dialog(){
   selection="$(zenity --list --radiolist --height=300 \
             --title="Checksum" --text="File: ${file##*/}\nPick the hash function." \
              --column="Pick" --column="Hash" "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")"

# If Cancel is clicked then exit
if [ "${PIPESTATUS[0]}" -ne "0" ]; then
    exit 0
fi

# Create a temp file
sum_temp="$(mktemp /tmp/sum.XXXXXXXX)"

case "${selection}" in
  "MD5") do_md5 ;;
  "SHA-1") do_sha1 ;;
  "SHA-224") do_sha224 ;;
  "SHA-256") do_sha256 ;;
  "SHA-384") do_sha384 ;;
  "SHA-512") do_sha512 ;;
esac
}

multi_checksum(){
case "${1}" in
  "MD5") md5sum "${2}" >> md5.checksum ;;
  "SHA-1") sha1sum "${2}" >> sha1.checksum ;;
  "SHA-224") sha224sum "${2}" >> sha224.checksum ;;
  "SHA-256") sha256 "${2}" >> ha256.checksum ;;
  "SHA-384") sha384sum "${2}" >> sha384.checksum ;;
  "SHA-512") sha512 "${2}" >> sha512.checksum ;;
esac
}

do_multi(){
if zenity --question --title="${1} Checksumsum" --no-wrap \
   --text="Multiple files selected.\nThis will create/overwrite a file named ${2}.checksum in the directory where the selected files are stored. Proceed?"
then
> "${2}.checksum"
i=0
TOTAL="$counter"

       while read -r line || [[ -n "$line" ]]; do
            ((++i))
            PERCENT=$((i*100/TOTAL))
            echo "#${2} $i/$TOTAL: $line"
            multi_checksum "${1}" "${line}" >&1
            echo "$PERCENT"
       done < "$LST" | zenity --progress --title="${1}" --auto-close

       exo-open "${2}.checksum" 2>/dev/null || zenity --text-info --title="${1} checksums" < "${2}.checksum"

fi
}

selection_dialog_multi(){
selection=$(zenity --list --radiolist --height=300 \
   --title="Checksum" --text="Pick the hash function." \
   --column="Pick" --column="Hash" \
   "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")

# If Cancel is clicked then exit
if [ "${PIPESTATUS[0]}" -ne "0" ]; then
    exit 0
fi

case "${selection}" in
  "MD5") do_multi "MD5" "md5" ;;
  "SHA-1") do_multi "SHA-1" "sha1" ;;
  "SHA-224") do_multi "SHA-224" "sha224" ;;
  "SHA-256") do_multi "SHA-256" "sha256" ;;
  "SHA-384") do_multi "SHA-384" "sha384" ;;
  "SHA-512") do_multi "SHA-512" "sha512" ;;
esac
}

LST=$(mktemp /tmp/XXXXXX)

    >$LST
    for arg
    do
    if [[ -f "${arg}" ]]; then
    echo "${arg}" >> "$LST"
    fi
    done

counter="$(wc -l "$LST" | cut -d' ' -f1)"

case "${counter}" in
    ""|0)  zenity --error --text="Nothing to calculate!" ;;
       1)    file="$@"; selection_dialog ; rm "$sum_temp" ;;
       *)     selection_dialog_multi ;;
    esac

rm "$LST"

#End of script
2 Likes

Usefull script for my needs. I added to my caja scripts, thanks!