diff --git a/build.gradle b/build.gradle
index 26a8fe7..612fc7d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
}
group = 'com.labelzoom.api'
-version = '1.3.0'
+version = '1.3.1'
java {
sourceCompatibility = JavaVersion.VERSION_1_8
diff --git a/src/main/java/com/labelzoom/api/util/CheckDigitUtils.java b/src/main/java/com/labelzoom/api/util/CheckDigitUtils.java
new file mode 100644
index 0000000..f2ab433
--- /dev/null
+++ b/src/main/java/com/labelzoom/api/util/CheckDigitUtils.java
@@ -0,0 +1,85 @@
+package com.labelzoom.api.util;
+
+public class CheckDigitUtils
+{
+ public enum CheckDigitType
+ {
+ MOD10,
+ }
+
+ public static int getCheckDigit(final String barcode, final CheckDigitType type)
+ {
+ switch (type)
+ {
+ case MOD10: return getMod10CheckDigit(barcode);
+ default: throw new IllegalArgumentException("Invalid check digit type");
+ }
+ }
+
+ /**
+ *
+ * MOD10 Check Digit Calculator
+ *
+ *
+ *
+ * How to calculate your check digit yourself
+ *
+ *
+ *
+ * Example barcode number: 501234576421
+ *
+ *
+ *
+ * Step 1: add together all alternate numbers starting from the right
+ * 5 0 1 2 3 4 5 7 6 4 2 1
+ * 0 + 2 + 4 + 7 + 4 + 1 = 18
+ *
+ *
+ *
+ * Step 2: multiply the answer by 3
+ * 18 x 3 = 54
+ *
+ *
+ *
+ * Step 3: now add together the remaining numbers
+ * 5 0 1 2 3 4 5 7 6 4 2 1
+ * 5 + 1 + 3 + 5 + 6 + 2 = 22
+ *
+ *
+ *
+ * Step 4: add step 2 and 3 together
+ * 54 + 22 = 76
+ *
+ *
+ *
+ * Step 5: the difference between step 4 and the next 10th number:
+ * 76 + 4 = 80
+ * Check digit = 4
+ *
+ *
+ * @param barcode the barcode data
+ * @return the check digit
+ */
+ private static int getMod10CheckDigit(final String barcode)
+ {
+ char[] digits = barcode.toCharArray();
+ /* Sum odds and evens separately so that we only perform one multiplication. In practice, one large
+ * multiplication was faster than several small multiplications
+ */
+ int evens = 0;
+ int odds = 0;
+ boolean isEven = false; // Use alternating boolean variable rather than modular division (e.g., i % 2)
+ for (int i = digits.length - 1; i >= 0; i--)
+ {
+ if (isEven = !isEven) // Invert and update value as we read it. Ignore IntelliJ, it doesn't appreciate my l33tness
+ {
+ evens += Character.getNumericValue(digits[i]);
+ }
+ else
+ {
+ odds += Character.getNumericValue(digits[i]);
+ }
+ }
+ return 10 - (((evens * 3) + odds) % 10);
+ }
+}
diff --git a/src/test/java/com/labelzoom/api/util/CheckDigitUtilsTests.java b/src/test/java/com/labelzoom/api/util/CheckDigitUtilsTests.java
new file mode 100644
index 0000000..6e32109
--- /dev/null
+++ b/src/test/java/com/labelzoom/api/util/CheckDigitUtilsTests.java
@@ -0,0 +1,17 @@
+package com.labelzoom.api.util;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class CheckDigitUtilsTests
+{
+ @Test
+ void testAxiconExample() { assertEquals(4, CheckDigitUtils.getCheckDigit("501234576421", CheckDigitUtils.CheckDigitType.MOD10)); }
+
+ @Test
+ void testSsccExample() { assertEquals(8, CheckDigitUtils.getCheckDigit("0000123456000000001", CheckDigitUtils.CheckDigitType.MOD10)); }
+
+ @Test
+ void testCode128Example() { assertEquals(8, CheckDigitUtils.getCheckDigit("0008100887950411637", CheckDigitUtils.CheckDigitType.MOD10)); }
+}