import binascii

# Chemin du fichier d'entrée
input_file = "/var/www/html/modification_carto/ori ocas pcr 2.1"

# Lire le fichier en mode binaire
with open(input_file, 'rb') as file:
    file_content = file.read()

# Convertir le contenu binaire en hexadécimal pour une meilleure lisibilité
hex_content = binascii.hexlify(file_content).decode('utf-8')

# Afficher les 1000 premiers caractères pour analyse initiale
print("First 1000 characters of the file in hex:")
print(hex_content[:1000])

# Définir le MCUID connu
mcuid_hex = "410482850C80A82F830600102417E000"
mcuid_bytes = bytes.fromhex(mcuid_hex)

# Diviser le fichier en segments plus petits pour gérer la charge de calcul
segment_size = len(mcuid_bytes)
num_segments = len(file_content) // segment_size

matching_segments = []

# Fonction pour appliquer des transformations spécifiques
def apply_specific_transformations(segment, mcuid_bytes):
    transformations = []
    for i in range(len(segment)):
        original_byte = segment[i]
        mcuid_byte = mcuid_bytes[i]
        results = {
            "addition_mod": (original_byte + mcuid_byte) % 256,
            "xor": original_byte ^ mcuid_byte,
            "subtraction_mod": (original_byte - mcuid_byte) % 256
        }
        transformations.append(results)
        if mcuid_byte in results.values():
            return True, transformations
    return False, transformations

# Analyser des segments spécifiques
for i in range(num_segments):
    segment = file_content[i * segment_size: (i + 1) * segment_size]
    
    # Exclure les segments contenant principalement des zéros
    if segment.count(0) > segment_size / 2:
        continue
    
    match, transformations = apply_specific_transformations(segment, mcuid_bytes)
    if match:
        matching_segments.append((i, segment, transformations))

# Fonction pour appliquer des transformations inversées
def invert_transformations(segment, transformations):
    inverted_bytes = []
    for i, trans in enumerate(transformations):
        mcuid_byte = None
        if trans["addition_mod"] == (segment[i] + mcuid_bytes[i]) % 256:
            mcuid_byte = (trans["addition_mod"] - segment[i]) % 256
        elif trans["xor"] == (segment[i] ^ mcuid_bytes[i]):
            mcuid_byte = segment[i] ^ trans["xor"]
        elif trans["subtraction_mod"] == (segment[i] - mcuid_bytes[i]) % 256:
            mcuid_byte = (trans["subtraction_mod"] + segment[i]) % 256
        inverted_bytes.append(mcuid_byte)
    return inverted_bytes

# Appliquer les transformations inversées sur les segments correspondants et extraire le MCUID
mcuid_segments = []

print("Matching segments in the file:")
for index, segment, transformations in matching_segments[:10]:  # Afficher seulement les 10 premiers pour éviter de surcharger
    inverted_bytes = invert_transformations(segment, transformations)
    mcuid_segments.append(inverted_bytes)
    print(f"Index: {index}, Segment: {segment.hex()}")
    for i, (orig, trans, inv) in enumerate(zip(segment, transformations, inverted_bytes)):
        print(f"  Byte {i}: Original: {orig}, Transformations: {trans}, Inverted Byte: {inv}")

# Afficher le nombre total de segments correspondants
print(f"Total matching segments: {len(matching_segments)}")

# Combiner les segments pour former le MCUID sans duplication
final_mcuid_bytes = []
seen = set()

for segment in mcuid_segments:
    for byte in segment:
        if byte is not None and byte not in seen:
            seen.add(byte)
            final_mcuid_bytes.append(byte)

final_mcuid_hex = ''.join([f'{byte:02x}' for byte in final_mcuid_bytes])

print(f"Extracted MCUID: {final_mcuid_hex}")
