trytodecrypt.com — middle (7-12)

posted
read
203 words · 1 min
contents

tryptodecrypt.com

字符集 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.,;:?! (71 个字符)。

Text 7

21052F151200271512413E35101A152F3511

固定 2-hex 替换表(步长 2)。

same script as easy level

Terminal window
❯ python decrypt_cipher.py 7 2
密文: 21052F151200271512413E35101A152F3511
******************

this was confusing

Text 8

eaidagdagenpmgodlceijmgoefodlceijcnllonmgodlcfilfgamgodnnflgfgafilmgofildihdagmgoefodlccnlcnledddagmgoedddagfobdagedd

3 字符一组的替换密码。

#!/usr/bin/env python3
import re
import subprocess
import sys
C = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.,;:?! "
def encrypt(text_id, text, cookie=""):
cmd = ["curl", "-s"]
if cookie:
cmd += ["-b", cookie]
cmd += [
f"https://www.trytodecrypt.com/decrypt.php?id={text_id}",
"-d",
f"text={text}&encrypt=Encrypt",
]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
# m = re.findall(r"panel-body[^>]>([0-9a-fA-F]+)</div>", r.stdout)
m = re.findall(r"panel-body[^>]*>([0-9a-zA-Z]+)</div>", r.stdout)
26 collapsed lines
return m[1] if len(m) >= 2 else None
def build_mapping(text_id, step, cookie=""):
mapping = {}
for i in range(0, len(C), 20): # 每次 20 字符,多数服务端限制 50
batch = C[i : i + 20]
enc = encrypt(text_id, batch, cookie)
if enc:
for j, ch in enumerate(batch):
mapping[enc[j * step : (j + 1) * step]] = ch
return mapping
def decode(ct, step, mapping):
return "".join(mapping.get(ct[i : i + step], "?") for i in range(0, len(ct), step))
if __name__ == "__main__":
if len(sys.argv) < 3:
print(f"用法: {sys.argv[0]} <text_id> <step>")
sys.exit(1)
text_id = int(sys.argv[1])
step = int(sys.argv[2])
ct = sys.stdin.read().strip() if not sys.stdin.isatty() else input("密文: ").strip()
mapping = build_mapping(text_id, step)
if not mapping:
print("ERROR: 映射表为空,检查 text_id / step / 网络连接")
sys.exit(1)
print(decode(ct, step, mapping))
Terminal window
❯ python decrypt_cipher_alpha.py 8 3
密文: eaidagdagenpmgodlceijmgoefodlceijcnllonmgodlcfilfgamgodnnflgfgafilmgofildihdagmgoefodlccnlcnledddagmgoedddagfobdagedd
***************************************

keep in mind: its just the middle level

Text 9

6224F12C1C3FAA5AA54836B3C446D6415E74

反转输入后,每字符映射到固定 3-hex 码。解码时反向操作。

#!/usr/bin/env python3
import re
import subprocess
import sys
C = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.,;:?! "
def encrypt(text_id, text, cookie=""):
cmd = ["curl", "-s"]
if cookie:
cmd += ["-b", cookie]
cmd += [
f"https://www.trytodecrypt.com/decrypt.php?id={text_id}",
"-d",
f"text={text}&encrypt=Encrypt",
]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
m = re.findall(r"panel-body[^>]*>([0-9a-zA-Z]+)</div>", r.stdout)
return m[1] if len(m) >= 2 else None
27 collapsed lines
def build_mapping(text_id, step, cookie=""):
mapping = {}
# 或者把加密块大小改成 1
for i in range(0, len(C), 20): # 每次 20 字符,多数服务端限制 50
batch = C[i : i + 20]
enc = encrypt(text_id, batch, cookie)
if enc:
for j, ch in enumerate(batch):
# mapping[enc[j * step : (j + 1) * step]] = ch
mapping[enc[-(j + 1) * step : len(enc) - j * step]] = ch
return mapping
def decode(ct, step, mapping):
return "".join(mapping.get(ct[i : i + step], "?") for i in range(0, len(ct), step))
if __name__ == "__main__":
if len(sys.argv) < 3:
print(f"用法: {sys.argv[0]} <text_id> <step>")
sys.exit(1)
text_id = int(sys.argv[1])
step = int(sys.argv[2])
ct = sys.stdin.read().strip() if not sys.stdin.isatty() else input("密文: ").strip()
mapping = build_mapping(text_id, step)
if not mapping:
print("ERROR: 映射表为空,检查 text_id / step / 网络连接")
sys.exit(1)
print(decode(ct, step, mapping))
Terminal window
❯ echo "6224F12C1C3FAA5AA54836B3C446D6415E74" | python trytodecrypt_cipher_reverse.py 9 3 | rev
************

fireball 123

Text 10

261129152E152B

7 -> 9 单表替换 每个字符固定映射到一个密文块,不依赖位置

10 -> 12 多表替换 映射关系随位置变化(Vigenère 风格)

步长 2,偏移量 [16, 17, 18] 循环。enc = charset_pos + offset[pos % 3]。

#!/usr/bin/env python3
"""trytodecrypt CPA solver — 基于网站加密工具建映射表解码
三种模式:
simple 固定映射(Text 1-8)
reverse 先反转再加密(Text 9)
vigenere 逐位置映射(Text 10-12)
derive 自动推导公式,少量请求解码(Text 10-12 推荐)
用法:
python trytodecrypt_solve.py <text_id> [options]
echo '密文' | python trytodecrypt_solve.py <text_id> [options]
选项:
-s, --step 步长(默认 auto)
-r, --reverse 反转模式(Text 9)
-v, --vigenere Vigenere 模式(逐位置建表,请求多)
-d, --derive 推导模式(少量请求算公式,Text 10-12 推荐)
-c, --cookie PHPSESSID
-q, --quiet 静默模式
180 collapsed lines
"""
import argparse
import re
import subprocess
import sys
import time
C = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.,;:?! "
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def encrypt(text_id, text, cookie="", retry=3):
for attempt in range(retry):
cmd = ["curl", "-s", "--max-time", "15", "--retry", "2"]
if cookie:
cmd += ["-b", cookie]
cmd += [
f"https://www.trytodecrypt.com/decrypt.php?id={text_id}",
"-d", f"text={text}&encrypt=Encrypt",
]
try:
r = subprocess.run(cmd, capture_output=True, text=True, timeout=20)
m = re.findall(r"panel-body[^>]*>([0-9a-zA-Z]+)</div>", r.stdout)
if len(m) >= 2:
return m[1]
except subprocess.TimeoutExpired:
pass
if attempt < retry - 1:
time.sleep(1)
return None
def detect_step(text_id, cookie=""):
for step in [2, 3, 4]:
enc = encrypt(text_id, "0" * 10, cookie)
if enc and len(enc) == step * 10:
return step
enc = encrypt(text_id, "0", cookie)
if enc:
return len(enc)
return 2
def build_mapping_simple(text_id, step, cookie="", batch=20, reverse=False):
mapping = {}
for i in range(0, len(C), batch):
plain = C[i:i + batch]
enc = encrypt(text_id, plain, cookie)
if not enc:
continue
groups = [enc[j * step:(j + 1) * step] for j in range(len(plain))]
if reverse:
groups.reverse()
for j, ch in enumerate(plain):
mapping[groups[j]] = ch
return mapping
def build_mapping_vigenere(text_id, step, ct_len, cookie="", quiet=False):
mapping = [{} for _ in range(ct_len)]
total = ct_len * len(C)
done = 0
t0 = time.time()
for pos in range(ct_len):
prefix = "0" * pos
for ch in C:
plain = prefix + ch
enc = encrypt(text_id, plain, cookie)
if enc:
key = enc[pos * step:(pos + 1) * step]
mapping[pos][key] = ch
done += 1
if not quiet and done % 50 == 0:
elapsed = time.time() - t0
eprint(f" [{done}/{total}] {done/total*100:.0f}% eta {elapsed/done*(total-done):.0f}s")
if not quiet:
eprint(f" [{total}/{total}] 100% ({time.time()-t0:.0f}s)")
return mapping
def derive_vigenere(text_id, step, ct_len, cookie=""):
"""推导公式模式:少量请求算出 key,直接解码"""
# 加密 "0"*n 获取每个位置的基值
enc_zeros = encrypt(text_id, "0" * ct_len, cookie)
if not enc_zeros:
return None
bases = [int(enc_zeros[p * step:(p + 1) * step], 16) for p in range(ct_len)]
# 加密 "1"*n 获取梯子
enc_ones = encrypt(text_id, "1" * ct_len, cookie)
if enc_ones:
steps = [int(enc_ones[p * step:(p + 1) * step], 16) - bases[p] for p in range(ct_len)]
else:
steps = [0] * ct_len
return bases, steps
def decode_with_key(ct, step, bases, steps):
"""用推导出的 key 解码"""
pt = ""
for i in range(len(ct) // step):
val = int(ct[i * step:(i + 1) * step], 16)
# enc = base + cp * step
if steps[i] != 0:
cp = round((val - bases[i]) / steps[i])
else:
cp = val - bases[i]
if 0 <= cp < len(C):
pt += C[cp]
else:
pt += "?"
return pt
def decode_simple(ct, step, mapping):
return "".join(mapping.get(ct[i:i + step], "?") for i in range(0, len(ct), step))
def decode_vigenere(ct, step, mapping):
return "".join(
mapping[i].get(ct[i * step:(i + 1) * step], "?")
for i in range(len(mapping))
)
def main():
ap = argparse.ArgumentParser(description="trytodecrypt CPA solver")
ap.add_argument("text_id", type=int, help="题目 ID")
ap.add_argument("-s", "--step", type=int, default=0, help="步长(默认 auto)")
ap.add_argument("-r", "--reverse", action="store_true", help="反转模式(Text 9)")
ap.add_argument("-v", "--vigenere", action="store_true", help="Vigenere 模式(逐位置建表)")
ap.add_argument("-d", "--derive", action="store_true", help="推导模式(少量请求算公式)")
ap.add_argument("-c", "--cookie", default="", help="PHPSESSID")
ap.add_argument("-q", "--quiet", action="store_true", help="静默模式")
ap.add_argument("--batch", type=int, default=20, help="每批字符数(默认 20,simple 专用)")
args = ap.parse_args()
ct = sys.stdin.read().strip() if not sys.stdin.isatty() else input("密文: ").strip()
if not ct:
eprint("ERROR: 未提供密文")
sys.exit(1)
step = args.step or detect_step(args.text_id, args.cookie)
if not args.quiet:
eprint(f"[*] 步长: {step}")
if args.derive:
ct_len = len(ct) // step
if not args.quiet:
eprint(f"[*] 推导模式: {ct_len} 个位置")
result = derive_vigenere(args.text_id, step, ct_len, args.cookie)
if result is None:
eprint("ERROR: 推导失败")
sys.exit(1)
bases, steps = result
if not args.quiet:
eprint(f"[*] bases: {bases}")
eprint(f"[*] steps: {steps}")
print(decode_with_key(ct, step, bases, steps))
elif args.vigenere:
ct_len = len(ct) // step
if not args.quiet:
eprint(f"[*] Vigenere: {ct_len} × {len(C)} = {ct_len * len(C)} 次请求")
mapping = build_mapping_vigenere(args.text_id, step, ct_len, args.cookie, args.quiet)
if not mapping[0]:
eprint("ERROR: 映射表为空")
sys.exit(1)
print(decode_vigenere(ct, step, mapping))
else:
mode = "reverse" if args.reverse else "simple"
if not args.quiet:
eprint(f"[*] 模式: {mode}")
mapping = build_mapping_simple(args.text_id, step, args.cookie, args.batch, args.reverse)
if not mapping:
eprint("ERROR: 映射表为空")
sys.exit(1)
print(decode_simple(ct, step, mapping))
if __name__ == "__main__":
main()
Terminal window
❯ python trytodecrypt_solve.py -v 10 -c "8rubc5nmtqala9gvdj8t7cigqn" -s 2 -d
密文: 261129152E152B
[*] 步长: 2
[*] 推导模式: 7 个位置
[*] bases: [16, 17, 18, 16, 17, 18, 16]
[*] steps: [1, 1, 1, 1, 1, 1, 1]
*******

m0n5t3r

Text 11

3785824AD56B2531A7150DF44C21434A61E63F040A42F2012BC2F43F0AD535D24D46013213866D7E0

步长 3 hex,6 位循环。基值 [168, 282, 567, 57, 245, 180],乘数 [12, 47, 21, 19, 35, 9]。

密文值=基值[位置]+字符位置×倍率[位置]\text{密文值} = \text{基值}[\text{位置}] + \text{字符位置} \times \text{倍率}[\text{位置}]

same as Text 10

Terminal window
❯ python trytodecrypt_solve.py -v 11 -c "8rubc5nmtqala9gvdj8t7cigqn" -s 3 -d
密文: 3785824AD56B2531A7150DF44C21434A61E63F040A42F2012BC2F43F0AD535D24D46013213866D7E0
[*] 步长: 3
[*] 推导模式: 27 个位置
[*] bases: [168, 282, 567, 57, 245, 180, 168, 282, 567, 57, 245, 180, 168, 282, 567, 57, 245, 180, 168, 282, 567, 57, 245, 180, 168, 282, 567]
[*] steps: [12, 47, 21, 19, 35, 9, 12, 47, 21, 19, 35, 9, 12, 47, 21, 19, 35, 9, 12, 47, 21, 19, 35, 9, 12, 47, 21]
***************************

You are very good. Respect!

Text 12

00D02703603C0450461340870A50B50EA10A0BD133

基值为三角数 T(pos+1)=(pos+1)(pos+2)2T(\mathrm{pos}+1) = \frac{(\mathrm{pos}+1)(\mathrm{pos}+2)}{2},步长 pos+22\frac{\mathrm{pos}+2}{2}。

C = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.,;:?! "
ct = "00D02703603C0450461340870A50B50EA10A0BD133"
vals = [int(ct[i*3:(i+1)*3], 16) for i in range(14)]
print("".join(C[round((v - (i+1)*(i+2)//2) / ((i+2)/2))] for i, v in enumerate(vals)))

cookie monster