2010年1月6日 星期三

大陸公民身份號碼驗證規則

大陸的身份證為18位,舊的身份證是15位。
公民身份號碼是特徵組合碼,由十七位數字和一位數字檢核碼組成。

從左至右依次為:
   1.六位數字地址碼。
   2.八位數字出生日期碼。
   3.三位數字流水號。
   4.一位數字檢核碼。

地址碼:
   第01位到第06位表示編碼對象戶籍所在縣應該是指出生地的行政區代碼。
   這裡可以查到所有的行政區編碼中華人民共和國國家統計局

生日碼:
   第07位到第14位表示編碼對像出生的年、月、日,當然是用西元年四碼
範例:1978年02月01日就用19780201。

流水號:
   第15位到第17位為同一地址碼內,對同一天出生的人員編定的流水號。
   第17位奇數分給男性,偶數分給女性。跟台灣的身分證字號類似。
   對岸大陸目前的出生率有這麼低嗎??

校驗碼:
   第18位是根據前面十七位數字,計算出來的檢核碼。

   第18位數字的計算方法為:
      1.將前面的身份證號碼17位數分別乘上一組係數。
         係數:7910584216379105842
      2.將這17位數字和系數相乘的結果加總。
      3.將第二步驟的機總數字除以11取餘數。
      4.餘數級代表核驗碼的Index 核驗碼10,X,9,8,7,6,5,4,3,2

程式碼:


    public static boolean isPRCId(String cId) {
        boolean isPRCId = false;
        //改為大寫
        cId = cId.toUpperCase();
        //長度檢查
        if (cId.trim().length() != 18) {
            return false;
        }

        //數字檢查
        //前17碼必須為數字
        for (int i = 0; i < cId.length() - 1; i++) {
            char c = cId.charAt(i);
            if (c < '0' || c > '9') {
                return false;
            }
        }

        //生日碼檢核
        if (isACDay(cId.substring(6, 14)) == false) {
            return false;
        }

        //計算係數
        int[] key = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] sparate = cId.substring(0, 17).toCharArray();
        int[] value = new int[17];
        for (int i = 0; i < 17; i++) {
            value[i] = Integer.parseInt(String.valueOf(sparate[i]));
        }

        int nValue = 0;
        for (int i = 0; i < 17; i++) {
            nValue = nValue + (key[i] * value[i]);
        }

        int cIdLastValueIndex = 0;
        cIdLastValueIndex = nValue % 11;
        String[] cIdLastValue = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

        if (cId.substring(17).equals(cIdLastValue[cIdLastValueIndex])) {
            isPRCId = true;
        } else {
            isPRCId = false;
        }
        return isPRCId;
    }

1 則留言:

Unknown 提到...

希望你能在係數之間加個空格