def validate_imei(imei: str) -> bool:
"""
Function to validate the International Mobile Equipment Identity
(IMEI
) number.
IMEI
is a unique identifier for mobile devices
, consisting of
15 digits
. The last digit
is a check digit calculated using the Luhn algorithm
.
Parameters:
- imei: str
The IMEI
number to be validated
.
Returns:
- bool:
True if the IMEI
is valid
, False otherwise
.
Raises:
- ValueError:
Raises an error if the IMEI
is not a string or if it does not consist of exactly
15 digits
. """
# Checking if the IMEI
is a string and consists of exactly
15 digits
if not isinstance(imei, str) or not imei.isdigit() or len(imei) != 15:
raise ValueError("IMEI should be a string consisting of exactly 15 digits.")
# Calculating the check digit using the Luhn algorithm
check_digit = int(imei[-1])
imei_digits = [int(digit) for digit in imei[:-1]]
imei_digits.reverse()
for i in range(len(imei_digits)):
if i % 2 == 0:
imei_digits[i] *= 2
if imei_digits[i] > 9:
imei_digits[i] -= 9
calculated_check_digit = (10 - sum(imei_digits) % 10) % 10
# Validating the check digit
return check_digit == calculated_check_digit
# Example usage:
imei_number = "123456789012345"
is_valid = validate_imei(imei_number)
print
(f"The IMEI
number {imei_number
} is valid
: {is_valid
}"
)
ZGVmIHZhbGlkYXRlX2ltZWkoaW1laTogc3RyKSAtPiBib29sOgogICAgIiIiCiAgICBGdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgSW50ZXJuYXRpb25hbCBNb2JpbGUgRXF1aXBtZW50IElkZW50aXR5IChJTUVJKSBudW1iZXIuCiAKICAgIElNRUkgaXMgYSB1bmlxdWUgaWRlbnRpZmllciBmb3IgbW9iaWxlIGRldmljZXMsIGNvbnNpc3Rpbmcgb2YgMTUgZGlnaXRzLgogICAgVGhlIGxhc3QgZGlnaXQgaXMgYSBjaGVjayBkaWdpdCBjYWxjdWxhdGVkIHVzaW5nIHRoZSBMdWhuIGFsZ29yaXRobS4KIAogICAgUGFyYW1ldGVyczoKICAgIC0gaW1laTogc3RyCiAgICAgICAgVGhlIElNRUkgbnVtYmVyIHRvIGJlIHZhbGlkYXRlZC4KIAogICAgUmV0dXJuczoKICAgIC0gYm9vbDoKICAgICAgICBUcnVlIGlmIHRoZSBJTUVJIGlzIHZhbGlkLCBGYWxzZSBvdGhlcndpc2UuCiAKICAgIFJhaXNlczoKICAgIC0gVmFsdWVFcnJvcjoKICAgICAgICBSYWlzZXMgYW4gZXJyb3IgaWYgdGhlIElNRUkgaXMgbm90IGEgc3RyaW5nIG9yIGlmIGl0IGRvZXMgbm90IGNvbnNpc3Qgb2YgZXhhY3RseSAxNSBkaWdpdHMuCiAgICAiIiIKIAogICAgIyBDaGVja2luZyBpZiB0aGUgSU1FSSBpcyBhIHN0cmluZyBhbmQgY29uc2lzdHMgb2YgZXhhY3RseSAxNSBkaWdpdHMKICAgIGlmIG5vdCBpc2luc3RhbmNlKGltZWksIHN0cikgb3Igbm90IGltZWkuaXNkaWdpdCgpIG9yIGxlbihpbWVpKSAhPSAxNToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJTUVJIHNob3VsZCBiZSBhIHN0cmluZyBjb25zaXN0aW5nIG9mIGV4YWN0bHkgMTUgZGlnaXRzLiIpCiAKICAgICMgQ2FsY3VsYXRpbmcgdGhlIGNoZWNrIGRpZ2l0IHVzaW5nIHRoZSBMdWhuIGFsZ29yaXRobQogICAgY2hlY2tfZGlnaXQgPSBpbnQoaW1laVstMV0pCiAgICBpbWVpX2RpZ2l0cyA9IFtpbnQoZGlnaXQpIGZvciBkaWdpdCBpbiBpbWVpWzotMV1dCiAgICBpbWVpX2RpZ2l0cy5yZXZlcnNlKCkKIAogICAgZm9yIGkgaW4gcmFuZ2UobGVuKGltZWlfZGlnaXRzKSk6CiAgICAgICAgaWYgaSAlIDIgPT0gMDoKICAgICAgICAgICAgaW1laV9kaWdpdHNbaV0gKj0gMgogICAgICAgICAgICBpZiBpbWVpX2RpZ2l0c1tpXSA+IDk6CiAgICAgICAgICAgICAgICBpbWVpX2RpZ2l0c1tpXSAtPSA5CiAKICAgIGNhbGN1bGF0ZWRfY2hlY2tfZGlnaXQgPSAoMTAgLSBzdW0oaW1laV9kaWdpdHMpICUgMTApICUgMTAKIAogICAgIyBWYWxpZGF0aW5nIHRoZSBjaGVjayBkaWdpdAogICAgcmV0dXJuIGNoZWNrX2RpZ2l0ID09IGNhbGN1bGF0ZWRfY2hlY2tfZGlnaXQKIAojIEV4YW1wbGUgdXNhZ2U6CmltZWlfbnVtYmVyID0gIjEyMzQ1Njc4OTAxMjM0NSIKaXNfdmFsaWQgPSB2YWxpZGF0ZV9pbWVpKGltZWlfbnVtYmVyKQpwcmludChmIlRoZSBJTUVJIG51bWJlciB7aW1laV9udW1iZXJ9IGlzIHZhbGlkOiB7aXNfdmFsaWR9Iik=