程序员边边角角,杂七杂八算法

身份证算法-生成合格的身份证号码

2018-11-15  本文已影响0人  pingerbufan

根据《中华人民共和国国家标准GB 11643-1999》中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。顺序码的奇数分给男性,偶数分给女性。校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

案例身份证号码:430923199509106866 
ps:此号码由算法算出,如有雷同纯属巧合

身份证号码的组成的结构:

841AE4D906940F38E8DA7F157DB640CF.jpg
1. 前1-6位数字表示:所在省(直辖市、自治区)、市、县的代码;
2. 第7—14位数字表示:出生年、月、日;
3. 第15、16位数字表示:所在地的派出所的代码;
4. 第17位数字表示性别:奇数表示男性,偶数表示女性;
5. 最后一位是校验码,校验你的身份证号码是否合格;

身份证号码是如何生成的?

两个必要因素:加权因子(wi) | 校验编码
wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 
校验编码:1 0 x 9 8 7 6 5 4 3 2
公式:S = 

通俗理解就是:身份证的第一位*加权因子的第一位 + 身份证的第二位*加权因子的第二位 
 ...  以此类推。

求出的和 % 11,得到一个校验位码 (假设是:5)

最后通过校验位码从校验编码中取出校验码(校验编码中的第5个数)

得到的数字与身份证最后一位匹配,如果相同,那就是合格的身份证号码
(第5位是8,那么身份证位数也必须是8)

用代码来生成合格身份证

 // 加权因子、固定的值
    NSArray *arr =@[@"7",@"9",@"10",@"5",@"8",@"4",@"2",@"1",@"6",@"3",@"7",@"9",@"10",@"5",@"8",@"4",@"2"];
    NSString *str = @"43092319950910"; // 身份证的省市县+出生年月
    NSString *JYM =@"10X98765432"; //校验码
    _array = [NSMutableArray array]; //保存产生的合格身份证的数组
    int sum = 0; //得到 省市县+出生年月 加权因子和
    for (int i = 0; i<str.length; i++) {
        id number = [str substringWithRange:NSMakeRange(i, 1)];
        sum += [number intValue] * [arr[i] intValue];
    }
    //通过加权因子计算,再衍算接下来的4位
    for (int i = 0; i<9999; i++) {
        int S = sum;
        int ge = i%10/1; //取各位 校验位
        int shi = i%100/10; //取十位
        int bai = i%1000/100; //取百位
        int qian = i %10000/1000; //取千位
        S += shi*[arr[16] intValue] + bai*[arr[15] intValue] + qian*[arr[14]intValue]; //加权求和
        int Y = S % 11; //身份证取模算法 y = mod(S, 11)
        //模数校验
        id M = [JYM substringWithRange:NSMakeRange(Y,1)];// 判断校验位
        BOOL b = ge == [M intValue]; // 判断身份证是否合格
        //合格的身份证添加到数组
        if(b){[_array addObject:[NSString stringWithFormat:@"%@%d%d%d%d",str,qian,bai,shi,ge]];}
    }

还有尾号是X的身份证

 for (int i = 0; i<999; i++) {
        int S = sum;
        NSString *ge = @"X"; //取各位 校验位
        int shi = i%10/1; //取i的各位
        int bai = i%100/10; //取i的十位
        int qian = i %1000/100; //取i的百位
        S += shi*[arr[16] intValue] + bai*[arr[15] intValue] + qian*[arr[14]intValue]; //加权求和
        int Y = S % 11; //身份证取模算法 y = mod(S, 11)
        //模数校验
        id M = [JYM substringWithRange:NSMakeRange(Y,1)];// 判断校验位
        BOOL b = [ge isEqualToString:M];
        if(b){[_array addObject:[NSString stringWithFormat:@"%@%d%d%d-%@",str,qian,bai,shi,ge]];}
    }

最终生成的号码就是当前这个县,当日所有的合格身份证号码。


C0A90AA44EA6A2BD37C86BE3BA5368A0.jpg

总结:

题外话:
🤪假设某个县当天出生的小孩超过1100个,会怎么样。
🤪谁能告诉我 公式那里怎么弄😝,图片?

上一篇下一篇

猜你喜欢

热点阅读