<?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] | |
} |
@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 is0
- 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:
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.
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;
}