import sys
import numpy as np

# Vérification du nombre d'arguments
if len(sys.argv) != 4:
    print("Usage: python3 final_mcuid.py <input_file> <output_file> <mcuid_file>")
    sys.exit(1)

# Chemins des fichiers à partir des arguments
file_paths = {
    "input_file": sys.argv[1],
    "output_file": sys.argv[2],
    "mcuid_file": sys.argv[3]
}

# Lire le contenu du fichier d'entrée
with open(file_paths["input_file"], "rb") as file:
    original_bytes = list(file.read())

# Lire le MCUID depuis le fichier
with open(file_paths["mcuid_file"], "r") as file:
    mcuid_hex = file.read().strip()
mcuid_bytes = bytes.fromhex(mcuid_hex)

# 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 None  # Return None if no transformation matches

# Appliquer les transformations aux octets pertinents
mcuid_not_found = False
for i, pos in enumerate(relevant_positions):
    original_byte = original_bytes[pos]
    mcuid_byte = mcuid_bytes[i % len(mcuid_bytes)]
    reference_byte = reference_bytes[i]
    transformed_byte = apply_transformations_v3(original_byte, mcuid_byte, reference_byte)
    if transformed_byte is None:
        mcuid_not_found = True
        break  # Exit the loop if MCUID is not found
    original_bytes[pos] = transformed_byte

if mcuid_not_found:
    print("mcuid non trouvé")
else:
    # Écrire le fichier de sortie
    with open(file_paths["output_file"], "wb") as file:
        file.write(bytearray(original_bytes))
    print("Transformations appliquées et fichier de sortie écrit avec succès.")
