diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md
new file mode 100644
index 0000000000..d220afd678
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-7/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
diff --git a/algorithms-modules/algorithms-miscellaneous-7/pom.xml b/algorithms-modules/algorithms-miscellaneous-7/pom.xml
new file mode 100644
index 0000000000..3703ea5a16
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-7/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+ algorithms-miscellaneous-7
+ 0.0.1-SNAPSHOT
+ algorithms-miscellaneous-7
+
+
+ com.baeldung
+ algorithms-modules
+ 1.0.0-SNAPSHOT
+
+
+
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/luhn/LuhnChecker.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/luhn/LuhnChecker.java
new file mode 100644
index 0000000000..8f8bed4261
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/luhn/LuhnChecker.java
@@ -0,0 +1,73 @@
+package com.baeldung.algorithms.luhn;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LuhnChecker {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LuhnChecker.class);
+
+ /*
+ * Starting from the rightmost digit, we add all the digits together, performing
+ * a special step for every second digit.
+ *
+ * If the result is not divisible by 10, then the card number must not be valid.
+ *
+ * We can form a number that passes the Luhn Check by subtracting the result of
+ * the Luhn algorithm from 10.
+ *
+ * This is how the final digit of a credit card is calculated.
+ */
+ public static boolean checkLuhn(String cardNumber) {
+ int sum = 0;
+
+ try {
+ for (int i = cardNumber.length() - 1; i >= 0; i--) {
+ int digit = Integer.parseInt(cardNumber.substring(i, i + 1));
+
+ if ((cardNumber.length() - i) % 2 == 0) {
+ digit = doubleAndSumDigits(digit);
+ }
+
+ sum += digit;
+ }
+
+ LOGGER.info("Luhn Algorithm sum of digits is " + sum);
+
+ } catch (NumberFormatException e) {
+ LOGGER.error("NumberFormatException - Card number probably contained some non-numeric characters, returning false");
+ return false;
+ } catch (NullPointerException e) {
+ LOGGER.error("Null pointer - Card number was probably null, returning false");
+ return false;
+ }
+
+ boolean result = sum % 10 == 0;
+
+ LOGGER.info("Luhn check result (sum divisible by 10): " + result);
+
+ return result;
+ }
+
+ /*
+ * We apply this method to every second number from the right of the card
+ * number. First, we double the digit, then we sum the digits.
+ *
+ * Note: subtracting 9 is equivalent to doubling and summing digits (when
+ * starting with a single digit) 0-4 -> produce single digit when doubled
+ * 5*2 = 10 -> 1+0 = 1 = 10-9
+ * 6*2 = 12 -> 1+3 = 3 = 12-9
+ * 7*2 = 14 -> 1+5 = 5 = 14-9
+ * 8*2 = 16 -> 1+7 = 7 = 16-9
+ * 9*2 = 18 -> 1+9 = 9 = 18-9
+ */
+ public static int doubleAndSumDigits(int digit) {
+ int ret = digit * 2;
+
+ if (ret > 9) {
+ ret -= 9;
+ }
+
+ return ret;
+ }
+}
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/luhn/LuhnCheckerUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/luhn/LuhnCheckerUnitTest.java
new file mode 100644
index 0000000000..dd1b184b81
--- /dev/null
+++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/luhn/LuhnCheckerUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.algorithms.luhn;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LuhnCheckerUnitTest {
+
+ @Test
+ public void whenCardNumberDoesMeetLuhnCriteria_thenCheckLuhnReturnsTrue() {
+ String cardNumber = "8649";
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertTrue(result);
+ }
+
+ @Test
+ public void whenCardNumberDoesNotMeetLuhnCriteria_thenCheckLuhnReturnsFalse() {
+ String cardNumber = "8642";
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void whenCardNumberHasNoSecondDigits_thenCheckLuhnCalculatesCorrectly() {
+ String cardNumber = "0505050505050505";
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertTrue(result);
+ }
+
+ @Test
+ public void whenCardNumberHasSecondDigits_thenCheckLuhnCalculatesCorrectly() {
+ String cardNumber = "75757575757575";
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertTrue(result);
+ }
+
+ @Test
+ public void whenDoubleAndSumDigitsIsCalled_thenOutputIsCorrect() {
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(0), 0);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(1), 2);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(2), 4);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(3), 6);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(4), 8);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(5), 1);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(6), 3);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(7), 5);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(8), 7);
+ Assert.assertEquals(LuhnChecker.doubleAndSumDigits(9), 9);
+ }
+
+ @Test
+ public void whenCardNumberNonNumeric_thenCheckLuhnReturnsFalse() {
+ String cardNumber = "test";
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void whenCardNumberIsNull_thenCheckLuhnReturnsFalse() {
+ String cardNumber = null;
+ boolean result = LuhnChecker.checkLuhn(cardNumber);
+ Assert.assertFalse(result);
+ }
+}
diff --git a/algorithms-modules/pom.xml b/algorithms-modules/pom.xml
index 4ba819cfe3..4a5f36c944 100644
--- a/algorithms-modules/pom.xml
+++ b/algorithms-modules/pom.xml
@@ -21,6 +21,7 @@
algorithms-miscellaneous-4
algorithms-miscellaneous-5
algorithms-miscellaneous-6
+ algorithms-miscellaneous-7
algorithms-searching
algorithms-sorting
algorithms-sorting-2