Skip to content

Hardware 1⚓︎

Difficulty:
image

Objective⚓︎

Jingle all the wires and connect to Santa's Little Helper to reveal the merry secrets locked in his chest!

Hints⚓︎

For this challenge, we are given a python script, heuristics.py and we use the file called shreds.zip that was retrieved during the completion of Frosty Keypad.

Silver⚓︎

The first thing we will need to understand is how the wires might go together to power the device on. Let's have a look at the documentation provided: documentation

Generally speaking, there are industry standards to how these pieces fit together:

  • GND (Ground): Connect GND to the corresponding GND on the motherboard.
  • TX (Transmit): Connect the TX pin on the UART-Bridge to the RX (Receive) pin on the motherboard.
  • RX (Receive): Connect the RX pin on the UART-Bridge to the TX (Transmit) pin on the motherboard.
  • VCC (Voltage): Connect VCC to the corresponding power (VCC or 3.3V/5V, as specified by the UART-Bridge).
  • USB: Connect from the UART-Bridge to the console.
  • Red Wire: Often used for VCC (power).
  • Black Wire: Commonly used for GND (ground).
  • Green Wire: Sometimes used for TX.
  • Yellow Wire: Sometimes used for RX.

Now that the console is powered on, we can have a look at the options. It seems we will need a bit more info that is generally available in the documentation. Perhaps this is what we need the shreds.zip and python script for!

Unzip the file and then run it through the python script.

unzip shreds.zip

heuristics.py
import os
import numpy as np
from PIL import Image

def load_images(folder):
    images = []
    filenames = sorted(os.listdir(folder))
    for filename in filenames:
        if filename.endswith('.png') or filename.endswith('.jpg'):
            img = Image.open(os.path.join(folder, filename)).convert('RGB')
            images.append(np.array(img))
    return images

def calculate_difference(slice1, slice2):
    # Calculate the sum of squared differences between the right edge of slice1 and the left edge of slice2
    return np.sum((slice1[:, -1] - slice2[:, 0]) ** 2)

def find_best_match(slices):
    n = len(slices)
    matched_slices = [slices[0]]
    slices.pop(0)

    while slices:
        last_slice = matched_slices[-1]
        differences = [calculate_difference(last_slice, s) for s in slices]
        best_match_index = np.argmin(differences)
        matched_slices.append(slices.pop(best_match_index))

    return matched_slices

def save_image(images, output_path):
    heights, widths, _ = zip(*(i.shape for i in images))

    total_width = sum(widths)
    max_height = max(heights)

    new_image = Image.new('RGB', (total_width, max_height))

    x_offset = 0
    for img in images:
        pil_img = Image.fromarray(img)
        new_image.paste(pil_img, (x_offset, 0))
        x_offset += pil_img.width

    new_image.save(output_path)

def main():
    input_folder = './slices'
    output_path = './assembled_image.png'

    slices = load_images(input_folder)
    matched_slices = find_best_match(slices)
    save_image(matched_slices, output_path)

if __name__ == '__main__':
    main()

Unzipping shreds.zip produced many slices files. So long as our python script and the slices are in our pwd, we should be good to run this:

python3 heuristics.py
Running the script provides us with a new file called assembled_image.png: assembledimage

While the picture is reversed, it can still be easily read and followed for the solution: process

silverSolution

Gold⚓︎

After achieving Silver, Jewell says, "Rumor has it you might be able to bypass the hardware altogether for the gold medal. Why not see if you can find that shortcut?"

Whelp, this seems like an indicator that the next step is somewhere in the source code. source code After having a look, we find that there are comments indicating the old api version might be the answer.

Interestingly, it was still necessary for me to use the hardware first because that was what I used to generate the POST request to version 1, but alas, here is the solution:

  1. Network tab
  2. Find the POST request from submitting the answer for Silver (or regenerate it if you're coming back to this challenge after closing your browser) and right-click the POST request to select Edit & Resend.
  3. Modify the URL to read v1 instead of v2.
  4. Send the modified URL.

gold solution