snippetcppMinor
Generate the Norwegian equivalent to social security numbers
Viewed 0 times
socialtheequivalentnumbersgeneratesecuritynorwegian
Problem
This is just a little hobby project I've been working on. I've been using it to learn/improve my knowledge of C++.
The program generate Norwegian personal-numbers (11 digits) for males born a given year. It works just fine, but I'd like some input on how to improve the code. For now I have a basic class structure.
Norwegian personal-numbers is built up like this.
```
#include
using namespace std;
const int DATE_LENGTH = 6;
const int BUFFER = 30;
class ID {
private:
int date[DATE_LENGTH];
int i1, i2, i3;
int k1, k2;
int year;
public:
ID(int i1 = 0, int i2 = 0, int i3 = 0, int k1 = 0, int k2 = 0) {
for (int i = 0; i year = year;
}
int getYear() {
return year;
}
void individSiffer() {
static int individ = -1;
if(year >= 1900 && year <= 1999 ){
individ++;
i1 = i2 = i3 = 0;
}
i3 = individ % 10;
if(individ < 100){
i1 = 0;
i2 = individ / 10 % 10;
}else if(individ < 10){
i1 = i2 = 0;
}else{
i1 = individ / 100 % 10;
i2 = individ / 10 % 10;
}
}
void generate() {
k1 = 11 - ((3date[0] + 7date[1] + 6date[2] + 1date[3] + 8date[4] + 9date[5] + 4i1 + 5i2 + 2*i3) % 11);
if(k1 == 11){
k1 = 0;
}
k2 = 11 - ((5date[0] + 4date[1] + 3date[2] + 2date[3] + 7date[4] + 6date[5] + 5i1 + 4i2 + 3i3 + 2k1) % 11);
if(k2 == 11){
k2 = 0;
}
if((i3 != 0 && i3 != 2 && i3 !=4 && i3 !=6 && i3 !=8) && (k1 != 10 && k2 !=10)){
for (int i = 0; i < DATE_LENGTH; i++) {
printf("%d", date[i]);
}
printf("%d%d%d%d%d\n", i1, i2, i3
The program generate Norwegian personal-numbers (11 digits) for males born a given year. It works just fine, but I'd like some input on how to improve the code. For now I have a basic class structure.
Norwegian personal-numbers is built up like this.
```
#include
using namespace std;
const int DATE_LENGTH = 6;
const int BUFFER = 30;
class ID {
private:
int date[DATE_LENGTH];
int i1, i2, i3;
int k1, k2;
int year;
public:
ID(int i1 = 0, int i2 = 0, int i3 = 0, int k1 = 0, int k2 = 0) {
for (int i = 0; i year = year;
}
int getYear() {
return year;
}
void individSiffer() {
static int individ = -1;
if(year >= 1900 && year <= 1999 ){
individ++;
i1 = i2 = i3 = 0;
}
i3 = individ % 10;
if(individ < 100){
i1 = 0;
i2 = individ / 10 % 10;
}else if(individ < 10){
i1 = i2 = 0;
}else{
i1 = individ / 100 % 10;
i2 = individ / 10 % 10;
}
}
void generate() {
k1 = 11 - ((3date[0] + 7date[1] + 6date[2] + 1date[3] + 8date[4] + 9date[5] + 4i1 + 5i2 + 2*i3) % 11);
if(k1 == 11){
k1 = 0;
}
k2 = 11 - ((5date[0] + 4date[1] + 3date[2] + 2date[3] + 7date[4] + 6date[5] + 5i1 + 4i2 + 3i3 + 2k1) % 11);
if(k2 == 11){
k2 = 0;
}
if((i3 != 0 && i3 != 2 && i3 !=4 && i3 !=6 && i3 !=8) && (k1 != 10 && k2 !=10)){
for (int i = 0; i < DATE_LENGTH; i++) {
printf("%d", date[i]);
}
printf("%d%d%d%d%d\n", i1, i2, i3
Solution
Comment on C++ interface:
You are doing work outside of ID that belongs as part of the class:
Because this work is not part of a method you are exposing implementation details of your ID class via getter methods. All of which is bad:
A better interface would have been:
Comments on Code
Don't use this interface.
What happens if the user types an extra long line of stuff.
Its not going to crash but you are left with lots of crap on the input stream. User input is line based so read a line from the user and then try and parse the line. Because a line can be any length don't use that version of get line.
Comments on C functions
C based functions for printing
Comments on Data values
What about people born after 31st Dec 1999?
Comments on Loop structures
Also notice that I am declaring my loop variable as close to the point of usage as possible. Do not use the C style of putting all the variables at the top of the function. Put your variables where you can see there declaration and type easily.
You are doing work outside of ID that belongs as part of the class:
ID generator;
for(int i = 0; i < DATE_LENGTH; i++){
*(generator.getDate() + i) = int(dateString[i]-'0');
}
generator.setYear(1900 + (*(generator.getDate() + 4) * 10) + *(generator.getDate() + 5));
while(i < 500){
generator.individSiffer();
generator.generate();
i++;
}Because this work is not part of a method you are exposing implementation details of your ID class via getter methods. All of which is bad:
A better interface would have been:
std::string date = getDate(); // Get a valid date or throw.
ID generator(date);
std::cout << generator;Comments on Code
Don't use this interface.
What happens if the user types an extra long line of stuff.
cin.getline(dateString, BUFFER);Its not going to crash but you are left with lots of crap on the input stream. User input is line based so read a line from the user and then try and parse the line. Because a line can be any length don't use that version of get line.
std::string line;
while(std::getline(std::cin, line))
{
// Valid line has been read.
if (validDate(line))
{ return line;
}
std::cerr << "Invalid date please try again\n";
}
throw std::runtime_error("The user give up trying to enter a date correctly");Comments on C functions
C based functions for printing
printf() are dangerous, because they are not type safe. Prefer to use the C++ type safe streams.Comments on Data values
generator.setYear(1900 + (*(generator.getDate() + 4) * 10) + *(generator.getDate() + 5));What about people born after 31st Dec 1999?
Comments on Loop structures
while(i < 500){
// STUFF
i++;
}
// This kind of loop is better written as a for:
for(int loop=0; loop < 500; ++loop) {
// STUFF
}Also notice that I am declaring my loop variable as close to the point of usage as possible. Do not use the C style of putting all the variables at the top of the function. Put your variables where you can see there declaration and type easily.
Code Snippets
ID generator;
for(int i = 0; i < DATE_LENGTH; i++){
*(generator.getDate() + i) = int(dateString[i]-'0');
}
generator.setYear(1900 + (*(generator.getDate() + 4) * 10) + *(generator.getDate() + 5));
while(i < 500){
generator.individSiffer();
generator.generate();
i++;
}std::string date = getDate(); // Get a valid date or throw.
ID generator(date);
std::cout << generator;cin.getline(dateString, BUFFER);std::string line;
while(std::getline(std::cin, line))
{
// Valid line has been read.
if (validDate(line))
{ return line;
}
std::cerr << "Invalid date please try again\n";
}
throw std::runtime_error("The user give up trying to enter a date correctly");generator.setYear(1900 + (*(generator.getDate() + 4) * 10) + *(generator.getDate() + 5));Context
StackExchange Code Review Q#55870, answer score: 5
Revisions (0)
No revisions yet.