PHP獲取IMEI號最後一位校驗碼

baiping_hb發表於2019-02-16

移動裝置國際識別碼(IMEI:International Mobile Equipment Identification Number)是區別移動裝置的標誌,具有唯一性,貼在手機背面的標誌上,並且儲存在移動裝置中,可用於監控被竊或無效的移動裝置,它也是該手機在廠家的”檔案”和”身份證號”.IMEI碼由GSM(全球行動通訊協會)統一分配,授權BABT(英國通訊認證管理委員會)審受.其總長為15位,每位數字僅使用0~9的數字

IMEI由15位數字組成,其組成為:

1、前6位數(TAC,Type ApprovalCode)是”型號核准號碼”,一般代表機型.
2、接著的2位數(FAC,Final Assembly Code)是”最後裝配號”,一般代表產地.
3、之後的6位數(SNR)是”串號”,一般代表生產順序號.
4、最後1位數(SP)通常是”0″,為檢驗碼,備用.

IMEI校驗碼演算法:

(1).將偶數位數字分別乘以2,分別計算個位數和十位數之和
(2).將奇數位數字相加,再加上上一步算得的值
(3).如果得出的數個位是0則校驗位為0,否則為10減去個位數

如:35 89 01 80 69 72 41 偶數位乘以2得到52=10 92=18 12=02 02=00 92=18 22=04 1*2=02,計算奇數位數字之和和偶數位個位十位之和,得到 3+(1+0)+8+(1+8)+0+(0+2)+8+(0+0)+6+(1+8)+7+(0+4)+4+(0+2)=63 => 校驗位 10-3 = 7

程式碼如下:

/**
     * 格式化imei
     * 因為IMEI格式不統一,長度有14位和16位的,所以,為了統一,將14位和16位的MEID,統一設定為15位的 設定格式:
     * 如果IMEI長度為14位,那麼直接得到第15位,如果MEID長度為16位,那麼直接在根據前14位得到第15位
     * 如果IMEI長度為其他長度,那麼直接返回原值
     * (1).將偶數位數字分別乘以2,分別計算個位數和十位數之和
     * (2).將奇數位數字相加,再加上上一步算得的值
     * (3).如果得出的數個位是0則校驗位為0,否則為10減去個位數
     * 如:35 89 01 80 69 72 41 偶數位乘以2得到5*2=10 9*2=18 1*2=02 0*2=00 9*2=18 2*2=04 1*2=02,
     * 計算奇數位數字之和和偶數位個位十位之和,得到 3+(1+0)+8+(1+8)+0+(0+2)+8+(0+0)+6+(1+8)+7+(0+4)+4+(0+2)=63 =>
     * 校驗位 10-3 = 7
     * @param imei $
     * @author Baip 125618036@qq.com
     */
    public function formatImei( $imei ){
        if ( empty( $imei ) ){
            return false;
        }
        $imeiStrlen = strlen($imei);
        if ( $imeiStrlen != 14 && $imeiStrlen != 16 ){
            return $imei;
        }
        $imeiRes = ``;
        if ( $imeiStrlen == 14 ){
            $imeiRes = $imei . $this->getImei15($imei);
        }
        if ($imeiStrlen == 16) {
            $imeiRes =  $imei . $this->getImei15(substr($imei, 0,14));
        }

        return $imeiRes;
    }

    /**
     * 根據imei前14位,得到第15位的校驗位
     * IMEI校驗碼演算法:
     * (1).將偶數位數字分別乘以2,分別計算個位數和十位數之和
     * (2).將奇數位數字相加,再加上上一步算得的值
     * (3).如果得出的數個位是0則校驗位為0,否則為10減去個位數
     * 如:35 89 01 80 69 72 41 偶數位乘以2得到5*2=10 9*2=18 1*2=02 0*2=00 9*2=18 2*2=04 1*2=02,計算奇數位數字之和和偶數位個位十位之和,
     * 得到 3+(1+0)+8+(1+8)+0+(0+2)+8+(0+0)+6+(1+8)+7+(0+4)+4+(0+2)=63
     * 校驗位 10-3 = 7
     * @param $imei
     * @author Baip 125618036@qq.com
     */
    private function getImei15($imei){
        if ( strlen( $imei ) == 14 ){
            $imeiArr = str_split($imei);
            $imeiNewArr = [];
            foreach ($imeiArr as  $key => $value){
                $imeiNewArr[$key+1] = $value;
            }
            $sum1 = 0;
            $sum2 = 0;
            if ( is_array($imeiNewArr) && count($imeiNewArr) == 14 ){
                for ($i=1; $i<= count($imeiNewArr); $i++ ){
                    //如果為偶數
                    if ( $i % 2 == 0 ){
                        $temp = intval( ($imeiNewArr[$i] - 0) * 2 );
                        if ($temp < 10){
                            $sum2 = $sum2 + $temp;
                        }else{
                            //目的:大於10的值12,最後要用個位+十位 (1+2) 轉化為:sum + 1 + 12-10
                            $sum2 = $sum2 + 1 + $temp -10 ;
                        }
                    }else{
                        $sum1  = $sum1 + $imeiNewArr[$i] - `0`;
                    }
                }
                $total = $sum1 + $sum2;
                if ( $total % 10 == 0 ){
                    return 0;
                }else{
                    return intval(10 - $total % 10);
                }
            }else{
                return ``;
            }
        }
    }

相關文章