orangitfi / finnpic

A Scala implementation of Finnish PIC (Personal Identity Code)("henkilötunnus" in Finnish).

Version Matrix

Codacy Badge Codacy Badge sbt test Maven Central


Flag of Finland

A Scala implementation of Finnish PIC (Personal Identity Code)("henkilötunnus" in Finnish).

See the specification here: https://vrk.fi/en/personal-identity-code1.


You need to have SDKMAN and direnv installed.

Put this in your ~/.direnvrc:

# https://github.com/direnv/direnv/issues/420
# iterate on pairs of [candidate] [version] and invoice `sdk use` on each of them
use_sdk() {
  [[ -s "${SDKMAN_DIR}/bin/sdkman-init.sh" ]] && source "${SDKMAN_DIR}/bin/sdkman-init.sh"

  while (( "$#" >= 2 )); do
    local candidate=$1
    local candidate_version=$2
    sdk use $candidate $candidate_version

    shift 2

cd to the root of the project and say direnv allow.

Install the required versions of Java, Scala and Sbt using SDKMAN.

Full build with test coverage (which should stay at 100%) measurement:

sbt clean coverage test coverageReport



There is a safe way and an unsafe way to make instances of Pic.

The safe way is to use Pic.fromString, which returns instances of Either (in Scala standard library). Left(errorMessage) means that the given PIC was invalid, the error message inside tells you why. Right(pic) means the PIC was valid and now you can obtain the value from the right side of the Either. This is a very common pattern in functional programming.

Use the safe way if the PIC value (the string) is coming from a user or some other undependable source.

The safe way, used successfully on a valid PIC:

// The safe way, success:
val p = Pic.fromString("070377-281V")
// ^ p is now Right(Pic(...))

The safe way, failing:

p = Pic.fromString("foo")
// ^ p is now Left("some error message")

The unsafe way is to use Pic.fromStringUnsafe, or its alias Pic.fromStringU (which does the same thing, but is shorter to type and read). The unsafe variants return a Pic object directly on success (the PIC is valid). If the PIC is not valid, these functions throw an exception (a java.lang.IllegalArgumentException, to be more precise).

Use the unsafe way when the PIC value comes from a dependable source (for example, from a database column where you know that only valid values are stored).

val p: Pic = Pic.fromStringUnsafe("070377-281V")
// ^ p is now Pic(...)

p = Pic.fromStringUnsafe("foo")
// ^ throws IllegalArgumentException

// There is also Pic.fromStringU, which is just an
// alias for Pic.fromStringUnsafe.

Publishing a new version

Open an sbt shell and run:

+ coverageOff

+ clean

+ publishSigned

Don't forget the plus signs (for cross compilation and cross publishing)!

As for your GPG keys and stuff, see https://www.scala-sbt.org/1.x/docs/Using-Sonatype.html and https://github.com/keybase/keybase-issues/issues/2798.


This project is proudly supported by Orangit Oy.

Orangit Oy