1. 程式人生 > >IMEI/MEID校驗位計算

IMEI/MEID校驗位計算

IMEI是國際移動通訊裝置識別號(International Mobile Equipment Identity)的縮寫,用於GSM系統。

由15位數字組成,前6位(TAC)是型號核准號碼,代表手機型別。接著2位(FAC)是最後裝配號,代表產地。後6位(SNR)是串號,代表生產順序號。最後1位(SP)是檢驗碼。


MEID是移動通訊裝置識別號(Mobile Equipment IDentifier)的縮寫,用於CDMA系統。

由15位16進位制數字組成(一般使用前14位),前8位是生產商編號,後6位是串號,最後1位是檢驗碼。

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

MEID校驗碼演算法:
(1).將偶數位數字分別乘以2,分別計算個位數和十位數之和,注意是16進位制數
(2).將奇數位數字相加,再加上上一步算得的值
(3).如果得出的數個位是0則校驗位為0,否則為10(這裡的10是16進位制)減去個位數
如:AF 01 23 45 0A BC DE 偶數位乘以2得到F*2=1E 1*2=02 3*2=06 5*2=0A A*2=14 C*2=18 E*2=1C,計算奇數位數字之和和偶數位個位十位之和,得到 A+(1+E)+0+2+2+6+4+A+0+(1+4)+B+(1+8)+D+(1+C)=64 => 校驗位 10-4 = C

/**
 * IMEI是國際移動通訊裝置識別號(International Mobile Equipment Identity)的縮寫,用於GSM系統。
 * 由15位數字組成,前6位(TAC)是型號核准號碼,代表手機型別。接著2位(FAC)是最後裝配號,代表產地。後6位(SNR)是串號,代表生產順序號。最後1位(SP)是檢驗碼。
 * MEID是移動通訊裝置識別號(Mobile Equipment IDentifier)的縮寫,用於CDMA系統。
 * 由15位16進位制數字組成,前8位是生產商編號,後6位是串號,最後1位是檢驗碼。
 * @author fengyifei11228
 * @since 2015-05-22
 */
public class DeviceUtil {
	/**
	 * 格式化MEID
	 * 因為MEID格式不統一,長度有14位和16位的,所以,為了統一,將14位和16位的MEID,統一設定為15位的 設定格式:
	 * 如果MEID長度為14位,那麼直接得到第15位,如果MEID長度為16位,那麼直接在根據後14位得到第15位
	 * 如果MEID長度為其他長度,那麼直接返回原值
	 * @param meid
	 * @return
	 */
	public static String formatMeid(String meid) {
		int dxml = meid.length();
		if (dxml != 14 && dxml != 16) {
			return meid;
		}
		String meidRes = "";
		if (dxml == 14) {
			meidRes =  meid + getmeid15(meid);
		}
		if (dxml == 16) {
			meidRes = meid.substring(2) + getmeid15(meid.substring(2));
		}
		return meidRes;
	}

	/**
	 * 格式化IMEI
	 * 因為IMEI格式不統一,長度有14位和16位的,所以,為了統一,將14位和16位的MEID,統一設定為15位的 設定格式:
	 * 如果IMEI長度為14位,那麼直接得到第15位,如果MEID長度為16位,那麼直接在根據前14位得到第15位
	 * 如果IMEI長度為其他長度,那麼直接返回原值
	 * @param imei
	 * @return
	 */
	public static String formatImei(String imei) {
		int dxml = imei.length();
		if (dxml != 14 && dxml != 16) {
			return imei;
		}
		String imeiRes = "";
		if (dxml == 14) {
			imeiRes =  imei + getimei15(imei);
		}
		if (dxml == 16) {
			imeiRes =  imei + getimei15(imei.substring(0,14));
		}
		return imeiRes;
	}
	/**
	 * 根據MEID的前14位,得到第15位的校驗位
	 * MEID校驗碼演算法:
	 * (1).將偶數位數字分別乘以2,分別計算個位數和十位數之和,注意是16進位制數
	 * (2).將奇數位數字相加,再加上上一步算得的值
	 * (3).如果得出的數個位是0則校驗位為0,否則為10(這裡的10是16進位制)減去個位數
	 * 如:AF 01 23 45 0A BC DE 偶數位乘以2得到F*2=1E 1*2=02 3*2=06 5*2=0A A*2=14 C*2=18 E*2=1C,
	 * 	計算奇數位數字之和和偶數位個位十位之和,得到 A+(1+E)+0+2+2+6+4+A+0+(1+4)+B+(1+8)+D+(1+C)=64 
	 *  校驗位 10-4 = C
	 * @param meid
	 * @return
	 */
	private static String getmeid15(String meid) {
		if (meid.length() == 14) {
			String myStr[] = { "a", "b", "c", "d", "e", "f" };
			int sum = 0;
			for (int i = 0; i < meid.length(); i++) {
				String param = meid.substring(i, i + 1);
				for (int j = 0; j < myStr.length; j++) {
					if (param.equalsIgnoreCase(myStr[j])) {
						param = "1" + String.valueOf(j);
					}
				}
				if (i % 2 == 0) {
					sum = sum + Integer.parseInt(param);
				} else {
					sum = sum + 2 * Integer.parseInt(param) % 16;
					sum = sum + 2 * Integer.parseInt(param) / 16;
				}
			}
			if (sum % 16 == 0) {
				return "0";
			} else {
				int result = 16 - sum % 16;
				if (result > 9) {
					result += 65 - 10;
				} 
				return result + "";
			}
		} else {
			return "";
		}
	}
	/**
	 * 根據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
	 * @return
	 */
	private static String getimei15(String imei){
		if (imei.length() == 14) {
			char[] imeiChar=imei.toCharArray();  
	        int resultInt=0;  
	        for (int i = 0; i < imeiChar.length; i++) {  
	            int a=Integer.parseInt(String.valueOf(imeiChar[i]));  
	            i++;  
	            final int temp=Integer.parseInt(String.valueOf(imeiChar[i]))*2;  
	            final int b=temp<10?temp:temp-9;  
	            resultInt+=a+b;  
	        }  
	        resultInt%=10;  
	        resultInt=resultInt==0?0:10-resultInt;  
	        return resultInt + "";
		}else{
			return "";
		}
	}
}


參考:http://blog.sina.com.cn/s/blog_53842fbe0100f3az.html