QThumbnail
Alice encodes a picture into a shared entangled state and shares her quantum operations. Bob needs to reconstruct the image on his computer using this information.

info.txt
ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX I I I I I I I I ZX ZX ZX ZX ZX ZX ZX ZX...The info.txt file contains a long sequence of "ZX" and "I" strings. These represent quantum gates. "ZX" likely corresponds to a quantum operation, and "I" represents the identity gate (no operation). Based on the earlier analysis of this challenge and the shape of the image found we can try different widths until we see something.
Solution Strategy
The core strategy is to interpret the "ZX" and "I" gates as black and white pixels, respectively, and reconstruct the image using PIL (Pillow).
Step 1: Refined Code with Logging
from PIL import Image
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("solver.log"),
logging.StreamHandler()
]
)
def solve(width):
logging.info(f"Starting solving process with width={width}")
try:
with open("info.txt", "r") as f:
gates = f.read().split()
logging.debug(f"Read {len(gates)} gates from info.txt")
except FileNotFoundError:
logging.error("info.txt file not found")
return
except Exception as e:
logging.error(f"Error reading info.txt: {e}")
return
num_pixels = len(gates)
# width = 200 # Try a reasonable width based on the image hints
if num_pixels % width != 0:
logging.error(f"Error: Number of gates ({num_pixels}) is not divisible by width ({width}).")
return
height = num_pixels // width
logging.info(f"Image size: {width}x{height}")
# Create image data (0 = black, 255 = white)
image_data = []
for gate in gates:
if gate == "ZX":
image_data.append(0) # Black
elif gate == "I":
image_data.append(255) # White
else:
logging.error(f"Unknown gate: {gate}")
return
logging.debug(f"Created image data with {len(image_data)} pixels")
# Reshape the data into a 2D array
pixels = [image_data[i * width:(i + 1) * width] for i in range(height)]
logging.debug("Reshaped data into 2D array")
# Create a PIL image
img = Image.new("L", (width, height)) # "L" mode for grayscale
for y in range(height):
for x in range(width):
img.putpixel((x, y), pixels[y][x])
output_filename = f"output_{width}.png"
try:
img.save(output_filename)
logging.info(f"Image successfully saved to {output_filename}")
except Exception as e:
logging.error(f"Failed to save image: {e}")
if __name__ == "__main__":
logging.info("Script started")
# You can add code here to try different widths
solve(200) # Default width to try
logging.info("Script completed")Explanation:
Logging: Added comprehensive logging using the
loggingmodule. This helps track the script's execution, identify errors, and debug the process. Logging levels (INFO, DEBUG, ERROR) provide different levels of detail. The logging will be sent to both the console and to a filesolver.log.File Handling: Includes checks and error handling for reading
info.txt.Image Dimensions: Attempts to determine image dimensions automatically based on the number of gates. Since no automatic method was successful the
widthwas changed manually by multiple runs to check image outputs.Pixel Data: Interprets 'ZX' as black (0) and 'I' as white (255) pixels.
Reshape: Reshapes the pixel data into a 2D array representing the image.
Create Image: Uses PIL (
Image.newandputpixel) to create a grayscale image from the pixel data.Save Image: Saves the image to a file.
Step 3: Running the Code and Analyzing the Output
Running the code with a width of 200 (as shown in the code snippet you provided) generated an image file.
PS C:\Users\saleh\Downloads\CTFKareemSecurinetsTekup\qt> python .\solver.py
2025-03-15 01:37:39,056 - INFO - Script started
2025-03-15 01:37:39,056 - INFO - Starting solving process with width=200
2025-03-15 01:37:39,057 - INFO - Image size: 200x100
2025-03-15 01:37:39,087 - INFO - Image successfully saved to output_200.png
2025-03-15 01:37:39,087 - INFO - Script completed
I got to look at the QR code and by scanning using a phone scanner was able to obtain the correct flag.
Flag
The flag is: Securinets{Sup1r_Qub1t}.
Last updated
Was this helpful?