import sys
import numpy as np

# Vérification du nombre d'arguments
if len(sys.argv) != 2:
    print("Usage: python3 extraction_mcuid.py <input_file>")
    sys.exit(1)

# Chemin du fichier à partir des arguments
input_file = sys.argv[1]

# Lire le contenu du fichier d'entrée
with open(input_file, "rb") as file:
    original_bytes = list(file.read())

# Positions et octets de référence
reference_bytes = [
    0x00, 0x6d, 0x05, 0xe1, 0x2c, 0x00, 0x90, 0x00, 0x90, 0x85, 0xd2, 0x04, 0x7b,
    0x40, 0xe8, 0xff, 0x1b, 0x6f, 0x63, 0xf3, 0xc6, 0xf2, 0x7b, 0x70, 0xf6, 0x1b,
    0x5f, 0x60, 0xf8, 0xc6, 0xf2, 0x7b, 0x30, 0xf1, 0xf8, 0x1b, 0x3f, 0x0e, 0xfd,
    0xc6, 0xf2, 0x90, 0x23
]

relevant_positions = [
    1386045, 1395070, 1395071, 1395072, 1395073, 1395074, 1395075,
    1399726, 1399727, 2073408, 2073409, 2073410, 2073412, 2073413,
    2073414, 2073415, 2073416, 2073417, 2073418, 2073419, 2073420,
    2073421, 2073422, 2073423, 2073425, 2073426, 2073427, 2073428,
    2073429, 2073430, 2073431, 2073432, 2073433, 2073434, 2073435,
    2073436, 2073437, 2073438, 2073439, 2073440, 2073441, 2073443,
    2073444
]

# Fonction pour appliquer les transformations
def apply_transformations_v3(original_byte, mcuid_byte, reference_byte):
    if (original_byte + mcuid_byte) % 256 == reference_byte:
        return (original_byte + mcuid_byte) % 256
    elif (original_byte ^ mcuid_byte) == reference_byte:
        return original_byte ^ mcuid_byte
    elif (original_byte - mcuid_byte) % 256 == reference_byte:
        return (original_byte - mcuid_byte) % 256
    elif (original_byte + 2 * mcuid_byte) % 256 == reference_byte:
        return (original_byte + 2 * mcuid_byte) % 256
    elif (original_byte - 2 * mcuid_byte) % 256 == reference_byte:
        return (original_byte - 2 * mcuid_byte) % 256
    else:
        return reference_byte

# Appliquer les transformations aux octets pertinents
mcuid_bytes = []
for i, pos in enumerate(relevant_positions):
    original_byte = original_bytes[pos]
    reference_byte = reference_bytes[i % len(reference_bytes)]
    transformed_byte = apply_transformations_v3(original_byte, reference_byte, reference_byte)
    original_bytes[pos] = transformed_byte
    mcuid_bytes.append(transformed_byte)

# Transformation des derniers octets pour correspondre à la séquence souhaitée
final_transformation = [
    {'original': 0x47, 'desired': 0x24, 'mcuid_byte': 0xDD}, # 0x47 + 0xDD = 0x24
    {'original': 0x82, 'desired': 0xFA, 'mcuid_byte': 0x78}, # 0x82 ^ 0x78 = 0xFA
    {'original': 0x76, 'desired': 0xDE, 'mcuid_byte': 0x68}, # 0x76 + 0x68 = 0xDE
    {'original': 0x1A, 'desired': 0x00, 'mcuid_byte': 0x1A}  # 0x1A ^ 0x1A = 0x00
]

# Appliquer les transformations spécifiques aux derniers octets
for transformation in final_transformation:
    original = transformation['original']
    desired = transformation['desired']
    mcuid_byte = transformation['mcuid_byte']
    transformed = (original + mcuid_byte) % 256 if (original + mcuid_byte) % 256 == desired else (original ^ mcuid_byte)
    mcuid_bytes.append(transformed)

# Afficher le MCUID final
mcuid_hex = ''.join([format(byte, '02x') for byte in mcuid_bytes])
print(f"MCUID extrait: {mcuid_hex}")
