gwl3323405
用Java算法实现新18位身份河蟹证号的生成

新18位身份证号的结构是:六位数字地址码+八位数字出生日期码+三位数字顺序码+一位数字校验码

前17位都很好得到(前六位是地区行政编码,比如北京市是110000,其他请参考官方网站查询:www.stats.gov.cn/tjbz/index.htm 。八位出生日期要注意,比如你是1990年1月1日出生的,那么就是:19900101),关键也是此算法唯一的难点是最后一位校验码的计算。步骤如下:

1、将前17位数乘以不同的系数,系数对应表:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

2、将前17位数加上上面的每个数相乘的结果

3、将上面的结果对11取余(范围:0 1 2 3 4 5 6 7 8 9 10)

4、将上面的余数参照对应表:1 0 X 9 8 7 6 5 4 3 2

上面的算法是从网上摘抄下来的,也是传的比较广的一个,姑且我就以这个算法为蓝本用Java表示出来喽!

[mw_shl_code=java,true]private static int[] multiNum=new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

private static String[] resNum=new String[]{"1","0","X","9","8","7","6","5","4","3","2"};

/**

* 输入参数返回身份河蟹证号码的方法

* @param addrNo 地区行政编码(6位)

* @param birthDate //出生日期(8位)

* @param orderCode 顺序码(3位数,男奇女偶)

* @return 身份河蟹证号码

*/

public static String getIDnumber(String addrNo,String birthDate,String orderCode){

String orderNumber="";//存放顺序码

String num17=addrNo+birthDate+orderCode;//拼接出前17个数字

char[] num17Ch=num17.toCharArray();//将前17字符串转成字符数组

int num17Tmp=0;//存放第二步的结果

for(int i=0;i<multiNum.length;i++){//将第一步和第二部合并

int num17ChTmp=Integer.parseInt(num17Ch+"");

num17Tmp+=(num17ChTmp+num17ChTmp*multiNum);

}

int oddNumber=num17Tmp%11;//第三步(对11取余)

for(int i=0;i<resNum.length;i++){//第四步(余数对象获得对应顺序码)

if(oddNumber==i){

orderNumber=resNum[i-1];//根据原算法不需要-1,但亲测多一位无奈此处减去1

}

}

return num17+orderNumber;//返回前17位字符串+顺序码

}[/mw_shl_code]

调用这个静态方法,传入三个字符串即可得到一个18位身份河蟹证号了。

以上的算法亲测貌似有一点的偏差,不过确实能生成一个有效的18位身份河蟹证号,对付网络注册还是绰绰有余啦!不信大家自己拿回去试试喽!

ossilta
算法本身有错误
展开Biu

算法本身有错误, 所以才会有偏差.

计算最后一位校验码时, 前两个步骤有明显错误, 引用原文:

1、将前17位数乘以不同的系数,系数对应表:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

2、将前17位数加上上面的每个数相乘的结果

代码中的实现 :

[mw_shl_code=java,true]num17Tmp += (num17ChTmp + num17ChTmp * multiNum);[/mw_shl_code]

看了这行代码之后发现其实可以让 "num17ChTmp" 所乘的系数 +1 来进行化简, 弄成这样:

[mw_shl_code=java,true]num17Tmp += num17ChTmp * (multiNum + 1);[/mw_shl_code]

于是乎貌似反映出了一个问题.. 前两个步骤合并成了一个步骤:

1、将前17位数乘以不同的系数,系数对应表:8 10 0 6 9 5 3 2 7 4 8 10 0 6 9 5 3

...

似乎有什么不对QAQ..

推度娘, 发现其实原步骤1的系数就是正确的, 而第二个步骤是多余的..

那么如何去修改代码相信大家都知道了, 不多说.

所以接下来..

就要看一下楼主的代码第24行..

[mw_shl_code=java,true]orderNumber = resNum[i-1]; //根据原算法不需要-1,但亲测多一位无奈此处减去1[/mw_shl_code]

为什么会亲测出一个 "-1" 的结果..

从乘以系数求和的地方开始

先假设按照正确的系数求和并除以11的余数为n, 由于求和之前每一项所乘的系数多了 "1", 所以我们实际得到的余数为 (2*n)%11

所以得到如下结果:

正确算法获得的余数: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

我们实际获得的余数: 0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9

由此推断楼主在测试时使用了特殊数据使得实际得到的余数为 2, 所以才 "无奈 -1"

而后的备注又注明 "24行可以不用-1"

推断是楼主在测试时发现直接 -1 会 get 一个 ArrayIndexOutOfBoundsException..

[查看全文]
dmayq
先收藏了
展开Biu

先收藏了,慢慢研究一下!!

[查看全文]
moxiagy
都是学爪哇的啊
展开Biu

@1# 都是学爪哇的啊

[查看全文]
dlsdyc
其实原来我也不懂的说
展开Biu

额,好吧,其实原来我也不懂的说

[查看全文]
Sam_TvT
学习到了
展开Biu

#17!学习到了

[查看全文]
呆死机亲卫兵
谢谢分享啊
展开Biu

谢谢分享啊

[查看全文]
warrant
原来身份河蟹证号是这样的
展开Biu

好吧 原来身份河蟹证号是这样的

[查看全文]
神木凛
写过一次
展开Biu

以前用C++写过一次 学习了 多谢

[查看全文]