Skip to content

Instantly share code, notes, and snippets.

@cristobal
Last active July 10, 2020 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cristobal/1170460 to your computer and use it in GitHub Desktop.
Save cristobal/1170460 to your computer and use it in GitHub Desktop.
Validate Norwegian Organization Number
<?php
/**
* Validate orgnr
* Validates an string number according to the brreg spec
* https://www.brreg.no/om-oss/oppgavene-vare/alle-registrene-vare/om-enhetsregisteret/organisasjonsnummeret/
*
* Test case: https://repl.it/repls/TechnicalForcefulBsddaemon
*
* @param <string> $value
*/
function validate_orgnr($value) {
if (!preg_match("/^\d{9}$/", $value, $matches)) {
throw new \Exception("Value must be a sequence of 9 numbers (value: {$value})");
}
$numbers = array_map(
function ($value) { return intval($value); },
str_split($matches[0])
);
$weights = array( 3, 2, 7, 6, 5, 4, 3, 2 );
$products = array_map(
function ($weight, $index) use($numbers) { return $numbers[$index] * $weight; },
$weights,
array_keys($weights)
);
$sum = array_reduce(
$products,
function ($acc, $product) { return $acc + $product; },
0
);
$mod11 = 11;
$rem = $sum % $mod11;
$cn = $rem == 0
? 0
: $mod11 - $rem;
if ($cn >= 10) {
return false;
}
return $cn === $numbers[8];
}
/**
* Validate orgnr
* Validates an string number according to the brreg spec
* https://www.brreg.no/om-oss/oppgavene-vare/alle-registrene-vare/om-enhetsregisteret/organisasjonsnummeret/
*
* Test case https://repl.it/@cristobal1/HappyVengefulDiscussion
*
* @param {string} value
*/
function validate_orgnr (value) {
const pattern = /^\d{9}$/
if (!pattern.test(value)) {
throw new Error(`Value must be a sequence of 9 numbers (value: ${value})`)
}
const numbers = String(value).split('').map(value => Number(value))
const weights = [ 3, 2, 7, 6, 5, 4, 3, 2 ]
const products = weights.map((value, index) => numbers[index] * value)
const sum = products.reduce((acc, product) => acc + product, 0)
const mod11 = 11
const rem = sum % mod11
const cn = rem === 0
? 0
: mod11 - rem
if (cn >= 10) {
return false
}
return cn === numbers[8]
}
@davidstrompremium
Copy link

for those having trubble with valid numbers getting $value -11 with this:

”Hvis divisjonen går opp (rest = 0) blir kontrollsifferet 0”

"If the division goes up (remainder = 0) the control digit becomes 0"

so i had to add a:
if($rest == 0 && $cn == 0)
{
return true;
}

@cristobal
Copy link
Author

cristobal commented Jul 8, 2020

@davistrompremium interesting seeing someone refering to this gist i made 9 years ago in 2001 😛.

Updates

I updated the code so it more reflects the current spec and the edge cases i.e:

  • When the remainder is 0 then the control number is 0
  • When the control number is greater than or equal to 10 then we have an invalid control number

Also the last check is checking whether the calculated control number matches the last digit in the organization number which is the control number.

Background story

I also remember that this code snippet was related to an online registry for companies interesting in joining TV-Aksjonen in 2001 through an website so we had to validate the organization number they typed into a submission form.

When i was working with this project there was no implementations out in the wild which there is now like:

@cristobal
Copy link
Author

Also seems like the nor-id-num (C#) project does a check whether the first digit in the organzation number is an 8 or 9, still that is not a part of the BBREG spec.

@davidstrompremium
Copy link

davidstrompremium commented Jul 10, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment