xylz,imxylz

          關注后端架構、中間件、分布式和并發編程

             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            111 隨筆 :: 10 文章 :: 2680 評論 :: 0 Trackbacks
          本著開發的原則,既然用到了別人家的東西,所以決定公開出來,也算是給別人一個參考。
          源碼如下:
          import java.util.Calendar;
          import java.util.HashMap;
          import java.util.Map;

          /**
           * 身份證校驗工具(支持15位或者18位身份證)<br/>
           * 身份證號碼結構:
           * <ol>
           * <li>17位數字和1位校驗碼:6位地址碼數字,8位生日數字,3位出生時間順序碼,1位校驗碼。</li>
           * <li>地址碼(前6位):表示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼,按GB/T2260的規定執行。</li>
           * <li>出生日期碼(第七位至十四位):表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。</li>
           * <li>順序碼(第十五位至十七位) :表示在同一地址碼所標識的區域范圍內,對同年、同月、同日出生的人編定的順序號,
           * 順序碼的奇數分配給男性,偶數分配給女性。</li>
           * <li>校驗碼(第十八位數):<br/>
           * <ul>
           * <li>十七位數字本體碼加權求和公式 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;</li>
           * <li>計算模 Y = mod(S, 11)</li>
           * <li>通過模得到對應的校驗碼 Y: 0 1 2 3 4 5 6 7 8 9 10 校驗碼: 1 0 X 9 8 7 6 5 4 3 2</li>
           * </ul>
           * </li>
           * </ol>
           * 
           * 
          @author xylz
           * 
          @since 2011-1-4
           * 
          @see {@link http://www.aygfsteel.com/zeroline/archive/2011/01/03/342227.html}
           
          */
          public class IdcardUtil {
              
          final static Map<Integer, String> zoneNum = new HashMap<Integer, String>();
              
          static {
                  zoneNum.put(
          11"北京");
                  zoneNum.put(
          12"天津");
                  zoneNum.put(
          13"河北");
                  zoneNum.put(
          14"山西");
                  zoneNum.put(
          15"內蒙古");
                  zoneNum.put(
          21"遼寧");
                  zoneNum.put(
          22"吉林");
                  zoneNum.put(
          23"黑龍江");
                  zoneNum.put(
          31"上海");
                  zoneNum.put(
          32"江蘇");
                  zoneNum.put(
          33"浙江");
                  zoneNum.put(
          34"安徽");
                  zoneNum.put(
          35"福建");
                  zoneNum.put(
          36"江西");
                  zoneNum.put(
          37"山東");
                  zoneNum.put(
          41"河南");
                  zoneNum.put(
          42"湖北");
                  zoneNum.put(
          43"湖南");
                  zoneNum.put(
          44"廣東");
                  zoneNum.put(
          45"廣西");
                  zoneNum.put(
          46"海南");
                  zoneNum.put(
          50"重慶");
                  zoneNum.put(
          51"四川");
                  zoneNum.put(
          52"貴州");
                  zoneNum.put(
          53"云南");
                  zoneNum.put(
          54"西藏");
                  zoneNum.put(
          61"陜西");
                  zoneNum.put(
          62"甘肅");
                  zoneNum.put(
          63"青海");
                  zoneNum.put(
          64"寧夏");
                  zoneNum.put(
          65"新疆");
                  zoneNum.put(
          71"臺灣");
                  zoneNum.put(
          81"香港");
                  zoneNum.put(
          82"澳門");
                  zoneNum.put(
          91"國外");
              }

              
          final static int[] PARITYBIT = { '1''0''X''9''8''7''6''5''4''3''2' };
              
          final static int[] POWER_LIST = { 791058421637910,
                      
          5842 };

              
          /**
               * 身份證號是否基本有效
               * 
               * 
          @param s
               *            號碼內容
               * 
          @return 是否有效,null和""都是false
               
          */
              
          public static boolean isIdcard(String s) {
                  
          if (s == null || (s.length() != 15 && s.length() != 18))
                      
          return false;
                  
          final char[] cs = s.toUpperCase().toCharArray();
                  
          // (1)校驗位數
                  int power = 0;
                  
          for (int i = 0; i < cs.length; i++) {// 循環比正則表達式更快
                      if (i == cs.length - 1 && cs[i] == 'X')
                          
          break;// 最后一位可以是X或者x
                      if (cs[i] < '0' || cs[i] > '9')
                          
          return false;
                      
          if (i < cs.length - 1)
                          power 
          += (cs[i] - '0'* POWER_LIST[i];
                  }
                  
          // (2)校驗區位碼
                  if (!zoneNum.containsKey(Integer.valueOf(s.substring(02)))) {
                      
          return false;
                  }
                  
          // (3)校驗年份
                  String year = s.length() == 15 ? "19" + s.substring(68) : s
                          .substring(
          610);
                  
          final int iyear = Integer.parseInt(year);
                  
          if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR)) {
                      
          return false;// 1900年的PASS,超過今年的PASS
                  }
                  
          // (4)校驗月份
                  String month = s.length() == 15 ? s.substring(810) : s.substring(10,
                          
          12);
                  
          final int imonth = Integer.parseInt(month);
                  
          if (imonth < 1 || imonth > 12)
                      
          return false;
                  
          // (5)校驗天數
                  String day = s.length() == 15 ? s.substring(1012) : s.substring(12,
                          
          14);
                  
          final int iday = Integer.parseInt(day);
                  
          if (iday < 1 || iday > 31)
                      
          return false;
                  
          // (6)校驗一個合法的年月日
                  if (!validate(iyear, imonth, iday))
                      
          return false;
                  
          // (7)校驗“校驗碼”
                  if (s.length() == 15)
                      
          return true;
                  
          return cs[cs.length - 1== PARITYBIT[power % 11];
              }

              
          static boolean validate(int year, int month, int day) {
                  
          //比如考慮閏月,大小月等
                  return true;
              }

              
          public static void main(String[] args) {
                  
          for(int i=0;i<10;i++) {
                      
          final String s = "42230219880101100"+i;
                      System.out.println(s
          +" --> "+isIdcard(s));
                  }
              }
          }

          這里需要說明的是,validate校驗年月日是否有效的方法沒有做,先不打算做了。它是校驗是否是一個合法的年月日組合,比如閏年、大小月天數等。有興趣的同學可以研究下吧。
          參考文地址:http://www.aygfsteel.com/zeroline/archive/2011/01/03/342227.html


          ©2009-2014 IMXYLZ |求賢若渴
          posted on 2011-01-05 10:00 imxylz 閱讀(4614) 評論(1)  編輯  收藏 所屬分類: J2EE

          評論

          # re: 一個身份證號碼的基礎驗證 2011-03-15 12:41 sun4love
          (s.length() != 15 && s.length() != 18)

          這個條件

          !(s.length() == 15 || s.length() == 18)  回復  更多評論
            


          ©2009-2014 IMXYLZ
          主站蜘蛛池模板: 方正县| 军事| 玉门市| 长沙县| 息烽县| 绍兴县| 民丰县| 泾源县| 如东县| 绵阳市| 彭山县| 瓮安县| 鹤庆县| 合作市| 荥经县| 会同县| 商城县| 汝阳县| 安阳市| 游戏| 凉山| 永善县| 浦城县| 福安市| 墨江| 桃源县| 余姚市| 凤山市| 通山县| 阜城县| 孟津县| 尉犁县| 满洲里市| 阳西县| 桐庐县| 武冈市| 汉阴县| 阜宁县| 莲花县| 安福县| 宁国市|