Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate IMEI in python

Tags:

python

luhn

Hello I am trying to make a function in python to generate valid IMEI numbers so here is my function.The IMEI validation uses the Luhn algorithm so I am trying to implement it in my script.

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

The function however fails to generate valid IMEI numbers. I found an article on wikipedia that tells me how to generate the check digit ( http://en.wikipedia.org/wiki/Luhn_algorithm )

The check digit (x) is obtained by computing the sum of digits then computing 9 times that value modulo 10 (in equation form, (67 * 9 mod 10)). In algorithm form: 1.Compute the sum of the digits (67). 2.Multiply by 9 (603). 3.The last digit, 3, is the check digit.

Am I missing something or the wiki is wrong ?

like image 796
opc0de Avatar asked Dec 22 '13 19:12

opc0de


People also ask

How is IMEI number generated?

The number is assigned by the manufacturer to the cellular device, just like every other piece of equipment, for instant cars. The phone device consisting of a SIM card is recognized by a dedicated IMEI number. IMEI consists of 15-digit numbers that are guaranteed unique and accepted globally.

How do I get a valid IMEI number?

The IMEI is validated in following steps:Starting from the rightmost digit, double the value of every second digit (e.g., 7 becomes 14). If doubling of a number results in a two digits number i.e greater than 9(e.g., 7 × 2 = 14), then add the digits of the product (e.g., 14: 1 + 4 = 5), to get a single digit number.

What does a valid IMEI number look like?

A standard IMEI number is a 14 digit string, with an additional 15th check digit for verifying the entire string. There is also a 16 digit variation that includes information on the device's software version, known as the IMEISV. Since 2004, the IMEI appears in the format AA-BBBBBB-CCCCCC-D.


2 Answers

Note that numbers at odd (from the end, starting from 0) postions are doubled, so you have to add it to your code, for example following code will return luhn checksum:

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

Here (1 + i%2) multiplier equals 2 for odd positioned numbers, and 1 for even positioned. Then sum(divmod(..., 10)) returns sum of digits for a (possibly) two digit number, and outer sum sums resulting sequence.

You can use it to generate valid number sequences:

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)

Demo:

>>> luhn_residue('79927398713')
0
>>> luhn_residue('05671564547361')
6
>>> luhn_residue(getImei(14))
0
like image 84
alko Avatar answered Oct 14 '22 11:10

alko


You're skipping the step where you double every other digit and take the sum of them if the result is bigger than 10. From Wikipedia:

From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if product of this doubling operation is greater than 9 (e.g., 7 * 2 = 14), then sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5).

like image 1
Henrik Avatar answered Oct 14 '22 11:10

Henrik