import binascii

# Path to the input file
input_file = "/var/www/html/modification_carto/volkswagensimospcr2.1_bench_fullbackup_41048480128019348206001024fade00_20230407173439_int_flash.bin"


# Read the file in binary mode
with open(input_file, 'rb') as file:
    file_content = file.read()

# Convert the file content to hexadecimal
hex_content = binascii.hexlify(file_content).decode('utf-8')
first_1000_chars = hex_content[:1000]
print("First 1000 characters of the file in hex:")
print(first_1000_chars)

# Known MCUID for verification
mcuid_hex = "4104848012801934"
mcuid_bytes = bytes.fromhex(mcuid_hex)

# Define segment size and calculate the number of segments
segment_size = len(mcuid_bytes)
num_segments = len(file_content) // segment_size

matching_segments = []

# Function to apply specific transformations
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": (mcuid_byte + original_byte) % 256,
            "xor": mcuid_byte ^ original_byte,
            "subtraction_mod": (mcuid_byte - original_byte) % 256
        }
        transformations.append(results)
    return transformations

# Analyze the segments
for i in range(num_segments):
    segment = file_content[i * segment_size: (i + 1) * segment_size]
    
    # Skip segments with mostly zeros
    if segment.count(0) > segment_size / 2:
        continue
    
    transformations = apply_specific_transformations(segment, mcuid_bytes)
    matching_segments.append((i, segment, transformations))

# Function to deduce MCUID
def deduce_mcuid(segment, transformations):
    deduced_bytes = [None] * len(segment)
    for i, trans in enumerate(transformations):
        if trans["addition_mod"] == (mcuid_bytes[i] + segment[i]) % 256:
            deduced_bytes[i] = (trans["addition_mod"] - segment[i]) % 256
        elif trans["xor"] == (mcuid_bytes[i] ^ segment[i]):
            deduced_bytes[i] = segment[i] ^ trans["xor"]
        elif trans["subtraction_mod"] == (mcuid_bytes[i] - segment[i]) % 256:
            deduced_bytes[i] = (trans["subtraction_mod"] + segment[i]) % 256
    return deduced_bytes

# Process matching segments and deduce MCUID
matching_segments_info = []
for index, segment, transformations in matching_segments:
    deduced_bytes = deduce_mcuid(segment, transformations)
    segment_info = {
        "index": index,
        "segment": segment,
        "deduced_bytes": deduced_bytes,
        "transformations": transformations
    }
    matching_segments_info.append(segment_info)

# Verify deduced MCUID
def verify_mcuid(deduced_bytes):
    return all(byte is not None for byte in deduced_bytes)

final_deduced_mcuid = [None] * segment_size
for segment_info in matching_segments_info:
    deduced_bytes = segment_info["deduced_bytes"]
    for i in range(segment_size):
        if final_deduced_mcuid[i] is None and deduced_bytes[i] is not None:
            final_deduced_mcuid[i] = deduced_bytes[i]

deduced_mcuid_hex = ''.join([format(byte, '02x') if byte is not None else '??' for byte in final_deduced_mcuid])
deduced_mcuid_valid = verify_mcuid(final_deduced_mcuid)

# Gather results to display
results = {
    "first_1000_chars_hex": first_1000_chars,
    "matching_segments_info": matching_segments_info[:10],  # Show only first 10 for brevity
    "total_matching_segments": len(matching_segments_info),
    "final_deduced_mcuid": final_deduced_mcuid,
    "deduced_mcuid_hex": deduced_mcuid_hex,
    "deduced_mcuid_valid": deduced_mcuid_valid
}

print("Matching segments in the file:")
for segment_info in matching_segments_info[:10]:
    index = segment_info["index"]
    segment = segment_info["segment"]
    transformations = segment_info["transformations"]
    deduced_bytes = segment_info["deduced_bytes"]
    
    print(f"Index: {index}, Segment: {segment.hex()}")
    for i, (orig, trans, deduced) in enumerate(zip(segment, transformations, deduced_bytes)):
        print(f"  Byte {i}: Original: {orig}, Transformations: {trans}, Deduced MCUID Byte: {deduced}")

print(f"Total matching segments: {len(matching_segments_info)}")

if verify_mcuid(final_deduced_mcuid):
    print("Deduced MCUID (bytes):")
    print(final_deduced_mcuid)
    print(f"Deduced MCUID (hex): {deduced_mcuid_hex}")
else:
    print("Failed to deduce a complete and valid MCUID.")