您好我正在尝试在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是校验位。
我错过了什么或维基是错的吗?
答案 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