在python中生成IMEI

时间:2013-12-22 19:07:56

标签: python luhn

您好我正在尝试在python中创建一个函数来生成有效的IMEI号,所以这是我的函数.IMEI验证使用Luhn算法,所以我试图在我的脚本中实现它。

def getImei():
    num = ''
    suma = 0
    for i in range(0,13):
        digit = random.randrange(0,9)
        suma = suma + digit
        num = num + str(digit)

    suma = suma * 9
    digit = suma % 10
    num = num + str(digit)
    return num

但该功能无法生成有效的IMEI号码。我在维基百科上发现了一篇文章,告诉我如何生成校验位(http://en.wikipedia.org/wiki/Luhn_algorithm

校验位(x)是通过计算数字之和然后计算9次模10的值(方程形式,(67 * 9 mod 10))获得的。 在算法形式: 1.计算数字之和(67)。 2.乘以9(603)。 3.最后一位数字3是校验位。

我错过了什么或维基是错的吗?

3 个答案:

答案 0 :(得分:5)

请注意,奇数(从最后开始,从0开始)位置的数字加倍,因此您必须将其添加到代码中,例如,以下代码将返回luhn校验和:

def luhn_residue(digits):
    return sum(sum(divmod(int(d)*(1 + i%2), 10))
                 for i, d in enumerate(digits[::-1])) % 10

对于奇数位数,(1 + i%2)乘数等于2,而对于偶数位置,1等于sum(divmod(..., 10))。然后def getImei(N): part = ''.join(str(random.randrange(0,9)) for _ in range(N-1)) res = luhn_residue('{}{}'.format(part, 0)) return '{}{}'.format(part, -res%10) 返回(可能)两位数字的数字总和,以及外部总和产生的序列。

您可以使用它来生成有效的数字序列:

>>> luhn_residue('79927398713')
0
>>> luhn_residue('05671564547361')
6
>>> luhn_residue(getImei(14))
0

演示:

{{1}}

答案 1 :(得分:1)

如果结果大于10,您将跳过将所有其他数字加倍的步骤并取其总和。来自Wikipedia

  

从最右边的数字,即校验位,向左移动,每隔一位数的值加倍;如果该倍增操作的乘积大于9(例如,7 * 2 = 14),则将产品的数字相加(例如,10:1 + 0 = 1,14:1 + 4 = 5)。

答案 2 :(得分:0)

来自@alko的解决方案并不适用于所有IMEI号码:请参阅this list有效的imei号码(或cc号码,实际上是相同的)。

以下是有效的解决方案:

def luhn_residue(digits):
    """ Lunh10 residue value """
    s = sum(d if (n % 2 == 1) else (0, 2, 4, 6, 8, 1, 3, 5, 7, 9)[d]
            for n, d in enumerate(map(int, reversed(digits))))
    return (10 - s % 10) % 10