Skip to content

Instantly share code, notes, and snippets.

@arecvlohe
Last active July 14, 2025 20:27
Show Gist options
  • Select an option

  • Save arecvlohe/18f59d0bf209675eb9ec690a0e65a870 to your computer and use it in GitHub Desktop.

Select an option

Save arecvlohe/18f59d0bf209675eb9ec690a0e65a870 to your computer and use it in GitHub Desktop.
/**
* ====================================================================================================
*
* Luhn Algorithm:
*
* - Given a number as input
* - Split the number into two parts:
* - the last digit (called the "check digit")
* - all other digits (called the "payload digits")
*
* On the payload digits, run this logic:
* - Starting from the last digit and working backwards, double every other digit
* - If doubling a digit produces a number >= 10, replace it with the sum of its digits
* - Sum all the digits
* - Take the remainder of dividing this sum by 10
* - Subtract the remainder from 10
*
* If the number you receive matches the "check digit", the input is valid
*
* ====================================================================================================
*/
const luhnAlgorithm = (number: number) => {
const strNum = String(number);
const payloadDigits = strNum.slice(0, strNum.length - 1);
const checkDigit = parseInt(strNum[strNum.length - 1]);
const payloadResult = payloadDigits
.split("")
.reverse()
.reduce((result: Array<number>, str, idx) => {
let num = parseInt(str);
if (idx % 2 === 0) {
num *= 2;
if (num >= 10) {
const nextNum = String(num)
.split("")
.reduce((r, s) => parseInt(s) + r, 0);
num = nextNum;
}
}
result.push(num);
return result;
}, [])
.reduce((result, num) => num + result, 0);
const divByTen = payloadResult % 10;
const subByTen = 10 - divByTen;
return subByTen === checkDigit;
};
/** Test cases */
const testCases: Array<[number, boolean]> = [
[1111111111111111, false],
[2222222222222222, false],
[3333333333333333, false],
[4444444444444444, false],
[5555555555555555, false],
[6666666666666666, false],
[7777777777777777, false],
[1234123412341234, false],
[4321432143214321, false],
[1111111111111117, true],
[2222222222222224, true],
[3333333333333331, true],
[4444444444444448, true],
[5555555555555557, true],
[6666666666666664, true],
[7777777777777771, true],
[1234123412341238, true],
[4321432143214327, true],
];
testCases.forEach(([input, expected], index) => {
const received = luhnAlgorithm(input);
if (received !== expected) {
throw new Error(
`Test case ${
index + 1
} failed: for input of ${input}, received ${received} instead of ${expected}`,
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment