NATIONAL ID ANALYZER | PERSONAL PROJECTS | PROGRAMMING
Encoding National IDs: My First Programming Project, from Idea to Publishing on GitHub
How a project that was supposed to take 1 month took me over 4
Hello all! As of yesterday, I was able to finish my first ever software project: the CNP Toolkit.
The CNP, or Codul Numeric Personal, is essentially the Social Security Number for Romanians, except it is actually somewhat secure.
My project, written in pure JavaScript (yes, it very much was a pain), can both encode a series of information into a valid CNP, or extract that information from a provided CNP.
I am very excited to share this achievement, and also to look back at what took me so long.
My Inspiration
As someone with a wide range of interests and a possible undiagnosed ADHD, I’ve explored many random topics. I am very attracted towards the law and logic, and so, naturally, I gravitated towards the one thing that combines those two: a national ID number, using an algorithm prescribed into law (see the Further Reading section).
As a beginning developer, I also wanted to make something that could teach me programming at a simple level, and so I decided that this would be my first programming project.
I started in early August of 2024 on a vacation with my family so that I could forget about their existence for a while, and I figured that I would get it done by September when I had to start school.
Long story short, I blew that deadline and then got carried away with high school, and ended up essentially abandoning the project all the way until the beginning of this week, when I decided that I would finally get back to work, as winter break had started and I finally had some time.
By that point, I had not completed any part of the project: not the generator, not the analyzer, and not the associated UI.
To my surprise, I was able to finish the generator within two days, then also finish the analyzer in 3 days, as I mostly just had to repurpose some things.
And then yesterday, the 21st of December, I finished the UI, added some JSDocs for the main functions, and committed it to GitHub.
I definitely think that this rapid timeline was only possible because I learned more of the fundamentals in the last few months since I started writing here, than I knew back when I initially started.
What Were the Challenges?
I had a few problems with this project.
My first problem was that I not only started this to learn JavaScript and programming, but also to learn how to use Git. The very first days, I tried to add a .gitignore file just to see how it would work and, surprise surprise, it didn’t work.
I tried to get it to work for a few hours and then decided screw it, not doing this. That decision ultimately led to the project still not having a .gitignore file, although it probably wasn’t necessary here as I was committing everything anyway, but I would’ve still preferred to be able to learn how to do it.
Another issue I had is that ES6 modules mandate that you add the .js extension at the end of imports. Guess who often forgot to do that? Me!
I had quite a few hiccups with this particular problem, mainly because the browser console wasn’t telling me where the issue was happening inside the code, nor was it telling me this was even the issue. It would throw an error at load time that essentially said one of the modules was being treated as HTML or text and then leave me to figure out the rest.
These issues, although minor, were still annoying as I went along, but they taught me how to troubleshoot more effectively, and, more importantly, not to give up on troubleshooting, because things will get fixed eventually.
Now, What Features Does It Have?
As I glossed over at the start, the project has two main parts: a generator, and an analyzer.
For some reason, I also wasn’t really consistent with the terminology, so just know that the code uses generator and analyzer, but the UI says encoder and decoder respectively.
The Generator
The generator works by taking a few different arguments:
- sex — the person’s sex assigned at birth. String, either “Male” or “Female”
- yearOfBirth — Numeric string, between 1800–2099
- monthOfBirth — String, month spelled out in English (e.g. “January”, “February” et cetera)
- dayOfBirth — Numeric string, between 1–31
- countyName — String, the issuing county’s name, spelled out exactly as in the file ‘constants.js’
- isForeigner — Boolean, whether or not the person is a foreigner.
- sequenceDigits (optional) — Numeric string, between 001–999, if not provided one will be randomly generated.
After processing the information, the generator will return a 13-digit numeric string.
For example:
import { generateCNP } from "./cnpUtils.js";
const sex = "Female";
const year = "1989";
const month = "December";
const day = "21";
const county = "Tulcea";
const foreigner = false;
const sequence = "001";
const cnp = generateCNP(sex, year, month, day, county, foreigner, sequence);
console.log(cnp); // 2891221360016
The Analyzer
The analyzer takes 1 argument: the 13-digit numeric string representing a CNP.
After processing the information, it will return an object containing 8 separate pieces of information:
- sex — String, either “Male” or “Female”
- yearOfBirth, monthOfBirth, dayOfBirth — same format as for the generator
- countyName — the county where the CNP was issued
- sequence — simply returns digits 10 through 12 (inclusive) of the CNP
- checksumReturn — an object that contains a boolean (true if the provided CNP’s checksum was valid and false if it wasn’t) and a 1-digit numeric string containing the correct checksum (will return this whether or not the original checksum was valid)
For example:
import { analyzeCNP } from "./cnpUtils.js";
const cnp = "2891221360016";
const extractedInfo = analyzeCNP(cnp);
console.log(extractedInfo); // Will log:
/*
{
sex: "Female",
isForeigner: false,
yearOfBirth: "1989",
monthOfBirth: "December",
dayOfBirth: "21",
countyName: "Tulcea",
sequence: "001",
checksumReturn: {
isChecksumValid: true,
calculatedChecksum: "6"
}
}
*/
Lessons Learned? A few
Finally finishing this project has given me a lot of new and useful information.
Probably the most important is that I just uploaded and it was done, the first-time anxiety of posting an entire project on GitHub was gone.
I also learned how simple it truly is to use GitHub Pages for a project, basically 3 presses of a button and the UI was online.
The fact that I managed to complete everything that I had abandoned in less than a week after a 3 months long hiatus has given me a lot more confidence in my abilities.
After this project, JavaScript seems less intimidating, it is now simply another pain point, but no longer something I need to fear.
Sharing is Important
I decided to release this project on GitHub under the MIT license.
For those unfamiliar: The MIT license allows others to freely use, modify, and distribute the code while crediting the original author.
I did this because sharing is very important. The developer community has thrived because of but also required the cooperation of people in order for information to get across from person to person.
I wouldn’t have been able to make this project if I didn’t have access to tons of free resources and if I had to resort to long technical explanations of books from the last century, and I am not the only one.
While this project won’t provide much value to the average developer, I hope that at least someone as passionate about random stuff as me can learn from it.
I encourage you to check out the GitHub repository for the project and maybe leave a contribution, however small, or provide some feedback.
What’s Next for the Project?
While I currently do not have plans for the future, I do hope that I will get back to polishing the project further, mainly to fix bugs — I didn’t realize before publishing but the analyzeCNP function will still say a CNP is valid even if the day contained is 33, and that is definitely not the only problem.
Given that this project was more of a test run for me, I do mainly want to focus on future, potentially better, projects. Currently, I have in mind an idea for another project: an app for teachers, letting you input your students’ grades and giving you the class statistics like the average grade, highest and lowest 20% and so on, potentially using cookies to allow for storage of data across more than one session.
Whatever the case, the fundamentals I was able to learn as I built this project will surely come in handy in the future.
To wrap up, I want to remind all of you that you should start making projects of your own, on any kind of subject, because no one can make anything perfectly, but even if you could, you would only ever feel proud of those things you did with passion.
Feel free to check out the repository or check out the web UI, but be warned that it is very, very ugly!
As for me, I might just have enough time on my hands this winter break to perhaps try and translate the Wikipedia page on CNPs from Romanian into English so that you all could understand the whole process, as I didn’t detail every little thing in the documentation.
If you have any questions or suggestions, write a comment, I would love to read them!
Further Reading
- The repository of the project
- The GitHub Pages website for the UI
- [RO] Wikipedia’s page on the CNP
- [RO] Decree nr. 59/2nd of March 1978, the law that codified how CNPs shall be used and given out, on the website of the Ministry of Justice
Acknowledgements
The author used some AI tools in order to create this article.
AI tools used:
- ChatGPT: Outlining and refining sentences for readability.