Skip to content

Instantly share code, notes, and snippets.

@n-st
Created October 16, 2015 01:25
Show Gist options
  • Save n-st/c9de1ba8a1a5024b034a to your computer and use it in GitHub Desktop.
Save n-st/c9de1ba8a1a5024b034a to your computer and use it in GitHub Desktop.
Solution for 0xf.at level 30 (https://www.0xf.at/play/30/)
#!/bin/bash
# Solution for 0xf.at level 30 (https://www.0xf.at/play/30/)
# solved in 49 minutes, 54 seconds
# This script expects the filename of the downloaded challenge image as its only parameter and will output the correct answer string.
# To prevent cheating, this version of the script has been modified in a few subtle ways so it will output an incorrect answer.
# Development process:
# - Use imagemagick to split input image into 40x40 px blocks
# - Print RGB representation of pixel (10, 10) in each block, along with block filenames
# - Sort list of (RGB, filename) tuples
# - Combine block files into output.png in the correct order
# - Try to download, process, and type the challenge image fast enough
# - Try again
# - And again
# - Notice that the blocks were being combined darkest-to-lighest, rather then lighest-to-darkest
# - Try manually typing the text *again* (and again, and again)
# - Notice that the input image occasionally contains block coloured rgb(0, 255, 0), which Imagemagick prints as 'lime'
# - Try newocr.com, notice that it can't distinguish between 1 and I
# - Accept the fact that one will need some kind of simplistic automated character recognition
# - ... like calculating the MD5 hashes of the image blocks (after converting them to monochrome) and creating a lookup table
# - Manually create said lookup table and an ugly sed-based lookup (replace) method
# - Notice that PNG files contain their creation date, and therefore have a different MD5 hash each time they're generated
# - Switch to PGM (Portable GreyMap) files, which don't contain any changing metadata
# - Shove the new hashes into the old lookup table (Vim to the rescue, as usual)
# - Test-run the script, add some not-so-clean output clean-up (i.e. get the output string into a single line without spaces)
# - Run it on the then-current challenge image
# - Succeed
# - Rejoice
rm -f image_*.png
convert "$1" -crop 40x40 +repage image_%d.png
(for i in {0..28}
do
convert image_$i.png -threshold 80% image_${i}_bw.pgm
echo -e "$(convert image_$i.png -format "%[pixel:s.p{10,10}]" info:)\t$(md5sum image_${i}_bw.pgm)"
done) | sed 's/lime/srgb(0,255,0)/' | sort -r | \
sed 's/befe753bba07b321059916f967556faf/</' | \
sed 's/84bce60583a14834dec4f23ff2c26368/>/' | \
sed 's/62a777ccc1f2eedd13e017d44d7a5072/:/' | \
sed 's/ee02aa72354589a97943c1aff44cc5cb/1/' | \
sed 's/dd3f162df20def8f4a7009a406327bd0/2/' | \
sed 's/d264df58a57645b5b71488612396b364/3/' | \
sed 's/04b4000d8d10b4557494483fd52a2306/4/' | \
sed 's/fc78ba23de4a0596da4a728f620eabf6/5/' | \
sed 's/95869c666478b05b565be8ecbb4cbf5e/6/' | \
sed 's/001e397718e12f02123807f531e4a65d/7/' | \
sed 's/33495198cba55733b1460b71ac53ddc7/8/' | \
sed 's/d9c9909cb32546d781e3310428c2de0b/9/' | \
sed 's/be0aaed8b2bad91b153f6611fea98a6c/B/' | \
sed 's/a24d965c423451a1a35dc8faccc47904/C/' | \
sed 's/235b9fb0c3c2c9f6bdb8fbf3a5e7beb4/D/' | \
sed 's/4a8c6d719ee4760d90b648e1aa7c96ce/E/' | \
sed 's/83b7e5a887470a3934c1248ce7db63f0/F/' | \
sed 's/c81ee9ec1b430b5bc55683e4557aa926/G/' | \
sed 's/eadf470736515f18a5b6c061708774d1/H/' | \
sed 's/3bab0bc2a4d57f0a3bcf6b9cbf1424cc/I/' | \
sed 's/c978df6610ea7bc842b476cc4b97cd90/J/' | \
sed 's/48794b8ef2ecbd62828cfac0ac7c364e/K/' | \
sed 's/2f922b0f62a13c70ac3cc79923aa3067/L/' | \
sed 's/2498c45a1457d0d1157e5210f5140f35/N/' | \
sed 's/0a468ac2b50bc326276cfdd7424c40a1/P/' | \
sed 's/26add7a2f6ca6ad73f383bcc2bb38657/R/' | \
sed 's/c189b38c05fe32604383c9239760974b/T/' | \
sed 's/745dea68226c89b92f91eb4c01249752/U/' | \
sed 's/82fa6dbedcab77402c5f27d795c7d53c/V/' | \
sed 's/8ba473b25fd868fb4659c9a946d9f3bb/X/' | \
awk '{print $2}' | xargs | tr -d ' '
rm -f "$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment