Today, I wanted to mess around with generating Chinese IDs, you know, those 18-digit numbers that are unique to every citizen. I’ve seen some libraries out there, but I figured, why not try building something myself? It seemed like a fun little project.
So, I started by digging into the structure of these ID numbers. I mean I learned the breakdown rules of Chinese ID cards many years ago. Turns out, it’s not just random digits. There’s a system!

- The first six digits are the address code.
- The next eight are the date of birth (YYYYMMDD).
- Then, there are three digits that are basically a sequence number, with the last digit of these three denotes the gender– odd for males, even for females.
- And finally, there’s a single check digit at the end.
The check digit is where it gets a bit mathematical, that need some calculation. It’s calculated using a formula (ISO 7064:1983, MOD 11-2) that involves weighting each of the previous 17 digits and then doing some modulo operations. I won’t bore you with the details, it’s a bit complicated for me. I am not so good at Math.
My Implementation Steps
First, I whipped up a quick function to generate a random address code. I just grabbed a list of valid area codes online and randomly picked one. Not super accurate, I know, but good enough for my testing purposes.
Next, I made a function to generate a random birthdate. I set some reasonable bounds, like no one born before 1900 or after today. Seemed logical.
Then came the sequence number. I just randomly generated a number between 001 and 999. For the gender part, I randomly picked an odd or even number.
The hardest part was figuring out that check digit calculation. I read up on the formula, and after a couple of tries, I got it working. Basically, you multiply each digit by a weight, sum them up, take the modulo 11 of that, and then do some subtraction to get the final check digit. It’s kind of a pain, honestly. But I did it.
Finally, I put it all together! I had a function that could spit out a seemingly valid Chinese ID number. It’s not perfect, of course. The address codes aren’t guaranteed to be accurate, and I’m not checking for any edge cases or anything. But it works for a basic generator.
I played around with it for a bit, generating a bunch of IDs. It was satisfying to see those 18-digit numbers pop up, knowing I’d built the thing that made them. It felt pretty good, I’d have to say!
This was a neat little coding exercise. I learned more about Chinese ID numbers, practiced my coding skills, and ended up with a somewhat functional generator. Might not be useful for anything serious, but it was a good time!