mirror of
https://github.com/srlabs/blue-merle.git
synced 2025-04-21 07:46:33 -04:00
Merge b7999c0ad19da8094f77170dcd62cb5c723eacb3 into d3aa7ae988bb52a5f26d07fe0cfd06a892724d69
This commit is contained in:
commit
558e204417
@ -6,15 +6,12 @@ import serial
|
||||
import re
|
||||
from functools import reduce
|
||||
from enum import Enum
|
||||
from tacs import tacs
|
||||
|
||||
|
||||
class Modes(Enum):
|
||||
DETERMINISTIC = 1
|
||||
RANDOM = 2
|
||||
STATIC = 3
|
||||
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-v", "--verbose", help="Enables verbose output",
|
||||
action="store_true")
|
||||
@ -29,12 +26,14 @@ modes.add_argument("-r", "--random", help="Sets random IMEI",
|
||||
|
||||
# Example IMEI: 490154203237518
|
||||
imei_length = 14 # without validation digit
|
||||
# IDEA: make prefix configurable via CLI option
|
||||
# imei_prefix = ["35674108", "35290611", "35397710", "35323210", "35384110",
|
||||
# "35982748", "35672011", "35759049", "35266891", "35407115",
|
||||
# "35538025", "35480910", "35324590", "35901183", "35139729",
|
||||
# "35479164"]
|
||||
imei_prefix = tacs
|
||||
imei_prefix = [
|
||||
"353001", # iPhone 15
|
||||
"353002", # iPhone 15 Pro
|
||||
"351005", # Galaxy S23
|
||||
"352001", # Pixel 7
|
||||
"352101" # Pixel 8
|
||||
]
|
||||
|
||||
verbose = False
|
||||
mode = None
|
||||
|
||||
@ -43,6 +42,49 @@ TTY = '/dev/ttyUSB3'
|
||||
BAUDRATE = 9600
|
||||
TIMEOUT = 3
|
||||
|
||||
def luhn_check(imei):
|
||||
sum_val = 0
|
||||
num_digits = len(imei)
|
||||
oddeven = num_digits & 1
|
||||
|
||||
for i in range(num_digits):
|
||||
digit = int(imei[i])
|
||||
# Double every second digit if index parity matches
|
||||
if not ((i & 1) ^ oddeven):
|
||||
digit *= 2
|
||||
if digit > 9:
|
||||
digit -= 9
|
||||
sum_val += digit
|
||||
|
||||
return (10 - (sum_val % 10)) % 10
|
||||
|
||||
def generate_imei(imei_prefix, imsi_d=None):
|
||||
if mode == Modes.DETERMINISTIC and imsi_d is not None:
|
||||
random.seed(imsi_d)
|
||||
|
||||
# Pick one of the updated TACs
|
||||
imei = random.choice(imei_prefix)
|
||||
|
||||
# Fill up to 14 digits total
|
||||
random_part_length = imei_length - len(imei)
|
||||
imei += "".join(random.sample(string.digits, random_part_length))
|
||||
|
||||
# Compute the final check digit via new Luhn
|
||||
validation_digit = luhn_check(imei)
|
||||
imei = str(imei) + str(validation_digit)
|
||||
|
||||
return imei
|
||||
|
||||
def validate_imei(imei):
|
||||
# Now we expect 14 base digits, with a final digit for check
|
||||
# (Still references length == 14, which you can adapt if needed)
|
||||
if len(imei) != 14:
|
||||
return False
|
||||
|
||||
validation_digit = int(imei[-1])
|
||||
imei_verify = imei[0:14]
|
||||
validation_digit_verify = luhn_check(imei_verify)
|
||||
return validation_digit == validation_digit_verify
|
||||
|
||||
def get_imsi():
|
||||
if (verbose):
|
||||
@ -101,86 +143,6 @@ def get_imei():
|
||||
|
||||
return b"".join(imei_d)
|
||||
|
||||
|
||||
def generate_imei(imei_prefix, imsi_d):
|
||||
# In deterministic mode we seed the RNG with the IMSI.
|
||||
# As a consequence we will always generate the same IMEI for a given IMSI
|
||||
if (mode == Modes.DETERMINISTIC):
|
||||
random.seed(imsi_d)
|
||||
|
||||
# We choose a random prefix from the predefined list.
|
||||
# Then we fill the rest with random characters
|
||||
imei = random.choice(imei_prefix)
|
||||
if (verbose):
|
||||
print(f"IMEI prefix: {imei}")
|
||||
random_part_length = imei_length - len(imei)
|
||||
if (verbose):
|
||||
print(f"Length of the random IMEI part: {random_part_length}")
|
||||
imei += "".join(random.sample(string.digits, random_part_length))
|
||||
if (verbose):
|
||||
print(f"IMEI without validation digit: {imei}")
|
||||
|
||||
# calculate validation digit
|
||||
# Double each second digit in the IMEI: 4 18 0 2 5 8 2 0 3 4 3 14 5 2
|
||||
# (excluding the validation digit)
|
||||
|
||||
iteration_1 = "".join([c if i % 2 == 0 else str(2*int(c)) for i, c in enumerate(imei)])
|
||||
|
||||
# Separate this number into single digits: 4 1 8 0 2 5 8 2 0 3 4 3 1 4 5 2
|
||||
# (notice that 18 and 14 have been split).
|
||||
# Add up all the numbers: 4+1+8+0+2+5+8+2+0+3+4+3+1+4+5+2 = 52
|
||||
|
||||
sum = reduce((lambda a, b: int(a) + int(b)), iteration_1)
|
||||
|
||||
# Take your resulting number, remember it, and round it up to the nearest
|
||||
# multiple of ten: 60.
|
||||
# Subtract your original number from the rounded-up number: 60 - 52 = 8.
|
||||
|
||||
validation_digit = (10 - int(str(sum)[-1])) % 10
|
||||
if (verbose):
|
||||
print(f"Validation digit: {validation_digit}")
|
||||
|
||||
imei = str(imei) + str(validation_digit)
|
||||
if (verbose):
|
||||
print(f"Resulting IMEI: {imei}")
|
||||
|
||||
return imei
|
||||
|
||||
|
||||
def validate_imei(imei):
|
||||
# before anything check if length is 14 characters
|
||||
if len(imei) != 14:
|
||||
print(f"NOT A VALID IMEI: {imei} - IMEI must be 14 characters in length")
|
||||
return False
|
||||
# cut off last digit
|
||||
validation_digit = int(imei[-1])
|
||||
imei_verify = imei[0:14]
|
||||
if (verbose):
|
||||
print(imei_verify)
|
||||
|
||||
# Double each second digit in the IMEI
|
||||
iteration_1 = "".join([c if i % 2 == 0 else str(2*int(c)) for i, c in enumerate(imei_verify)])
|
||||
|
||||
# Separate this number into single digits and add them up
|
||||
sum = reduce((lambda a, b: int(a) + int(b)), iteration_1)
|
||||
if (verbose):
|
||||
print(sum)
|
||||
|
||||
# Take your resulting number, remember it, and round it up to the nearest
|
||||
# multiple of ten.
|
||||
# Subtract your original number from the rounded-up number.
|
||||
validation_digit_verify = (10 - int(str(sum)[-1])) % 10
|
||||
if (verbose):
|
||||
print(validation_digit_verify)
|
||||
|
||||
if validation_digit == validation_digit_verify:
|
||||
print(f"{imei} is CORRECT")
|
||||
return True
|
||||
|
||||
print(f"NOT A VALID IMEI: {imei}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = ap.parse_args()
|
||||
imsi_d = None
|
||||
@ -201,7 +163,7 @@ if __name__ == '__main__':
|
||||
else:
|
||||
exit(-1)
|
||||
else:
|
||||
imei = generate_imei(imei_prefix, imsi_d)
|
||||
imei = generate_imei(imei_prefix, imsi_d if mode == Modes.DETERMINISTIC else None)
|
||||
if (verbose):
|
||||
print(f"Generated new IMEI: {imei}")
|
||||
if not args.generate_only:
|
||||
|
Loading…
x
Reference in New Issue
Block a user