Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

09 - Santas Quick Response 3.0

Description

Level: Medium
Author: brp64 feat. M.

Visiting the following railway station has left lasting memories.

Railway station

Santas brand new gifts distribution system is heavily inspired by it. Here is your personal gift, can you extract the destination path of it?

QR code

Solution

First, I did an image reverse-search to find out more about the railway station. This lead to the Wikipedia article about rule 30. From there one it was obvious what I had to do: I took the "tree" structure generated by rule 30 and XORed it with the QR Code. At first this did not give a valid QR Code because the rule 30 structure was misaligned by one pixel. By running the following code I got the new QR code:

public class Rule30 {

    public static void main(String[] args) throws IOException {
        BufferedImage image = ImageIO.read(new File("original.png"));
        byte[][] rule30 = rule30();

        for (int i = 0; i < 33; i++) {
            for (int j = 0; j < 33; j++) {
                Color color = new Color(image.getRGB(i, j));

                byte value = toByte(color);
                byte newValue = (byte) (value ^ rule30[j][i + 84]); // Off by one!

                image.setRGB(i, j, fromByte(newValue).getRGB());
            }
        }

        ImageIO.write(image, "PNG", new File("solution.png"));
    }

    private static byte[][] rule30() {
        byte[][] cells = new byte[33][200]; // Greater
        cells[0][cells[0].length / 2 + 1] = 1;

        for (int r = 0; r < 32; r++) {
            for (int c = 1; c < 199; c++) {
                byte lhs = cells[r][c - 1];
                byte mid = cells[r][c];
                byte rhs = cells[r][c + 1];
                cells[r + 1][c] = (byte) (lhs ^ (mid | rhs));
            }
        }

        return cells;
    }

    private static byte toByte(Color color) {
        return (byte) (Color.BLACK.equals(color) ? 1 : 0);
    }

    private static Color fromByte(byte value) {
        return value == 1 ? Color.BLACK : Color.WHITE;
    }

}

QR Code

Scanning the code gave the flag HV19{Cha0tic_yet-0rdered}.