-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
291 additions
and
0 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
src/main/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/Fnr.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
/** Sjekker at streng er riktig lengde, kun består av siffer, og at 6 første siffer er gyldig dato. */ | ||
private val fnrRgx = Regex( | ||
"(?:[04][1-9]|[1256]\\d|[37][01])" + // to første siffer er gyldig dag (+40 for D-nummer) | ||
"(?:[048][1-9]|[159][012])" + // to neste siffer er gyldig måned, med støtte for testpersoner (+40 for NAV, +80 for TestNorge) | ||
"\\d{7}" // resten er tall | ||
) | ||
|
||
private val sifferVekter1 = listOf(3, 7, 6, 1, 8, 9, 4, 5, 2) | ||
private val sifferVekter2 = listOf(5, 4, 3, 2, 7, 6, 5, 4, 3, 2) | ||
|
||
|
||
@Serializable | ||
@JvmInline | ||
value class Fnr(val verdi: String) { | ||
init { | ||
require(erGyldig(verdi)) | ||
} | ||
|
||
override fun toString(): String = | ||
verdi | ||
|
||
companion object { | ||
/** Les [her](https://no.wikipedia.org/wiki/F%C3%B8dselsnummer) for forklaring av regler. */ | ||
fun erGyldig(fnr: String): Boolean = | ||
if (fnr.matches(fnrRgx)) { | ||
val fnrSiffer = fnr.toList().map(Char::digitToInt) | ||
|
||
val sjekksum1 = sjekksum(fnrSiffer, sifferVekter1) | ||
val sjekksum2 = sjekksum(fnrSiffer, sifferVekter2) | ||
|
||
10 !in listOf(sjekksum1, sjekksum2) && | ||
sjekksum1 == fnrSiffer[9] && | ||
sjekksum2 == fnrSiffer[10] | ||
} else { | ||
false | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/Orgnr.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
/** Sjekker at streng er riktig lengde og kun består av siffer. */ | ||
private val orgnrRgx = Regex("\\d{9}") | ||
|
||
private val sifferVekter = listOf(3, 2, 7, 6, 5, 4, 3, 2) | ||
|
||
@Serializable | ||
@JvmInline | ||
value class Orgnr(val verdi: String) { | ||
init { | ||
require(erGyldig(verdi)) | ||
} | ||
|
||
override fun toString(): String = | ||
verdi | ||
|
||
companion object { | ||
/** Les [her](https://www.brreg.no/om-oss/registrene-vare/om-enhetsregisteret/organisasjonsnummeret/) for forklaring av regler. */ | ||
fun erGyldig(orgnr: String): Boolean = | ||
if (orgnr.matches(orgnrRgx)) { | ||
val orgnrSiffer = orgnr.toList().map(Char::digitToInt) | ||
|
||
val sjekksum = sjekksum(orgnrSiffer, sifferVekter) | ||
|
||
sjekksum != 10 && | ||
sjekksum == orgnrSiffer.last() | ||
} else { | ||
false | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/Sjekksum.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
internal fun sjekksum(siffer: List<Int>, sifferVekter: List<Int>): Int = | ||
siffer.zip(sifferVekter) | ||
.sumOf { (siffer, vekt) -> siffer * vekt } | ||
.mod(11) | ||
.let { 11 - it } | ||
.mod(11) |
81 changes: 81 additions & 0 deletions
81
src/test/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/FnrTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
import io.kotest.assertions.throwables.shouldNotThrowAny | ||
import io.kotest.assertions.throwables.shouldThrowExactly | ||
import io.kotest.core.spec.style.FunSpec | ||
import io.kotest.datatest.withData | ||
import io.kotest.matchers.shouldBe | ||
|
||
class FnrTest : FunSpec({ | ||
|
||
context("gyldig") { | ||
withData( | ||
listOf( | ||
// Sjekker ikke kontrollsiffer | ||
"01010012345", | ||
"19092212345", | ||
"29104512345", | ||
"31129912345", | ||
"25056712345", | ||
"11085812345", | ||
"41066612345", // D-nummer | ||
"45066612345", // D-nummer | ||
"50066612345", // D-nummer | ||
"57066612345", // D-nummer | ||
"60066612345", // D-nummer | ||
"69066612345", // D-nummer | ||
"70066612345", // D-nummer | ||
"71066612345", // D-nummer | ||
"01490012345", // Testperson fra NAV | ||
"01500012345", // Testperson fra NAV | ||
"01890012345", // Testperson fra TestNorge | ||
"01900012345" // Testperson fra TestNorge | ||
) | ||
) { | ||
shouldNotThrowAny { | ||
Fnr(it) | ||
} | ||
} | ||
} | ||
|
||
context("ugyldig") { | ||
withData( | ||
listOf( | ||
"00010012345", // dag 0, andre siffer feil | ||
"32010012345", // dag 32, andre siffer feil | ||
"40010012345", // dag 40, andre siffer feil (D-nummer) | ||
"72010012345", // dag 72, andre siffer feil (D-nummer) | ||
"80010012345", // dag 80, første siffer feil | ||
"01000012345", // måned 0, fjerde siffer feil | ||
"01130012345", // måned 13, fjerde siffer feil | ||
"01200012345", // måned 20, tredje siffer feil | ||
"01390012345", // måned 39, tredje og fjerde siffer feil | ||
"01400012345", // måned 40, fjerde siffer feil (testperson) | ||
"01530012345", // måned 53, fjerde siffer feil (testperson) | ||
"01790012345", // måned 79, tredje og fjerde siffer feil | ||
"01800012345", // måned 80, fjerde siffer feil (testperson) | ||
"01930012345", // måned 93, fjerde siffer feil (testperson) | ||
"0101001234", // for kort | ||
"010100123456", // for langt | ||
"010100x2345", // med bokstav | ||
"010100 1234" // med mellomrom | ||
) | ||
) { | ||
shouldThrowExactly<IllegalArgumentException> { | ||
Fnr(it) | ||
} | ||
} | ||
|
||
test("tom streng") { | ||
shouldThrowExactly<IllegalArgumentException> { | ||
Fnr("") | ||
} | ||
} | ||
} | ||
|
||
test("toString gir wrappet verdi") { | ||
Fnr("24120612345").let { | ||
it.toString() shouldBe it.verdi | ||
} | ||
} | ||
}) |
54 changes: 54 additions & 0 deletions
54
src/test/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/OrgnrTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
import io.kotest.assertions.throwables.shouldNotThrowAny | ||
import io.kotest.assertions.throwables.shouldThrowExactly | ||
import io.kotest.core.spec.style.FunSpec | ||
import io.kotest.datatest.withData | ||
import io.kotest.matchers.shouldBe | ||
|
||
class OrgnrTest : FunSpec({ | ||
|
||
context("gyldig") { | ||
withData( | ||
listOf( | ||
"161231654", | ||
"908498460", | ||
"135103210", | ||
"684603132", | ||
"167484979", | ||
"796033020" | ||
) | ||
) { | ||
shouldNotThrowAny { | ||
Orgnr(it) | ||
} | ||
} | ||
} | ||
|
||
context("ugyldig") { | ||
withData( | ||
listOf( | ||
"123", // for kort | ||
"0123456789", // for langt | ||
"12x456789", // med bokstav | ||
"1234 6789" // med mellomrom | ||
) | ||
) { | ||
shouldThrowExactly<IllegalArgumentException> { | ||
Orgnr(it) | ||
} | ||
} | ||
|
||
test("tom streng") { | ||
shouldThrowExactly<IllegalArgumentException> { | ||
Orgnr("") | ||
} | ||
} | ||
} | ||
|
||
test("toString gir wrappet verdi") { | ||
Orgnr("123456789").let { | ||
it.toString() shouldBe it.verdi | ||
} | ||
} | ||
}) |
72 changes: 72 additions & 0 deletions
72
src/test/kotlin/no/nav/helsearbeidsgiver/utils/wrapper/SjekksumTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package no.nav.helsearbeidsgiver.utils.wrapper | ||
|
||
import io.kotest.core.spec.style.FunSpec | ||
import io.kotest.datatest.withData | ||
import io.kotest.matchers.shouldBe | ||
|
||
class SjekksumTest : FunSpec({ | ||
context("gyldig") { | ||
withData( | ||
mapOf( | ||
"siffer og sifferVekter er tomme" to TestData( | ||
siffer = emptyList(), | ||
sifferVekter = emptyList(), | ||
forventetSjekksum = 0 | ||
), | ||
"siffer er tom" to TestData( | ||
siffer = emptyList(), | ||
sifferVekter = listOf(1, 2, 3), | ||
forventetSjekksum = 0 | ||
), | ||
"sifferVekter er tom" to TestData( | ||
siffer = listOf(1, 2, 3), | ||
sifferVekter = emptyList(), | ||
forventetSjekksum = 0 | ||
), | ||
"siffer er kortere enn sifferVekter" to TestData( | ||
siffer = listOf(3), | ||
sifferVekter = listOf(5, 7, 9), | ||
forventetSjekksum = 7 | ||
), | ||
"sifferVekter er kortere enn siffer" to TestData( | ||
siffer = listOf(2, 4, 6), | ||
sifferVekter = listOf(8), | ||
forventetSjekksum = 6 | ||
), | ||
"krever ikke enkeltsiffer" to TestData( | ||
siffer = listOf(13), | ||
sifferVekter = listOf(14), | ||
forventetSjekksum = 5 | ||
), | ||
"sjekksum kalkuleres korrekt (1 av 2)" to TestData( | ||
siffer = listOf(4, 4, 9), | ||
sifferVekter = listOf(9, 3, 4), | ||
forventetSjekksum = 4 | ||
), | ||
"sjekksum kalkuleres korrekt (2 av 2)" to TestData( | ||
siffer = listOf(4, 8, 4, 8), | ||
sifferVekter = listOf(3, 8, 2, 1), | ||
forventetSjekksum = 7 | ||
), | ||
"sjekksum er tosifret" to TestData( | ||
siffer = listOf(3, 1, 0, 5, 3), | ||
sifferVekter = listOf(6, 8, 4, 2, 3), | ||
forventetSjekksum = 10 | ||
), | ||
"sjekksum er 0" to TestData( | ||
siffer = listOf(7, 5, 6, 5, 1, 2, 1), | ||
sifferVekter = listOf(0, 6, 0, 9, 9, 2, 0), | ||
forventetSjekksum = 0 | ||
), | ||
) | ||
) { | ||
sjekksum(it.siffer, it.sifferVekter) shouldBe it.forventetSjekksum | ||
} | ||
} | ||
}) | ||
|
||
private data class TestData( | ||
val siffer: List<Int>, | ||
val sifferVekter: List<Int>, | ||
val forventetSjekksum: Int | ||
) |