The following Bash script takes a single parameter (the PAN) and exits with 1 if the PAN does not satisfy a LUHN check.
#!/bin/bash
pan=$1
panlen=${#pan}
for i in $(seq $((panlen - 1)) -1 0); do
digit=${pan:$i:1}
if [ $(((panlen-i) % 2)) -eq 0 ]; then
#even
((digit*=2))
[ ${#digit} -eq 2 ] && digit=$((${digit:0:1}+${digit:1:1}))
fi
((sum+=digit))
done
[ $((sum % 10)) -eq 0 ] || exit 1
For example, when placed in a file called isLUHNValid.sh it can be run with a valid PAN like:
./isLUHNValid.sh 4388576018410707 && echo 'Valid PAN' || echo 'Invalid PAN'
which will echo 'Valid PAN'.
And with an invalid PAN:
./isLUHNValid.sh 4388576018410708 && echo 'Valid PAN' || echo 'Invalid PAN'
it will echo 'Invalid PAN'.
I'm interested to know:
- if I've followed best practices; and/or
- if there's an opportunity for optimisation
I've been using Bash for a couple of years - but I'm constantly learning new things from examples on the Internet (like from here) and from man bash
. Unfortunately in my position I don't have anyone to look over my shoulder and review by Bash code so I thought I'd take advantage of this community.