From 3bc707796c435ce964ca07f01feef70957092aa3 Mon Sep 17 00:00:00 2001 From: Marc Wrobel Date: Sat, 22 Oct 2022 12:04:03 +0200 Subject: [PATCH] Introduce the CheckDigit interface (closes #174) --- CHANGELOG.md | 3 ++ .../jbanking/checkdigit/CheckDigit.java | 41 +++++++++++++++++++ .../{iban => checkdigit}/IbanCheckDigit.java | 13 +++--- .../jbanking/checkdigit/package-info.java | 5 +++ .../jbanking/creditor/CreditorIdentifier.java | 2 +- .../fr/marcwrobel/jbanking/iban/Iban.java | 1 + .../IbanCheckDigitTest.java | 10 +---- 7 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 src/main/java/fr/marcwrobel/jbanking/checkdigit/CheckDigit.java rename src/main/java/fr/marcwrobel/jbanking/{iban => checkdigit}/IbanCheckDigit.java (92%) create mode 100644 src/main/java/fr/marcwrobel/jbanking/checkdigit/package-info.java rename src/test/java/fr/marcwrobel/jbanking/{iban => checkdigit}/IbanCheckDigitTest.java (92%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01bb81a..d0b2aab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). regular expression. - (**breaking change**) Make `BicFormatException`, `CreditorIdentifierFormatException`, `IbanFormatException` and `SwiftPatternSyntaxException` extend `IllegalArgumentException` instead of `RuntimeException` (#220). +- (**breaking change**) Move `IbanCheckDigit` from `fr.marcwrobel.jbanking.iban` to `fr.marcwrobel.jbanking.checkdigit` + (#174). - Get rid of regexes to validate BICs (#170). This significantly increased the performances of BIC validation and creation (+200-300%). - Get rid of regexes to validate Creditor Identifiers (#172). This significantly increased the performances of @@ -81,5 +83,6 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Use `Character.digit` instead of `Character.getNumericValue` in `IbanCheckDigit` as recommended in [Error Prone#CharacterGetNumericValue](https://errorprone.info/bugpattern/CharacterGetNumericValue) (closes #117). - Add serialization tests for serializable classes (#222). +- Add the `CheckDigit` interface and make `IbanCheckDigit` implements it (#174). ### Thanks diff --git a/src/main/java/fr/marcwrobel/jbanking/checkdigit/CheckDigit.java b/src/main/java/fr/marcwrobel/jbanking/checkdigit/CheckDigit.java new file mode 100644 index 0000000..449c2cc --- /dev/null +++ b/src/main/java/fr/marcwrobel/jbanking/checkdigit/CheckDigit.java @@ -0,0 +1,41 @@ +package fr.marcwrobel.jbanking.checkdigit; + +/** + * A check digit is a form of redundancy check used for error detection on identification numbers, such as bank account + * numbers, which are used in an application where they will at least sometimes be input manually. It consists of one + * or more digits (or letters) computed by an algorithm from the other digits (or letters) in the sequence input. + * + *

+ * With a check digit, one can detect simple errors in the input of a series of characters (usually digits) such as a + * single mistyped digit or some permutations of two successive digits. + * + *

+ * A class that implements this interface implements one of the many existing algorithms for calculating and validating + * check digits, such as one defined in ISO/IEC 7064. + * + * @see Check digit + */ +public interface CheckDigit { + + /** + * Calculates the check digit for a given input string. + * + * @param input the non-null input string to calculate the check digit for + * @return a non-null string + * @throws IllegalArgumentException if the check digit cannot be computed for the given input string (because it is + * {@code null}, to short...) + */ + String calculate(String input); + + /** + * Validates the check digit for the given input string. + * + *

+ * Invalid input strings, such as {@code null}, are considered invalid and do not throw any exception. + * + * @param input the input string to validate, may be null + * @return {@code true} if the check digit is verified, {@code false} otherwise + */ + boolean validate(String input); + +} diff --git a/src/main/java/fr/marcwrobel/jbanking/iban/IbanCheckDigit.java b/src/main/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigit.java similarity index 92% rename from src/main/java/fr/marcwrobel/jbanking/iban/IbanCheckDigit.java rename to src/main/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigit.java index f3b00eb..cf65662 100644 --- a/src/main/java/fr/marcwrobel/jbanking/iban/IbanCheckDigit.java +++ b/src/main/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigit.java @@ -1,4 +1,4 @@ -package fr.marcwrobel.jbanking.iban; +package fr.marcwrobel.jbanking.checkdigit; /** * Provide ISO 7064 Mod 97,10 IBAN check digit calculation and validation. @@ -15,7 +15,7 @@ * "https://git.apache.org/repos/asf?p=commons-validator.git;a=blob;f=src/main/java/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java;hb=HEAD">https://git.apache.org/repos/asf?p=commons-validator.git;a=blob;f=src/main/java/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java;hb=HEAD * @since 1.0 */ -public enum IbanCheckDigit { +public enum IbanCheckDigit implements CheckDigit { /** * The singleton instance for this class. */ @@ -33,10 +33,10 @@ public enum IbanCheckDigit { * The behavior of this method changed in 4.0.0: prior to this version this method raised an exception on invalid * check digits. Now it is returning {@code false} instead. * - * @param iban a non-null string. - * @return {@code true} if the given IBAN check digit is valid, {@code false} otherwise. - * @throws IllegalArgumentException if the given IBAN is {@code null} or if its size is not at least four characters. + * @param iban a non-null string + * @return {@code true} if the given IBAN check digit is valid, {@code false} otherwise */ + @Override public boolean validate(String iban) { if (iban == null || iban.length() <= BBAN_INDEX) { return false; @@ -58,8 +58,9 @@ public boolean validate(String iban) { * ([a-zA-Z0-9]) and check digit characters have to be set to zero. * * @param iban a non-null string - * @return the given IBAN check digit. + * @return the given IBAN check digit */ + @Override public String calculate(String iban) { if (iban == null) { throw new IllegalArgumentException("the iban argument cannot be null"); diff --git a/src/main/java/fr/marcwrobel/jbanking/checkdigit/package-info.java b/src/main/java/fr/marcwrobel/jbanking/checkdigit/package-info.java new file mode 100644 index 0000000..5ba5b8d --- /dev/null +++ b/src/main/java/fr/marcwrobel/jbanking/checkdigit/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes that relates to {@link fr.marcwrobel.jbanking.checkdigit.CheckDigit check digits} computation and + * validation. + */ +package fr.marcwrobel.jbanking.checkdigit; diff --git a/src/main/java/fr/marcwrobel/jbanking/creditor/CreditorIdentifier.java b/src/main/java/fr/marcwrobel/jbanking/creditor/CreditorIdentifier.java index 89c4d31..8f6d79f 100644 --- a/src/main/java/fr/marcwrobel/jbanking/creditor/CreditorIdentifier.java +++ b/src/main/java/fr/marcwrobel/jbanking/creditor/CreditorIdentifier.java @@ -1,7 +1,7 @@ package fr.marcwrobel.jbanking.creditor; import fr.marcwrobel.jbanking.IsoCountry; -import fr.marcwrobel.jbanking.iban.IbanCheckDigit; +import fr.marcwrobel.jbanking.checkdigit.IbanCheckDigit; import fr.marcwrobel.jbanking.internal.AsciiCharacters; import java.io.Serializable; import java.util.Optional; diff --git a/src/main/java/fr/marcwrobel/jbanking/iban/Iban.java b/src/main/java/fr/marcwrobel/jbanking/iban/Iban.java index 336a1b4..78adf40 100644 --- a/src/main/java/fr/marcwrobel/jbanking/iban/Iban.java +++ b/src/main/java/fr/marcwrobel/jbanking/iban/Iban.java @@ -1,6 +1,7 @@ package fr.marcwrobel.jbanking.iban; import fr.marcwrobel.jbanking.IsoCountry; +import fr.marcwrobel.jbanking.checkdigit.IbanCheckDigit; import java.io.Serializable; import java.util.Optional; diff --git a/src/test/java/fr/marcwrobel/jbanking/iban/IbanCheckDigitTest.java b/src/test/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigitTest.java similarity index 92% rename from src/test/java/fr/marcwrobel/jbanking/iban/IbanCheckDigitTest.java rename to src/test/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigitTest.java index 6a14bf3..4d84c01 100644 --- a/src/test/java/fr/marcwrobel/jbanking/iban/IbanCheckDigitTest.java +++ b/src/test/java/fr/marcwrobel/jbanking/checkdigit/IbanCheckDigitTest.java @@ -1,9 +1,6 @@ -package fr.marcwrobel.jbanking.iban; +package fr.marcwrobel.jbanking.checkdigit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import com.google.common.collect.Sets; import java.util.Set; @@ -13,9 +10,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -/** - * Tests for the {@link IbanCheckDigit} class. - */ class IbanCheckDigitTest { // Generated using