是否可以验证 IMEI 号码?

Posted

技术标签:

【中文标题】是否可以验证 IMEI 号码?【英文标题】:Is it possible to validate IMEI Number? 【发布时间】:2014-10-03 11:26:53 【问题描述】:

对于移动商店应用程序,我需要验证 IMEI number。我知道如何根据输入长度进行验证,但是他们还有其他验证输入数字的机制吗?是否有任何内置功能可以实现这一点?

任何语言的逻辑都被接受和赞赏。

【问题讨论】:

如果您只是想检查号码是否输入正确,en.wikipedia.org/wiki/IMEI。 Check for valid IMEI的可能重复 那个答案不符合我的要求,这个问题没有正确回答,只给出了一个提示。我的问题得到了更好的答案。我接受了 【参考方案1】:

我认为没有任何内置方法可以验证 IMEI 号码。您需要根据第三方数据库进行验证(谷歌搜索表明有许多此类服务,但大概他们也从更集中的来源获取信息)。

【讨论】:

【参考方案2】:

搜索表明没有内置函数可以验证 IMEI 号码,但有一种使用 Luhn algorithm 的验证方法。

一般流程:

    输入IMEI:490154203237518 去掉最后一个数字,记住它:49015420323751 & 8。最后一个数字 8 是验证数字。 IMEI 中的每个第二个数字加倍:4 18 0 2 5 8 2 0 3 4 3 14 5 2(不包括验证数字) 将此号码分成一位数:4 1 8 0 2 5 8 2 0 3 4 3 1 4 5 2(请注意,1814 已分开)。 将所有数字相加:4+1+8+0+2+5+8+2+0+3+4+3+1+4+5+2 = 52 将得到的数字记下来,然后四舍五入到最接近的十的倍数:60。 从四舍五入的数字中减去您的原始数字:60 - 52 = 8。 将结果与您的原始验证数字进行比较。如果两个号码匹配,则您的 IMEI 有效。

上面第 1 步中给出的 IMEI 是有效的,因为在第 7 步中找到的数字是 8,与验证数字匹配。

【讨论】:

我第6步,它应该是最接近十的下一个倍数。【参考方案3】:

我认为这个逻辑是不正确的,因为这仅适用于特定的 IMEI 号码 - 490154203237518 不适用于其他 IMEI 号码......我也实现了代码......

var number = 490154203237518;
var array1 = new Array();
var array2 = new Array();
var specialno = 0 ;
var sum = 0 ;
var finalsum = 0;
var cast = number.toString(10).split('');
var finalnumber = '';
if(cast.length == 15)
    for(var i=0,n = cast.length; i<n; i++)

        if(i !== 14)
          if(i == 0 || i%2 == 0 )
            array1[i] = cast[i];
          else
            array1[i] = cast[i]*2;
          
        else
           specialno = cast[14];
        

     

     for(var j=0,m = array1.length; j<m; j++)
        finalnumber = finalnumber.concat(array1[j]);
     

     while(finalnumber)
        finalsum += finalnumber % 10;
        finalnumber = Math.floor(finalnumber / 10);
     

    contno = (finalsum/10);
    finalcontno = Math.round(contno)+1;

    check_specialno = (finalcontno*10) - finalsum; 

    if(check_specialno == specialno)
        alert('Imei')
    else
        alert('Not IMEI');
    
else
    alert('NOT imei - length not matching');
   


 //alert(sum);

【讨论】:

【参考方案4】:

根据Karl Nicoll 中的previous answer,我在Java 中创建了这个方法。

public static int validateImei(String imei) 

    //si la longitud del imei es distinta de 15 es invalido
    if (imei.length() != 15)
        return CheckImei.SHORT_IMEI;

    //si el imei contiene letras es invalido
    if (!PhoneNumber.allNumbers(imei))
        return CheckImei.MALFORMED_IMEI;

    //obtener el ultimo digito como numero
    int last = imei.charAt(14) - 48;

    //duplicar cada segundo digito
    //sumar cada uno de los digitos resultantes del nuevo imei
    int curr;
    int sum = 0;
    for (int i = 0; i < 14; i++) 
        curr = imei.charAt(i) - 48;
        if (i % 2 != 0)
            // sum += duplicateAndSum(curr);
            // initial code from Osvel Alvarez Jacomino contains 'duplicateAndSum' method.
            // replacing it with the implementation down here:
            curr = 2 * curr;
            if(curr > 9) 
                curr = (curr / 10) + (curr - 10);
            
            sum += curr;
        
        else 
            sum += curr;
        

    

    //redondear al multiplo de 10 superior mas cercano
    int round = sum % 10 == 0 ? sum : ((sum / 10 + 1) * 10);

    return (round - sum == last) ? CheckImei.VALID_IMEI_NO_NETWORK : CheckImei.INVALID_IMEI;


【讨论】:

【参考方案5】:

IMEI 可以从 0 位开始。这就是函数输入是字符串的原因。 感谢@KarlNicol的方法

Golang

func IsValid(imei string) bool 
    digits := strings.Split(imei, "")

    numOfDigits := len(digits)

    if numOfDigits != 15 
        return false
    

    checkingDigit, err := strconv.ParseInt(digits[numOfDigits-1], 10, 8)
    if err != nil 
        return false
    

    checkSum := int64(0)
    for i := 0; i < numOfDigits-1; i++  // we dont need the last one
        convertedDigit := ""

        if (i+1)%2 == 0 
            d, err := strconv.ParseInt(digits[i], 10, 8)
            if err != nil 
                return false
            
            convertedDigit = strconv.FormatInt(2*d, 10)
         else 
            convertedDigit = digits[i]
        

        convertedDigits := strings.Split(convertedDigit, "")

        for _, c := range convertedDigits 
            d, err := strconv.ParseInt(c, 10, 8)
            if err != nil 
                return false
            
            checkSum = checkSum + d
        

    

    if (checkSum+checkingDigit)%10 != 0 
        return false
    

    return true

【讨论】:

以上是关于是否可以验证 IMEI 号码?的主要内容,如果未能解决你的问题,请参考以下文章

手机串号开发思路运行原理解剖

有啥方法可以使用 C# 获取 Windows Phone 设备的 IMEI 号码

在所有 android 设备中获取多个 imei 号码

我怎样才能得到IMEI号码。我的设备通过离子?

如何处理2电话权限以获取设备的IMEI号码和手机号码?

为啥模拟器给IMEI号码000000000000000