用户并且验证方法(包括大陆,台湾,香港)

大陆的(有15位的也有18位的):

1、号码的结构
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3、出生日期码
表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4、顺序码
表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5、校验码
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
Ai:表示第i位置上的身份证号码数字值
Wi:表示第i位置上的加权因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)计算模
Y = mod(S, 11)
(3)通过模得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2

代码:

public static String conver15CardTo18(String idCard) { String idCard18 = ""; if(idCard.length() != 15) return null; if(isNum(idCard)) { String birthday = idCard.substring(6, 12); Date birthDate = null; try { birthDate = (new SimpleDateFormat("yyMMdd")).parse(birthday); } catch(ParseException e) { e.printStackTrace(); } Calendar cal = Calendar.getInstance(); if(birthDate != null) cal.setTime(birthDate); String sYear = String.valueOf(cal.get(1)); idCard18 = (new StringBuilder(String.valueOf(idCard.substring(0, 6)))).append(sYear).append(idCard.substring(8)).toString(); char cArr[] = idCard18.toCharArray(); if(cArr != null) { int iCard[] = converCharToInt(cArr); int iSum17 = getPowerSum(iCard); String sVal = getCheckCode18(iSum17); if(sVal.length() > 0) idCard18 = (new StringBuilder(String.valueOf(idCard18))).append(sVal).toString(); else return null; } } else { return null; } return idCard18; }converCharToint方法:

public static int[] converCharToInt(char ca[]) { int len = ca.length; int iArr[] = new int[len]; try { for(int i = 0; i < len; i++) iArr[i] = Integer.parseInt(String.valueOf(ca[i])); } catch(NumberFormatException e) { e.printStackTrace(); } return iArr; }getPowerSum方法:

public static int getPowerSum(int iArr[]) { int iSum = 0; if(power.length == iArr.length) { for(int i = 0; i < iArr.length; i++) { for(int j = 0; j < power.length; j++) if(i == j) iSum += iArr[i] * power[j]; } } return iSum; }getCheckCode18方法:

public static String getCheckCode18(int iSum) { String sCode = ""; switch(iSum % 11) { case 10: // '\n' sCode = "2"; break; case 9: // '\t' sCode = "3"; break; case 8: // '\b' sCode = "4"; break; case 7: // '\007' sCode = "5"; break; case 6: // '\006' sCode = "6"; break; case 5: // '\005' sCode = "7"; break; case 4: // '\004' sCode = "8"; break; case 3: // '\003' sCode = "9"; break; case 2: // '\002' sCode = "x"; break; case 1: // '\001' sCode = "0"; break; case 0: // '\0' sCode = "1"; break; } return sCode; }isNum方法:

public static boolean isNum(String val) { return val != null && !"".equals(val) ? val.matches("^[0-9]*{1}quot;) : false; }验证18位身份证号码的有效性:

public static boolean validateIdCard18(String idCard) { boolean bTrue = false; if(idCard.length() == 18) { String code17 = idCard.substring(0, 17); String code18 = idCard.substring(17, 18); if(isNum(code17)) { char cArr[] = code17.toCharArray(); if(cArr != null) { int iCard[] = converCharToInt(cArr); int iSum17 = getPowerSum(iCard); String val = getCheckCode18(iSum17); if(val.length() > 0 && val.equalsIgnoreCase(code18)) bTrue = true; } } } return bTrue; }验证15位有效性:

public static boolean validateIdCard15(String idCard) { if(idCard.length() != 15) return false; if(isNum(idCard)) { String proCode = idCard.substring(0, 2); if(cityCodes.get(proCode) == null) return false; String birthCode = idCard.substring(6, 12); Date birthDate = null; try { birthDate = (new SimpleDateFormat("yy")).parse(birthCode.substring(0, 2)); } catch(ParseException e) { e.printStackTrace(); } Calendar cal = Calendar.getInstance(); if(birthDate != null) cal.setTime(birthDate); return valiDate(cal.get(1), Integer.valueOf(birthCode.substring(2, 4)).intValue(), Integer.valueOf(birthCode.substring(4, 6)).intValue()); } else { return false; } }cityCodes相关代码:

public static Map cityCodes; cityCodes = new HashMap(); static { cityCodes.put("11", "\u5317\u4EAC"); cityCodes.put("12", "\u5929\u6D25"); cityCodes.put("13", "\u6CB3\u5317"); cityCodes.put("14", "\u5C71\u897F"); cityCodes.put("15", "\u5185\u8499\u53E4"); cityCodes.put("21", "\u8FBD\u5B81"); cityCodes.put("22", "\u5409\u6797"); cityCodes.put("23", "\u9ED1\u9F99\u6C5F"); cityCodes.put("31", "\u4E0A\u6D77"); cityCodes.put("32", "\u6C5F\u82CF"); cityCodes.put("33", "\u6D59\u6C5F"); cityCodes.put("34", "\u5B89\u5FBD"); cityCodes.put("35", "\u798F\u5EFA"); cityCodes.put("36", "\u6C5F\u897F"); cityCodes.put("37", "\u5C71\u4E1C"); cityCodes.put("41", "\u6CB3\u5357"); cityCodes.put("42", "\u6E56\u5317"); cityCodes.put("43", "\u6E56\u5357"); cityCodes.put("44", "\u5E7F\u4E1C"); cityCodes.put("45", "\u5E7F\u897F"); cityCodes.put("46", "\u6D77\u5357"); cityCodes.put("50", "\u91CD\u5E86"); cityCodes.put("51", "\u56DB\u5DDD"); cityCodes.put("52", "\u8D35\u5DDE"); cityCodes.put("53", "\u4E91\u5357"); cityCodes.put("54", "\u897F\u85CF"); cityCodes.put("61", "\u9655\u897F"); cityCodes.put("62", "\u7518\u8083"); cityCodes.put("63", "\u9752\u6D77"); cityCodes.put("64", "\u5B81\u590F"); cityCodes.put("65", "\u65B0\u7586"); cityCodes.put("71", "\u53F0\u6E7E"); cityCodes.put("81", "\u9999\u6E2F"); cityCodes.put("82", "\u6FB3\u95E8"); cityCodes.put("91", "\u56FD\u5916"); }大陆的验证方式基本上可以满足需求了。

台湾:

台湾身份证总共有10位数字。第一位是字母。后面九位是数字。 
台湾省份证的第一位的字母代表地区分别以A——Z表示 
规则如下: 
地区后面的数字为该字母转换的数字码。 
A 台北市10 
B 台中市11 
C 基隆市12 
D 台南市13 
E 高雄市14 
F 台北县15 
G 宜兰县16 
H 桃园县17 
I 嘉义市34 
J 新竹县18 
K 苗栗县19 
L 台中县20 
M 南投县21 
N 彰化县22 
O 新竹市35 
P 云林县23 
Q 嘉义县24 
R 台南县25 
S 高雄县26 
T 屏东县27 
U 花莲县28 
V 台东县29 
W 金门县30 
X 澎湖县31 
Y 阳明山32 
Z 连江县33 
第二位数字代表性别 男性是1,女性是2 
例如台北市的男性身份证号码就应该是A1开头 
第三位到第九位为任意的一串数字 
第十位为验证码。 

第十位数字——验证码的计算规则为: 

字母(ABCDEFGHJKLMNPQRSTUVXYWZIO)对应一组数(10——35)。 
令其十位数为X1,个位数为X2; 
D2到D9分别代表身份证号码的第二至第九位数。 
Y=X1+9×X2+8×D2+7×D3+6×D4+5×D5+4×D6+3×D7+2×D8+1×D9 

将Y的值除以10。得出的余数结果。 
再用10来减去这个余数结果。就得出身份证上的最后一位数字。 

例如R123456783,R=25, 

检查公式是:2+5*9+1*8+2*7+3*6+4*5+5*4+6*3+7*2+8*1=167, 

其167再除以10求余数结果。 

其余数结果的个位数为7以10减去得3(检查码)。 

这里有一个台湾花莲县男性的身份证号码U154482387 
用我上面给出的公式去验证一下,看最后一位的身份证号码是不是7。 

———————————————————————— 
综上所述: 
在台湾网站上填写身份证,对方能知道正确与否是从你注册信息中通过了上述三个途径知道是不是正确的身份号码。 
1.地区(第一位的26字母代表了台湾不同的市县) 
2.性别(第二位,男性就是1;女性就是2) 
3.最后一位的验证码(是不是满足上面的验证规则) 
代码:

public static boolean validateTWCard(String idCard) { String start = idCard.substring(0, 1); String mid = idCard.substring(1, 9); String end = idCard.substring(9, 10); Integer iStart = (Integer)twFirstCode.get(start); Integer sum = Integer.valueOf(iStart.intValue() / 10 + (iStart.intValue() % 10) * 9); char chars[] = mid.toCharArray(); Integer iflag = Integer.valueOf(8); char ac[]; int j = (ac = chars).length; for(int i = 0; i < j; i++) { char c = ac[i]; sum = Integer.valueOf(sum.intValue() + Integer.valueOf((new StringBuilder(String.valueOf(c))).toString()).intValue() * iflag.intValue()); iflag = Integer.valueOf(iflag.intValue() - 1); } return (sum.intValue() % 10 != 0 ? 10 - sum.intValue() % 10 : 0) == Integer.valueOf(end).intValue(); }twFirstCode相关代码:

public static Map twFirstCode; twFirstCode = new HashMap(); static{ twFirstCode.put("A", Integer.valueOf(10)); twFirstCode.put("B", Integer.valueOf(11)); twFirstCode.put("C", Integer.valueOf(12)); twFirstCode.put("D", Integer.valueOf(13)); twFirstCode.put("E", Integer.valueOf(14)); twFirstCode.put("F", Integer.valueOf(15)); twFirstCode.put("G", Integer.valueOf(16)); twFirstCode.put("H", Integer.valueOf(17)); twFirstCode.put("J", Integer.valueOf(18)); twFirstCode.put("K", Integer.valueOf(19)); twFirstCode.put("L", Integer.valueOf(20)); twFirstCode.put("M", Integer.valueOf(21)); twFirstCode.put("N", Integer.valueOf(22)); twFirstCode.put("P", Integer.valueOf(23)); twFirstCode.put("Q", Integer.valueOf(24)); twFirstCode.put("R", Integer.valueOf(25)); twFirstCode.put("S", Integer.valueOf(26)); twFirstCode.put("T", Integer.valueOf(27)); twFirstCode.put("U", Integer.valueOf(28)); twFirstCode.put("V", Integer.valueOf(29)); twFirstCode.put("X", Integer.valueOf(30)); twFirstCode.put("Y", Integer.valueOf(31)); twFirstCode.put("W", Integer.valueOf(32)); twFirstCode.put("Z", Integer.valueOf(33)); twFirstCode.put("I", Integer.valueOf(34)); twFirstCode.put("O", Integer.valueOf(35)); }香港:

由前7位确定,首位字母改为数字代表,即A以1代表,B以2代表...Z以26代表,可以得到8个数字,之后第一个数字乘以8,第二个数字乘以7,依此类推,第七个数字乘以2

再将以上所有乘积相加,得到一个数,再将这个数除以11,得到余数。如果整除,校验码为0,如果余数为1,则校验码为A,如果余数为2~10,则用11减去这个余数,则为校验码。

例子:计算P103265的校验码(该号码纯属虚构,如与您的身份证号相同,实属巧合)

P,在字母表中排行16,则以16代表

计算:16×8+1×7+0×6+3×5+2×4+6×3+5×2=186

186÷11=16......10

11-10=1

所以算出来的身份证号码是P103265(1)

掌握了这个方法之后可以随意去验证一个香港身份证号码了,按照这个规律,括弧内验证码为A的,比例只有11分之1,所以平时见得少也很正常的

另外:内地的二代身份证号码(18位)的最后一位也是属于验证码,其编码规则与香港的相仿,也是由前面的17位通过公式计算出来的,不过计算更加复杂,到最后也是通过除以11的余数确定的,所以会出现一些身份证号码最后一位为字母X,原因也是一样的

代码:

public static boolean validateHKCard(String idCard) { String card = idCard.replaceAll("[\\(|\\)]", ""); Integer sum = Integer.valueOf(0); if(card.length() == 9) { sum = Integer.valueOf((Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]).intValue() - 55) * 9 + (Integer.valueOf(card.substring(1, 2).toUpperCase().toCharArray()[0]).intValue() - 55) * 8); card = card.substring(1, 9); } else { sum = Integer.valueOf(522 + (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]).intValue() - 55) * 8); } String mid = card.substring(1, 7); String end = card.substring(7, 8); char chars[] = mid.toCharArray(); Integer iflag = Integer.valueOf(7); char ac[]; int j = (ac = chars).length; for(int i = 0; i < j; i++) { char c = ac[i]; sum = Integer.valueOf(sum.intValue() + Integer.valueOf((new StringBuilder(String.valueOf(c))).toString()).intValue() * iflag.intValue()); iflag = Integer.valueOf(iflag.intValue() - 1); } if(end.toUpperCase().equals("A")) sum = Integer.valueOf(sum.intValue() + 10); else sum = Integer.valueOf(sum.intValue() + Integer.valueOf(end).intValue()); return sum.intValue() % 11 == 0; }澳门的算法和香港是一样的,只是各个位数形式不一样,1字开首的身份证号码代表是因龙的行动或1992年后领取身份证之人士,现在新发出的身份证亦以1字开首;5字开首的身份证号码代表持有或曾经持有葡萄牙国民身份证或葡萄牙给外国人身份证之人士;7字开首代表曾经取得蓝卡之人士,大多都是在1970年代至1980年代期间从中国大陆持合法证件到澳门的人士。具体见下面的validateCard10方法。

这样我们可以写一个方法来验证这几种身份证号码形式的有效性:

public static boolean validateCard(String idCard) { String card = idCard.trim(); if(validateIdCard18(card)) return true; if(validateIdCard15(card)) return true; String cardval[] = validateIdCard10(card); return cardval != null && cardval[2].equals("true"); }在这一个方法里validateIdCard10这个方法是验证除大陆外的身份证信息的,代码如下:

public static String[] validateIdCard10(String idCard) { String info[] = new String[3]; String card = idCard.replaceAll("[\\(|\\)]", ""); if(card.length() != 8 && card.length() != 9 && idCard.length() != 10) return null; if(idCard.matches("^[a-zA-Z][0-9]{9}{1}quot;)) { info[0] = "\u53F0\u6E7E";//\u53F0\u6E7E=台湾 System.out.println("11111"); String char2 = idCard.substring(1, 2); if(char2.equals("1")) { info[1] = "M"; System.out.println("MMMMMMM"); } else if(char2.equals("2")) { info[1] = "F"; System.out.println("FFFFFFF"); } else { info[1] = "N"; info[2] = "false"; System.out.println("NNNN"); return info; } info[2] = validateTWCard(idCard) ? "true" : "false"; } else if(idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?{1}quot;)) { info[0] = "\u6FB3\u95E8";//\u6FB3\u95E8=澳门 info[1] = "N"; } else if(idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?{1}quot;)) { info[0] = "\u9999\u6E2F";//\u9999\u6E2F=香港 info[1] = "N"; info[2] = validateHKCard(idCard) ? "true" : "false"; } else { return null; } return info; }这个方法会复杂一点,熟悉了身份证的格式就会明白这个方法里的代码。主要的还是正则表达式的匹配写法。比如这里的^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$它的意思是以1或5或7开头然后后面接着6个数字接着后面就是(字母或数字)。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值