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=1C 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

时间: 2024-10-06 22:36:21

IMEI/MEID校验位计算的相关文章

[技术栈]C#利用Luhn算法(模10算法)对IMEI校验

1.Luhn算法(模10算法) 通过查看ISO/IEC 7812-1:2017文件可以看到对于luhn算法的解释,如下图: 算法主要分为三步: 第一步:从右边第一位(最低位)开始隔位乘2: 第二步:把第一步所得的每一个数字加入到原来的数中,比如9*2=18,为1+8: 第三步:用以0结尾且大于第二步所获得的数的和的最小整数减去第二步所获得的合即可以获得校验位,如70-67=3,3即为校验位,如果第二步所有数字的和以0结尾,比如30.40.50等,那么校验为0: 2.IMEI校验 IMEI码由GS

Android如何获取SIM卡信息

android 获取sim卡运营商信息 TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE); TelephonyManager 的使用 TelephonyManager 提供设备上获取通讯服务信息的入口,应用程序使用这个类的方法来获取电话的服务商或者状态.程序也可以注册一个监听器来监听电话状态的改变. 不需要直接实例化这个类,使用Context.getSystemS

3.zookeeper原理解析-数据存储之TxnLog事务日志

=====================================斩秋|http://blog.csdn.net/quhongwei_zhanqiu======================================= 事务日志文件用来记录事物操作,每一个事务操作如添加,删除节点等等,都会在事务日志中记录一条记录,用来在zookeeper异常情况下,通过txnlog和snapshot文件来恢复数据,下面我们来看下txnLog事务日志文件的格式 打开一个事务日志文件看看 一个日志文

Android逆向之旅---静态方式破解微信获取聊天记录和通讯录信息

一.猜想数据存放路径 微信现在是老少皆宜,大街小巷都在使用,已经替代了传统的短信聊天方式了,只要涉及到聊天就肯定有隐私消息,那么本文就来讲解如何获取微信的聊天记录以及通讯录信息. 首先我们在没有网络的时候,打开微信同样可以查看聊天记录,说明微信会把聊天记录保存到本地,那么这么多信息肯定会保存在数据库中,所以我们可以去查看微信的databases目录看看内容: 可惜的是,我们在这个里面并没有发现一些有用的数据,所以这时候就了解到了微信因为把重要信息的数据库存在其他目录下面,我们可以直接把微信的整个

Genymotion User Guide

Discover Genymotion User Guide FAQ Support/Contact API Get Genymotion Go to preview program Overview Features Requirements Installation Quick Start Licensing Genymotion Application Genymotion virtual devices Eclipse Plugin IntelliJ Plugin Genymotion

身份证号码生成与校验

在测试过程中难免会遇到需要身份证号码的情况,记录下随机生成身份证号码与如何检验身份证号码的方法. 首先要了解身份证号码的组成方式: 号码结构:公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码. 地址码(前六位数):表示编码对象常住户口所在县(市.旗.区)的行政区划代码,按GB/T2260的规定执行. 出生日期码(第七位至十四位):表示编码对象出生的年.月.日,按GB/T7408的规定执行,年.

Android 最常用的快速开发工具类

Android开发的工具类能很好的封装一些常用的操作,以后使用起来也非常方便,我把我经常使用的工具类分享给大家. FileCache: package com.pztuan.common.util; import java.io.File; import android.content.Context; public class FileCache { private File cacheDir; public FileCache(Context context) { // 判断外存SD卡挂载状

android 获取sim卡运营商信息(转)

TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE); 注意:一些电话信息需要相应的权限. // 获取服务提供商名字,比如电信,联通,移动用下面的方法第一种方法: 获取手机的IMSI码,并判断是中国移动\中国联通\中国电信 getSimOperatorName() //Returns the Service Provider Name (SPN). IMSI 国际移动

【工具类】获取手机sim卡的运营商

加入权限:<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 1 package com.example.textphone; 2 3 import android.content.Context; 4 import android.telephony.TelephonyManager; 5 6 public class SIMCardInfo { 7 /** 8 * Telephon