SHELTER ZONE | Coder 語言認證

Difficulty: 簡單

https://github.com/SHELTER-ZONE/Coder_Cert

Question

不久之前,邪惡的綠茶大魔王將城堡裡一間刻有藍黃蛇形紋的殿堂鎖起來了。 而殿堂的門上有10道鎖,貝利的好朋友——善良小兔和小貓發現這些鎖是有一定規律的。 端詳之際,貝利看見門下有10組若隱若現的數字,他們覺得這些數字是解開鎖的線索,便轉身向守衛求助。 年老的烏龜守衛印證了貝利的猜想,它幫助貝利推算出了鎖的邏輯,並將它們寫在一張紙上。它告訴貝利,在這10個鎖中,只有前5個鎖會在給錯密鑰時發出紅色的光芒,而後5個則不會有任何動靜。 拿著老守衛給他的紙,貝利鑽研了幾天後仍束手無策,你能幫助他進入大殿嗎?

Description

老守衛給出的代碼中寫入了所有鎖的資料與內部方法,而你只需要幫助貝利找出每個鎖的解鎖密鑰就好。 LockSolver這個類別當中存有開鎖的內部邏輯,你必須將LockSolver實例化之後才能使用。 你需要寫出一個solve函數,用於計算鎖的解鎖密鑰。run方法與solve函數的關係就好比鎖頭與鑰匙,把solve函數傳入run方法之後,run方法將會使用solve函數來計算出每個鎖的密鑰,前5組鎖會有錯誤提示。 當你確認十組密鑰都沒錯的時候,將伺服器的創立日期20180627(請使用字串型態)傳入getPassword方法並呼叫,它將會回傳一組最終密鑰,得到該密鑰後去【已刪除頻道】驗證你的答案。

為了能找出每個鎖的解鎖密鑰,你必須依照下面的邏輯撰寫solve函數:

  1. 將token的每個數字相加後,記錄結果。

  2. 將token的第一個數字與倒數第二個數字相加後,記錄結果。

  3. 呼叫encrypt方法,傳入整數形態的原始token後,記錄得到的結果。

  4. 將以上(1,2,3)步驟得到的結果全部相加之後,這將會是你的答案。

  5. 如果第4步驟得出的答案超過674361,你必須將它減上78763。

  6. 以字串型態回傳運算出的結果。

執行LockSolver的run方法,傳入你完成的solve函數,沒有出現錯誤提示之後再使用getPassword方法就能得到最終密鑰了。(記得先將LockSolver實例化)

Input Format

The first line is a string of digit, where the minimum length is 2.

Constraints

10N1019,N is the string10 \le N \le 10^{19}, \text{N is the string}

Output Format

Output an encrypted string which will be tested on Coder Verification Zone.

Sample Inputs:

Input

12345

Output

5815565c5494add6ce0031333edd55aa049f9306

Explanation

路過的勇者示範了解開一個鎖的過程,他的token為12345

  1. 1+2+3+4+5 = 15

  2. 1+4 = 5

  3. 呼叫encrypt傳入12345,回傳值2333

  4. 15+5+2333 = 2353

  5. 由於2353小於674361,答案保持不變

  6. 回傳字串型態的2353


Starter Code Template (Python)
Python.Cert.py
from pickle import loads
from base64 import b64decode
from hashlib import sha1
from gzip import decompress
from typing import Callable

data = decompress(b64decode((
    b'H4sIACMDel4C/yVSuY4VMRB8sNyniIkQyUpIqC/38RMvntT27GQEDgiR+HRqhmRatqurq6rn'
    b'78OfdXvcvtxuN0oOYXNJYcI31rPtEfcHTW56dO0sxZYtuLdm80l9DG2TtMWYZOv59g3wNGpq'
    b'AQpKCXVLisbuimqcTuvhop29/IlZQ3XuxxxiTkXytAvlHIfNpi5z7+vF9h1wttbY2CPJnINU'
    b'IQSK3aU83ZR9vfyvt5V4Lxrae8kx2m419tRRpHvyaBI9Du7r1fYScOeiXK+vVtaBBKggZ/Ix'
    b'5hjdZU/xUht0tBmxl1asN5cmIVFqCYepnmdtzllBDgzOorneXsTJPI9KRAVEhXibSfsRIYEH'
    b'hHVIbzCx3m1fTx0tnLVAk+hEmkjRriBjvb9fEGvmyMAT7o0RHiBhxNRqfbhvP055FiTYAngJ'
    b'wZUmtkeFmwZGb0RlhT1F2vp4336drBhzMiEERbpwEKnG4EAf+AtFIOpalgqSQwMFVMg5Ri3L'
    b'UsUN/uucgSPsYgjazz5mh3D8Qq3p+nS/NiDUqNbn+++f/wAo+U3jjgIAAA==')))


def checkType(targetType: object, obj: object) -> object:
    if not isinstance(obj, targetType):
        raise TypeError(f'Expected type {targetType} for {repr(obj)}"')
    return obj
    
class LockSolver():
    def __init__(self):
        global data
        self.tcdict = loads(data)
        self.testans = []
        self.func = None

    def run(self, function: Callable) -> None:
        checkType(Callable, function)
        sampletc = function('12345')
        if checkType(str, sampletc) != '2353':
            raise ValueError(
                f'Your function returned {repr(sampletc)} for token "12345".')

        self.func = function
        for i, tc in enumerate(self.tcdict.keys()):
            res = function(tc[1::2])
            if self.tcdict[tc] is not None and \
                (sha1(res.encode('utf-8')).hexdigest() !=
                 self.tcdict[tc][::-1]):
                raise RuntimeError(f"Failed to open lock #{i+1}, "
                                   "your solution is probably wrong.")
            self.testans.append(res)

    def getPassword(self, uid: str) -> str:
        ans = ''.join(self.testans) + self.func(checkType(str, uid))
        return sha1(ans.encode('utf-8')).hexdigest()


def encrypt(number: int) -> int: return checkType(int, number) >> 23 ^ 2333


# user code space
def solve(token: str) -> str:
    pass # Write your solutions here
Solution

基本上就是照著步驟走而已,不難。

參考答案如下:

# user code space
def solve(token: str) -> str:
    padcode1 = sum(int(c) for c in token)          # 第一條件
    padcode2 = int(token[0]) + int(token[-2])      # 第二條件
    padcode3 = encrypt(int(token))                 # 第三條件
    verify = padcode1 + padcode2 + padcode3        # 第四條件
    if verify > 674361:                            # 第五條件
        verify -= 78763
    return str(verify)                             # 輸出

solver = LockSolver()
solver.run(solve)
print(solver.getPassword("20180627"))

Last updated