| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import java.util.stream.IntStream;
-
- public class Luhn {
-
- private long number;
- private long checkDigit;
- private int[] addends;
- private int checkSum;
- private boolean isValid;
-
- public Luhn(long number) {
- this.number = number;
- this.checkDigit = number % 10;
- this.addends = generateAddends();
- this.checkSum = IntStream.of(addends).sum();
- this.isValid = checkSum % 10 == 0;
- }
-
- public long getCheckDigit() {
- return checkDigit;
- }
-
- public int[] getAddends() {
- return addends;
- }
-
- public int getCheckSum() {
- return checkSum;
- }
-
- public boolean isValid() {
- return isValid;
- }
-
- private int[] generateAddends() {
- int[] reversedIntArray = splitToReversedIntArray(number);
-
- for (int index = 1; index < reversedIntArray.length; index++) {
- if (index % 2 != 0) {
- reversedIntArray[index] = convertDigitForAddend(reversedIntArray[index]);
- }
- }
-
- return reverseIntArray(reversedIntArray);
- }
-
- private static int[] splitToReversedIntArray(long value) {
- int[] ints = new StringBuilder(Long.toString(value))
- .reverse()
- .toString()
- .chars()
- .map(x -> Character.getNumericValue(x))
- .toArray();
-
- return ints;
- }
-
- private static int convertDigitForAddend(int value) {
- int doubled = value * 2;
-
- return doubled < 10 ? doubled : doubled - 9;
- }
-
- public static long create(long number) {
- long zeroCheckDigitNumber = number * 10;
- Luhn luhn = new Luhn(zeroCheckDigitNumber);
-
- if (luhn.isValid()) {
- return zeroCheckDigitNumber;
- }
-
- return zeroCheckDigitNumber + createCheckDigit(luhn.getCheckSum());
- }
-
- private static int createCheckDigit(int value) {
- int nearestTen = (int) (Math.ceil(value / 10.0) * 10);
-
- return nearestTen - value;
- }
-
- private static int[] reverseIntArray(int[] array) {
- int[] reversed = new int[array.length];
-
- for (int index = 0; index < array.length; index++) {
- reversed[index] = array[array.length - 1 - index];
- }
-
- return reversed;
- }
- }
|