是否可以验证 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
(请注意,18
和 14
已分开)。
将所有数字相加: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 号码?的主要内容,如果未能解决你的问题,请参考以下文章