HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMinor

Validating a credit card number using Luhn's algorithm

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
numbercreditcardvalidatingalgorithmusingluhn

Problem

I implemented Luhn's algorithm explained on Wikipedia to validate a credit card number, in Bash.

Does this code follow good practices?

#!/bin/bash
getchecknumber(){ # get the last digit of the cc number
    str=$1
    checknum=$(echo ${str: -1})
}
getrest(){ # get the rest of the numbers in the sequence
    str=$(echo ${str%?})
}
doubleeveryother(){ # double every other number
    # split characters into an array
    arr=()
    i=0
    while [ "$i" -lt "${#str}" ]; do
        arr+=(${str:$i:1})
        i=$((i+1))
    done
    for ((i=1; i<=15; i++))
    do  {
        char=$(echo "$i-1" | bc)
        double=$(echo "${arr[$char]} * 2" | bc)
        if [ $(($i%2)) -eq 0 ] ; then foo=bar; else arr[$char]=$double #replace the number in the array
        fi
    }
    done
    echo -e
}
adddigitsum() { #split a two digit number into two numbers and add them
    for ((a=0; a<=14; a++))
    do {

        NUMSPLIT=()
        number=$(echo ${arr[$a]})
        if [[ ${#number} == 2 ]] ; then
            i=0
            while [[ "$i" -lt ${#number} ]]; do
                NUMSPLIT+=(${number:$i:1})
                i=$((i+1))
                done
            num=$((${NUMSPLIT[0]} + ${NUMSPLIT[1]}))
            addeddigit=$( echo $num | bc )
            arr[$a]=$addeddigit # replace the number in the array
        fi
    }
    done
}
addall(){ #add all the digits
    sum=$( IFS="+"; bc <<< "${arr[*]}" )
}
multiply(){ #multiply by 9
    result=$( echo "$sum * 9" | bc )
}
validate(){ #see if the last number of 'result' is equal to the checknum
    resultchecknum=$(echo ${result: -1})
    if [[ $resultchecknum == $checknum ]] ; then echo "CC Number is valid!" ; else echo "CC Number is not valid."
    fi
}
echo "$1 "
getchecknumber $1
getrest
doubleeveryother
adddigitsum
addall
multiply
validate

Solution

if [ $(($i%2)) -eq 0 ] ; then foo=bar; else arr[$char]=$double


Then foo=bar? In any case, an alternative way of writing this is something like (borrowing your final if statement):

[[ $resultchecknum == $checknum ]] && echo "CC Number is valid!" \
                                    || echo "CC Number is not valid."


Also, you have a mix of echo "..." | bc and bc <<< "...", I suggest keeping to the latter as it simpler to write.

A similar alternative to if-then-else is using &&:

[ ! $(($i%2)) -eq 0 ] && arr[$char]=$double

Code Snippets

if [ $(($i%2)) -eq 0 ] ; then foo=bar; else arr[$char]=$double
[[ $resultchecknum == $checknum ]] && echo "CC Number is valid!" \
                                    || echo "CC Number is not valid."
[ ! $(($i%2)) -eq 0 ] && arr[$char]=$double

Context

StackExchange Code Review Q#95211, answer score: 4

Revisions (0)

No revisions yet.