Python/Python Challenge

[Python Challenge 30] 통신이상 오류있는가?

Python Challenge 30의 Url은 다음과 같다

Python challenge 30 : http://www.pythonchallenge.com/pc/ring/yankeedoodle.html


구성

문제 페이지에 들어가면 휴식이 있다. 아래 영어는 다음의 의미를 가지고 있다.

 

"이 그림은 오직 당신의 휴식을 위함"

 

(X치고 다음 문제로 보내주면 좋겠다. ) 주석을 한번 보도록 하자

주석은 csv(comma separated values)을 확인하라고 되어있다. yankeedoodle.csv를 다운로드 하자.

확인 결과는 다음과 같다. 

으흠; 어떤 자료인걸까.... 0~1 사이 소수 값들이다.


해결 아이디어

이미지 모드에 'F'모드라는 것이 있다.

https://ko.wikipedia.org/wiki/TIFF

 

TIFF - 위키백과, 우리 모두의 백과사전

TIFF 위키백과, 우리 모두의 백과사전.

ko.wikipedia.org

F 모드는 (32-bit floating point pixels) 그니까 32bit 정확도의 소수 값을 가지는 이미지 모드이다. 딱0~1 사이 값들을 보유하고, 우리 상황이랑 정확하게 틀어맞는다. 일단 Image의 가로세로를 확인하기 위해 w, h를 구하는 내포를 하나 만들고 이미지를 만들어 보자

### 30_1.py

import re
from PIL import Image

if __name__=="__main__" :
    with open("yankeedoodle.csv","r") as f:
        data = f.read()
        data = re.findall("\d[.]\d*",data)

    w,h = (x for x in range(2,len(data)//2) if len(data)%x==0)

    img = Image.new("F",(w,h))
    img.putdata([float(x) for x in data], 256)
    img.show()

 

* img.save("뭐. tiff")가 잘 안된다.

* putdata 2번째 파라미터는 비중치이다. 높으면 높을수록 선명해진다. 어차피 흑백이긴 하지만

 

다음과 같은 사진을 구할 수 있다.

응? 뭔가 Python 식 같은 표현이 나왔는데, 사진이 돌아가 있다. 조금 보기 편하게 돌려보자

### 30_2.py

import re
from PIL import Image

if __name__=="__main__" :
    with open("yankeedoodle.csv","r") as f:
        data = f.read()
        data = re.findall("\d[.]\d*",data)

    w,h = (x for x in range(2,len(data)//2) if len(data)%x==0)

    img = Image.new("F",(w,h))
    img.putdata([float(x) for x in data], 256)
    
    img = img.transpose(Image.FLIP_LEFT_RIGHT)
    img = img.transpose(Image.ROTATE_90)
    img.show()

다음과 같은 사진을 구할 수 있다.

일단 그렇다. 식은

n = str(x [i])[5] + str(x [i+1])[5] + str(x [i+2])[6]

 

이고, 식을 조금 해석해 보자면, 첫 번째, 두 번째, 세 번째의 offset5, offset5, offset6을 더한 값을 2ke2ke 해보라는 의미이다.

코드를 짜 보자

### 30_3.py

import re
from PIL import Image

if __name__=="__main__" :
    with open("yankeedoodle.csv","r") as f:
        data = f.read()
        data = re.findall("\d[.]\d*",data)

    first,second,third = data[0::3],data[1::3],data[2::3]

    ans = list()
  
    for d in zip(first,second,third) :
        ans.append(chr(int(d[0][5] + d[1][5] + d[2][6])))

    print(''.join(ans))

코드의 출력 결과는 다음과 같다.

So, you found the hidden message.
There is lots of room here for a long message, but we only need very little space to say 
"look at grandpa", so the rest is just garbage. 
VTZ.l'tf*Om@I"p]#R`cWEBZ40ofSC>OZFkRP0\)+b?Ir)S%Jt3f{ei%n2<FErFx~IzVm JTh =xdx++'de8C5'
|>2\/We;ib(b%d$N<2u(o$*d@.*6Fd'nW5#J!}a]T"1Q-7Y~bOF]T+^9d]e^J^=&I&<x|EEgdQ$$pX'f!_n>F0(
[j%Y'XjwWu,4w/q;1Hd#1H{{Nf~BQ6f![m#fb^a;{Ei%$2fEyN[*4KhK[-7({jh5k0n kwZyx|x=xvFC
....

 

"grandpa" 찾았다.

Answer Url : http://www.pythonchallenge.com/pc/ring/grandpa.html