公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码,最后一位是数字校验码。
身份证最后一位是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
具体计算过程如下:
1、将前面的身份证号码17位数分别乘以不同的系数。第i位对应的数为[2^(18-i)]mod11。
从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
2、将这17位数字和系数相乘的结果相加;
3、用加出来和除以11,看余数是多少;
4、余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。
其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2;
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
C++代码实现如下:
思路:
1.先将身份证前17位用字符型数组进行存储即char a[17];
2.将上述1-17位每一位的权重储存在整型数组b[17]中;
3.将char a[17]这些字符型数据转化成整型数据方便进行后续运算。
值得注意的是,如果直接将字符型数据进行运算的话,使用的是其ASCLL码,由于0的ASCLL码为48,只需要将每个字符型数据减去‘0’即可将其转化成整型数据;
4.将身份证每位数与其对应的权重相乘并相加,得到sum。将sum除以11得到其余数mod;
5.由余数对应的校验码,可以得知身份证的第18位。
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
具体代码如下:
总结:
本代码主要运用了循环结构、选择结构。遇到的困难主要有字符型数据转整型数据。由于是数据结构与算法课,本程序还能用更加高效的代码来实现,后续还需要加以学习。
文章评论