7-51 实验9_2_身份证号码最后一位 (100 分)

身份证编码规则如下:根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。

顺序码(身份证第十五位到十七位)是县级公安机关所辖派出所的分配码,每个派出所分配码为10个连续号码,例如“000-009”或“060-069”,其中单数为男性分配码,双数为女性分配码,如遇同年同月同日有两人以上时顺延第二、第三、第四、第五个分配码。如:005的就是个男性,而且和他同年月日生的男性至少有两个,他们的后四位是001*和003*。分配顺序码中“999、998、997、996”四个顺序号分别为男女性百岁以上老人专用的特定编号。 校验码(身份证最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码。

从1999年10月1日起,全国实行公民身份证号码制度,居民身份证编号由原15位升至18位。前6位为地址码;第七位至14位为出生日期码,此码由6位数改为8位数,其中年份用4位数表示;第15位至17位为顺序码,取消了顺序码中对百岁老人使用的特定编号;第十八位为校验码,主要是为了校验计算机输入公民身份证号码的前17位数字是否正确,其取值范围是0至10,当值等于10时,用罗马数字符X表示。

计算方法

1、将前面的身份证号码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,余数1对应0,余数2对应X...)

5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。

例如:某男性的身份证号码为【53010219200508011X】, 我们看看这个身份证是不是符合计算规则的身份证。

首先我们得出前17位的乘积和【(5*7)+(3*9)+(0*10)+(1*5)+(0*8)+(2*4)+(1*2)+(9*1)+(2*6)+(0*3)+(0*7)+(5*9)+(0*10)+(8*5)+(0*8)+(1*4)+(1*2)】是189,然后用189除以11得出的结果是189÷11=17余下2,187÷11=17,还剩下2不能被除尽,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

现在请你写一段程序来判断一个身份证号码的最后一位是否与上述规则相符。

输入格式:

第一行一个整数T(0<T<100),表示有T行测试数据。后边是T行每行是一个18位的身份证号码(测试数据前17位保证符合身份证号码的要求,罗马数字X就是大写的英文字母X)。

输出格式:

T行,与输入的T行测试数据相对应,如果该行测试数据最后一位符合所述算法则输出right,否则输出wrong。

输入样例:

2
34052419800101001X
310105199412049278

输出样例:

right
wrong

这个题我实在不想写第二遍,大家康康我以前写的代码吧

#include<stdio.h>
int main()
{
    int n = 0;
    scanf("%d", &n);
    char ar[100][18] = { 0 };
    int i = 0, j = 0, k = 0;
    for (i = 0; i < n; i++)
        scanf("%s", &ar[i]);
    char pand[11] = { 1,0,'X',9,8,7,6,5,4,3,2 };
    for (i = 0; i < n; i++)
    {
        k = pack(ar, i);
        if (ar[i][17] == 'X')
        {
            if (pand[k] == ar[i][17])
                printf("right\n");
            else
                printf("wrong\n");
        }
        else {
            if (pand[k] == (ar[i][17] - 48))
                printf("right\n");
            else
                printf("wrong\n");
        }
    }
    return 0;
}
int pack(char ar[100][18], int i)
{
    int p[17] = { 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
    int k = 0, zhi = 0;
    for (k = 0; k < 17; k++)
        zhi += p[k] * (ar[i][k] - 48);
    return zhi % 11;
}

就离谱 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值