NAME
Business::DK::CPR - Danish CPR (SSN) number generator/validator
VERSION
This documentation describes version 0.16
SYNOPSIS
use Business::DK::CPR qw(validate);
my $rv;
eval { $rv = validate(1501721111); };
if ($@) {
die "Code is not of the expected format - $@";
}
if ($rv) {
print 'CPR is valid';
} else {
print 'CPR is not valid';
}
use Business::DK::CPR qw(calculate);
my @cprs = calculate(150172);
my $number_of_valid_cprs = calculate(150172);
#Using with Params::Validate
#See also examples/
use Params::Validate qw(:all);
use Business::DK::CPR qw(validateCPR);
sub check_cpr {
validate( @_,
{ cpr =>
{ callbacks =>
{ 'validate_cpr' => sub { validateCPR($_[0]); } } } } );
print $_[1]." is a valid CPR\n";
}
DESCRIPTION
CPR stands for Central Person Registration and is the social security number used in Denmark.
SUBROUTINES AND METHODS
All methods are exported by explicit request. None are exported implicitly.
validate
This function checks a CPR number for validity. It takes a CPR number as argument and returns:
1 (true) for valid male CPR number
2 (true) for a valid female CPR number
0 (false) for invalid CPR number
It dies if the CPR number is malformed or in any way unparsable, be aware that the 6 first digits are representing a date (SEE: _checkdate function below).
In brief, the date indicate the person's birthday, the last 4 digits are representing a serial number and control cipher.
For a more thorough discussion on the format of CPR numbers please refer to the SEE ALSO section.
validate1968 is the old form of the CPR number. It is validated using modulus 11.
The new format introduced in 2001 (put to use in 2007, hence the name used throughout this package) can be validated using validate2007 and generate using generate2007.
The validate subroutine wraps both validators and checks using against both.
The generate subroutine wraps both generators and accumulated the results.
NB! it is possible to make fake CPR numbers that appear valid, please see MOTIVATION and the "calculate" function.
validate is also exported as: validateCPR, which is less imposing.
validateCPR
Better name for export. This is just a wrapper for "validate"
validate1968
Validation against the original CPR algorithm introduced in 1968.
validate2007
Validation against the CPR algorithm introduced in 2007.
generate
This is a wrapper around calculate, so the naming is uniform to Business::DK::CVR
This function takes an integer representing a date and calculates valid CPR numbers for the specified date. In scalar context returns the number of valid CPR numbers possible and in list context a list of valid CPR numbers.
If the date is malformed or in any way invalid or unspecified the function dies.
generate1968
Specialized generator for validate1968 compatible CPR numbers. See: generate
generate2007
Specialized generator for validate2007 compatible CPR numbers. See: generate
calculate
See generate and generate1968. This is the old name for generate1968. It is just kept for backwards compatibility and it calls generate.
merge
Mimics Hash::Merge's merge function. Takes two references to hashes and returns a single reference to a hash containing the merge of the two with the left parameter having precedence. The precedence has not meaning on the case in this module, but then the behaviour is documented.
PRIVATE FUNCTIONS
_length
This function validates the length of the argument, it dies if the argument does not fit within the boundaries specified by the arguments provided:
The _length function takes the following arguments:
_assertdate
This subroutine takes a digit integer representing a date in the format: DDMMYY.
The date is checked for definedness, contents and length and finally, the correctness of the date.
The subroutine returns 1 indicating true upon successful assertion or dies upon failure.
_checkdate
This subroutine takes a 6 digit integer representing a date in the format: DDMMYY.
The subroutine returns 1 indicating true upon successful check or dies upon failure.
_assert_controlnumber
This subroutine takes an 10 digit integer representing a complete CPR. The CPR is tested for definedness, contents and length.
The subroutine returns 1 indicating true upon successful assertion or dies upon failure.
EXPORTS
Business::DK::CPR exports on request:
DIAGNOSTICS
'argument for birthdate should be provided', a data parameter has to be provided.
This error is thrown from _checkdate, which is used for all general parameter validation.
'argument: <birthdate> could not be parsed', the date provided is not represented by 6 digits (see also below).
This error is thrown from _checkdate, which is used for all general parameter validation.
'argument: <birthdate> has to be a valid date in the format: ddmmyy', the date format used for CPR numbers has to adhere to ddmmyy in numeric format like so: 311210, day in a two digit representation: 01-31, month also two digit representation: 01-12 and finally year in a two digit representation: 00-99.
This error is thrown from _checkdate, which is used for all general parameter validation.
'Unknown gender: <gender>, assuming no gender', this is just a warning issued if a call to generate2007 has not been provided with a gender parameter
DEPENDENCIES
CONFIGURATION AND ENVIRONMENT
This module requires no special configuration or environment.
INCOMPATIBILITIES
There are no known incompatibilies in this package.
TODO
Nothing to do, please refer to the distribution TODO file for the general wish list and ideas for future expansions and experiments.
TEST AND QUALITY
The distribution uses the TEST_AUTHOR environment variable to run some additional tests, which are interesting to the the author, these can be disabled by not defining or setting the environment variable to something not positive.
The distribution uses the TEST_CRITIC environment variable to control Perl::Critic tests.
STANDARD TESTS
Here are listed the standard tests, recommended for all CPAN-like distributions. The matrix lists what flags are required to run the specific test.
NONE TEST_AUTHOR TEST_CRITIC TEST_POD
--------------- ---- ----------- ----------- --------
00.load.t *
changes.t *
critic.t *
kwalitee.t *
pod-coverage.t *
pod.t *
prerequisites.t *
--------------- ---- ----------- ----------- --------
All of the above tests are actually boilerplates and are maintained as separate components.
TEST COVERAGE
Coverage of the test suite is at 89.1% for release 0.04, the coverage report was generated with the TEST_AUTHOR flag enabled (SEE: TEST AND QUALITY)
---------------------------- ------ ------ ------ ------ ------ ------ ------
File stmt bran cond sub pod time total
---------------------------- ------ ------ ------ ------ ------ ------ ------
blib/lib/Business/DK/CPR.pm 74.2 41.9 53.8 100.0 100.0 72.9 70.3
.../Class/Business/DK/CPR.pm 89.1 85.7 77.8 71.4 100.0 27.1 86.0
Total 77.6 50.0 63.6 91.3 100.0 100.0 74.1
---------------------------- ------ ------ ------ ------ ------ ------ ------
PERL::CRITIC
This section describes use of Perl::Critic from a perspective of documenting additions and exceptions to the standard use.
Perl::Critic::Policy::Miscellanea::ProhibitTies
This package utilizes Tie::IxHash (SEE: DEPENDENCIES), this module relies on tie.
Perl::Critic::Policy::NamingConventions::NamingConventions::Capitalization
CPR is an abbreviation for 'Centrale Person Register' (Central Person Register) and it is kept in uppercase.
Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs deprecated by the policy above.
Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma
Constants are good in most cases, see also: http://logicLAB.jira.com/wiki/display/OPEN/Perl-Critic-Policy-ValuesAndExpressions-ProhibitConstantPragma
Perl::Critic::Policy::ValuesAndExpressions::ProhibitMagicNumbers
Some values and boundaries are defined for certain intervals of numbers, these are currently kept as is. Perhaps with a refactoring of the use of constants to use of Readonly will address this.
BUGS AND LIMITATIONS
No known bugs at this time.
Business::DK::CPR has some obvious flaws. The package can only check for validity and format, whether a given CPR has been generated by some random computer program and just resemble a CPR or whether a CPR has ever been assigned to a person is not possible without access to central CPR database an access, which is costly, limited and monitored.
There are no other known limitations apart from the obvious flaws in the CPR system (See: SEE ALSO).
BUG REPORTING
BUG REPORTING
Please report issue via GitHub
L<https://github.com/jonasbn/perl-business-dk-cpr/issues>
Alternatively report issues via CPAN RT:
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Business-DK-CPR>
or by sending mail to
bug-Business-DK-CPR@rt.cpan.org
SEE ALSO
MOTIVATION
I write business related applications. So I need to be able to validate CPR numbers once is a while, hence the validation function.
The calculate/generate1968 function is however a different story. When I was in school we where programming in Comal80 and some of the guys in my school created lists of CPR numbers valid with their own birthdays. The thing was that if you got caught riding the train without a valid ticket the personnel would only check the validity of you CPR number, so all you have to remember was your birthday and 4 more digits not being the actual last 4 digits of your CPR number.
I guess this was the first hack I ever heard about and saw - I never tried it out, but back then it really fascinated me and my interest in computers was really sparked.
AUTHOR
Jonas B., (jonasbn) -
<jonasbn@cpan.org>
ACKNOWLEDGEMENTS
Karen Etheridge (ETHER)
Neil Bowers (NEILB)
COPYRIGHT
Business-DK-CPR and related is (C) by Jonas B., (jonasbn) 2006-2020
LICENSE
Business-DK-CPR is released under the Artistic License 2.0