======================================= Luhn Check Digit Validation ======================================= To validate a number using the Luhn algorithm, follow these steps: 1. Starting from the rightmost digit (the check digit), move left and double every second digit. 2. If doubling a digit results in a value greater than 9, subtract 9 from the product (or sum the digits of the product). 3. Sum all the resulting digits, including those that were not doubled. 4. If the total sum modulo 10 is equal to 0 (i.e. the sum ends in zero), the number is valid. --------------------------------------- Credit Card Test Numbers 49927398716 good 49927398717 bad 1234567812345670 good 1234567812345678 bad ======================================= php --------------------------------------- function luhn($card) { if(!count($card)) return; $number = preg_replace('/\D/', '', $card); $sum = 0; $is_even = false; for($i = strlen($number) - 1; $i >= 0; $i--) { $digit = intval($number[$i]); if($is_even) { $digit *= 2; if($digit > 9) { $digit -= 9; } } $sum += $digit; $is_even = !$is_even; } return $sum % 10 === 0; } ======================================= javascript --------------------------------------- function luhn(card) { if(!card.length) return; const number = card.replace(/\D/g, ''); let sum = 0; let is_even = false; for(let i = number.length - 1; i >= 0; i--) { let digit = parseInt(number[i], 10); if(is_even) { digit *= 2; if(digit > 9) { digit -= 9; } } sum += digit; is_even = !is_even; } return sum % 10 === 0; } ======================================= echo 49927398716 | awk -f luhn.awk --------------------------------------- { if($0 == "") { exit 1 } gsub(/[^0-9]/, "", $0) n = length($0) sum = 0 is_even = 0 for(i = n; i >= 1; i--) { digit = substr($0, i, 1) + 0 if(is_even) { digit *= 2 if(digit > 9) { digit -= 9 } } sum += digit is_even = !is_even } print(sum % 10 == 0) ? 1 : 0 } ======================================= echo 49927398716 | luhn.sh --------------------------------------- #!/bin/sh read card if [ -z "$card" ]; then echo 0; exit fi n=$(echo "$card" | tr -cd '0-9') sum=0 is_even=0 i=${#n} while [ $i -gt 0 ]; do digit=$(printf '%s' "$n" | cut -c $i) if [ $is_even -eq 1 ]; then double=$((digit * 2)) [ $double -gt 9 ] && double=$((double - 9)) sum=$((sum + double)) else sum=$((sum + digit)) fi is_even=$((1 - is_even)) i=$((i - 1)) done [ $((sum % 10)) -eq 0 ] && echo 1 || echo 0 ======================================= end =======================================