Skip to content

Commit

Permalink
Merge pull request #24 from cominvent/kid-generering
Browse files Browse the repository at this point in the history
KID number generator
  • Loading branch information
eivinhb authored Jan 11, 2018
2 parents c8f5eaa + 5cdb879 commit 13a7091
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 78 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Maven Site: [http://bekkopen.github.com/NoCommons/](http://bekkopen.github.com/N
* validering
* Bank
* Kontonummer validering og generering
* KID generering
* KID validering
* Norsk språk o.l.
* Konvertering av norske bokstaver i en tekst til de engelske erstatningene aa, ae og oe
Expand All @@ -28,11 +29,8 @@ Maven Site: [http://bekkopen.github.com/NoCommons/](http://bekkopen.github.com/N
* Sjekk om dato er arbeidsdag (dvs. ikke helligdag eller helg)
* Legg til x antall arbeidsdager til en gitt dato
* Liste ut alle helligdager


## Features som ikke er implementert, men som kan passe inn
* Bank
* KID generator
* Fylkesnummer
* Finn fylkesnummer for fylke
* Finn fylke for fylkesnummer
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,6 @@
<project-info-reports-plugin.version>2.4</project-info-reports-plugin.version>
<!-- Other properties -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk>1.5</project.jdk>
<project.jdk>1.6</project.jdk>
</properties>
</project>
57 changes: 54 additions & 3 deletions src/main/java/no/bekk/bekkopen/banking/Kidnummer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,66 @@

import no.bekk.bekkopen.common.StringNumber;

import java.math.BigInteger;

import static no.bekk.bekkopen.common.Checksums.*;

/**
* This class represent a Norwegian KID-nummer - a number used to identify
* a customer on invoices. A Kidnummer consists of digits only, and the last
* digit is a checksum digit (either mod10 or mod11).
*/
public class Kidnummer extends StringNumber {

Kidnummer(String kontonummer) {
super(kontonummer);

Kidnummer(String kidnummer) {
super(kidnummer);
}

/**
* Return a valid mod10 Kidnummer by adding checksum digit
* @param baseNumber input number, digits only
* @return Kidnummer
*/
public static Kidnummer mod10Kid(String baseNumber) {
return Kidnummer.mod10Kid(baseNumber, baseNumber.length()+1);
}

/**
* Create a valid KID numer of the wanted length, using MOD10.
* Input is padded with leading zeros to reach wanted target length
* @param baseNumber base number to calculate checksum digit for
* @param targetLength wanted length, 0-padded. Between 2-25
* @return Kidnummer
*/
public static Kidnummer mod10Kid(String baseNumber, int targetLength) {
if (baseNumber.length() >= targetLength)
throw new IllegalArgumentException("baseNumber too long");
String padded = String.format("%0" + (targetLength-1) + "d", new BigInteger(baseNumber));
Kidnummer k = new Kidnummer(padded + "0");
return KidnummerValidator.getKidnummer(padded + calculateMod10CheckSum(getMod10Weights(k), k));
}

/**
* Return a valid mod10 Kidnummer by adding checksum digit
* @param baseNumber input number, digits only
* @return Kidnummer
*/
public static Kidnummer mod11Kid(String baseNumber) {
return Kidnummer.mod11Kid(baseNumber, baseNumber.length()+1);
}

/**
* Create a valid KID numer of the wanted length, using MOD11.
* Input is padded with leading zeros to reach wanted target length
* @param baseNumber base number to calculate checksum digit for
* @param targetLength wanted length, 0-padded. Between 2-25
* @return Kidnummer
*/
public static Kidnummer mod11Kid(String baseNumber, int targetLength) {
if (baseNumber.length() >= targetLength)
throw new IllegalArgumentException("baseNumber too long");
String padded = String.format("%0" + (targetLength-1) + "d", new BigInteger(baseNumber));
Kidnummer k = new Kidnummer(padded + "0");
return KidnummerValidator.getKidnummer(padded + calculateMod11CheckSum(getMod11Weights(k), k));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import static no.bekk.bekkopen.common.Checksums.*;

public class KidnummerValidator extends StringNumberValidator implements ConstraintValidator<no.bekk.bekkopen.banking.annotation.Kidnummer, String> {

public static final String ERROR_LENGTH = "A Kidnummer is between 2 and 25 digits";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static no.bekk.bekkopen.common.Checksums.calculateMod11CheckSum;
import static no.bekk.bekkopen.common.Checksums.getMod11Weights;

/**
* Provides methods that validates if a Kontonummer is valid with respect to
* syntax (length and digits only) and that the checksum digit is correct.
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/no/bekk/bekkopen/common/Checksums.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package no.bekk.bekkopen.common;

public class Checksums {
public static final String ERROR_INVALID_CHECKSUM = "Invalid checksum : ";
private static int[] BASE_MOD11_WEIGHTS = new int[]{2, 3, 4, 5, 6, 7};

/**
* Calculate the check sum for the given weights and number.
*
* @param weights The weights
* @param number The number
* @return The checksum
*/
public static int calculateMod11CheckSum(int[] weights, StringNumber number) {
int c = calculateChecksum(weights, number, false) % 11;
if (c == 1) {
throw new IllegalArgumentException(ERROR_INVALID_CHECKSUM + number);
}
return c == 0 ? 0 : 11 - c;
}

/**
* Calculate the check sum for the given weights and number.
*
* @param weights The weights
* @param number The number
* @return The checksum
*/
public static int calculateMod10CheckSum(int[] weights, StringNumber number) {
int c = calculateChecksum(weights, number, true) % 10;
return c == 0 ? 0 : 10 - c;
}

public static int calculateChecksum(int[] weights, StringNumber number, boolean tverrsum) {
int checkSum = 0;
for (int i = 0; i < weights.length; i++) {
int product = weights[i] * number.getAt(weights.length - 1 - i);
if (tverrsum) {
checkSum += (product > 9 ? product - 9 : product);
} else {
checkSum += product;
}
}
return checkSum;
}

public static int[] getMod10Weights(StringNumber k) {
int[] weights = new int[k.getLength() - 1];
for (int i = 0; i < weights.length; i++) {
if ((i % 2) == 0) {
weights[i] = 2;
} else {
weights[i] = 1;
}
}
return weights;
}

public static int[] getMod11Weights(StringNumber k) {
int[] weights = new int[k.getLength() - 1];
for (int i = 0; i < weights.length; i++) {
int j = i % BASE_MOD11_WEIGHTS.length;
weights[i] = BASE_MOD11_WEIGHTS[j];
}
return weights;
}

}
68 changes: 1 addition & 67 deletions src/main/java/no/bekk/bekkopen/common/StringNumberValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,12 @@
*/
public abstract class StringNumberValidator {

public static final String ERROR_INVALID_CHECKSUM = "Invalid checksum : ";

public static final String ERROR_SYNTAX = "Only digits are allowed : ";

private static int[] BASE_MOD11_WEIGHTS = new int[]{2, 3, 4, 5, 6, 7};


protected StringNumberValidator() {
super();
}

/**
* Calculate the check sum for the given weights and number.
*
* @param weights The weights
* @param number The number
* @return The checksum
*/
protected static int calculateMod11CheckSum(int[] weights, StringNumber number) {
int c = calculateChecksum(weights, number, false) % 11;
if (c == 1) {
throw new IllegalArgumentException(ERROR_INVALID_CHECKSUM + number);
}
return c == 0 ? 0 : 11 - c;
}

/**
* Calculate the check sum for the given weights and number.
*
* @param weights The weights
* @param number The number
* @return The checksum
*/
protected static int calculateMod10CheckSum(int[] weights, StringNumber number) {
int c = calculateChecksum(weights, number, true) % 10;
return c == 0 ? 0 : 10 - c;
}

private static int calculateChecksum(int[] weights, StringNumber number, boolean tverrsum) {
int checkSum = 0;
for (int i = 0; i < weights.length; i++) {
int product = weights[i] * number.getAt(weights.length - 1 - i);
if (tverrsum) {
checkSum += (product > 9 ? product - 9 : product);
} else {
checkSum += product;
}
}
return checkSum;
}

protected static void validateLengthAndAllDigits(String numberString,
int length) {
if (numberString == null || numberString.length() != length) {
Expand All @@ -74,26 +30,4 @@ protected static void validateAllDigits(String numberString) {
}
}
}

protected static int[] getMod10Weights(StringNumber k) {
int[] weights = new int[k.getLength() - 1];
for (int i = 0; i < weights.length; i++) {
if ((i % 2) == 0) {
weights[i] = 2;
} else {
weights[i] = 1;
}
}
return weights;
}

protected static int[] getMod11Weights(StringNumber k) {
int[] weights = new int[k.getLength() - 1];
for (int i = 0; i < weights.length; i++) {
int j = i % BASE_MOD11_WEIGHTS.length;
weights[i] = BASE_MOD11_WEIGHTS[j];
}
return weights;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static no.bekk.bekkopen.common.Checksums.calculateMod11CheckSum;
import static no.bekk.bekkopen.common.Checksums.getMod11Weights;

/**
* Provides methods that validates if an Organisasjonsnummer is valid with
* respect to syntax (length and digits only) and that the checksum digit is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static no.bekk.bekkopen.common.Checksums.calculateMod11CheckSum;

/**
* Provides methods that validates if a Fodselsnummer is valid with respect to
* syntax, Individnummer, Date and checksum digits.
Expand Down
54 changes: 54 additions & 0 deletions src/test/java/no/bekk/bekkopen/banking/KidnummerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package no.bekk.bekkopen.banking;

import org.junit.Test;

import static org.junit.Assert.*;

public class KidnummerTest {
@Test
public void mod10Kid() throws Exception {
assertValidKid("0000001230", Kidnummer.mod10Kid("123", 10));
assertValidKid("0000012344", Kidnummer.mod10Kid("1234", 10));
}

@Test
public void mod11Kid() throws Exception {
assertValidKid("0000001236", Kidnummer.mod11Kid("123", 10));
assertValidKid("0000012343", Kidnummer.mod11Kid("1234", 10));
}

@Test(expected = IllegalArgumentException.class)
public void tooLongBaseMod10() {
Kidnummer.mod10Kid("1234567890", 3);
}

@Test(expected = IllegalArgumentException.class)
public void tooLongBaseMod101() {
Kidnummer.mod11Kid("1234567890", 3);
}

@Test(expected = IllegalArgumentException.class)
public void belowRangeMod10() {
Kidnummer.mod10Kid("12", 1);
}

@Test(expected = IllegalArgumentException.class)
public void belowRangeMod11() {
Kidnummer.mod11Kid("12", 1);
}

@Test(expected = IllegalArgumentException.class)
public void aboveRangeMod10() {
Kidnummer.mod10Kid("12", 26);
}

@Test(expected = IllegalArgumentException.class)
public void aboveRangeMod11() {
Kidnummer.mod11Kid("12", 26);
}

private void assertValidKid(String expected, Kidnummer kidnummer) {
KidnummerValidator.isValid(kidnummer.toString());
assertEquals(expected, kidnummer.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.junit.Test;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static org.junit.Assert.*;

public class KidnummerValidatorTest extends NoCommonsTestCase {
Expand Down Expand Up @@ -61,7 +62,7 @@ public void testInvalidKidnummerWrongChecksum() {
KidnummerValidator.validateChecksum(KIDNUMMER_INVALID_CHECKSUM);
fail();
} catch (IllegalArgumentException e) {
assertMessageContains(e, StringNumberValidator.ERROR_INVALID_CHECKSUM);
assertMessageContains(e, ERROR_INVALID_CHECKSUM);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.bekk.bekkopen.banking;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand Down Expand Up @@ -38,7 +39,7 @@ public void testInvalidKontonummerWrongChecksum() {
KontonummerValidator.validateChecksum(KONTONUMMER_INVALID_CHECKSUM);
fail();
} catch (IllegalArgumentException e) {
assertMessageContains(e, KontonummerValidator.ERROR_INVALID_CHECKSUM);
assertMessageContains(e, ERROR_INVALID_CHECKSUM);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.bekk.bekkopen.org;

import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand Down Expand Up @@ -38,7 +39,7 @@ public void testInvalidOrgnummerWrongChecksum() {
OrganisasjonsnummerValidator.validateChecksum(ORGNUMMER_INVALID_CHECKSUM);
fail();
} catch (IllegalArgumentException e) {
assertMessageContains(e, OrganisasjonsnummerValidator.ERROR_INVALID_CHECKSUM);
assertMessageContains(e, ERROR_INVALID_CHECKSUM);
}
}

Expand Down
Loading

0 comments on commit 13a7091

Please sign in to comment.