In the first part we've layed out the basic requirements and had a glance of the data the class would model. In short it would model a SSN-like identificator for romanian citizens.

Let's see what properties and methods the class should expose and what interfaces should be implemented and how.

Basic data :

  • Sex
  • Foreigner or native
  • Resident
  • Birth date
  • Birth county
  • Index
  • Check digit

Extra information :

  • The raw value
  • A list of violations (if any)
  • A boolean to quickly see if the instance is valid or not

Let's make a quick range check and see what data type we could choose for the underlying (raw) value :

The smallest valid PNC could be 1010100010011 (male, January 1st, 1900, born in Alba, first born in that day and the last digit, the check digit I am too lazy to compute it - we'll see later and - its value won't change the calculations much). The largest valid could be 9311299529999 (non-resident foreigner born on December 31st, 1999 and so on..).

The range would be 9311299529999 - 1010100010011 = 8,301,199,519,988

Now this is larger than Int32's (2 billion and something) and UInt32's (4 billion and something) maximum values so Int64 is the smallest numeric data type that could fit the raw value. It also fits the value without using an offset (having the raw value stored as a difference between a minimum value and the actual value) which simplifies the storage logic.

Having it fit in an Int64 is reassuring that at least on 64bits OSs + CPUs the operations on it will be fast.

Let's go back to the public properties now. The sex property could have been a simple boolean and set up a convention to set true for one sex and false for the other (I won't go in deep phylosophical discussion whether men or women are "true" :P ). However value 9 for the first digit screws things up as it does not specify the sex. Sure, a nullable boolean could be in order but I will choose an enum over this one. Let's call it PersonBirthSex and assign three values for it : Male, Female and Unknown (for 9'ers).

The Foreigner property can very well be a bool just like Resident.
The BirthDate will be a DateTime.
For the county of birth an enum will fit the bill.
Index is always positive and has values from 1 to 999 inclusive. So the nicest fit will be the UInt16 (ushort) type.
The check digit is from 1 to 9 inclusive so a byte should do the trick.

Having settled on the public properties, their types and the raw value type we'll see the validation part.

As I said in the beginning the instance of the class should be able to report zero, one or more violations that it may contain. For a quick check it will also expose a bool that we'll call "IsValid". Let's end the analysys in the next episode.