火星文

This commit is contained in:
RubyOcelot
2020-11-05 13:53:39 +08:00
parent fe6234ce30
commit 09fc4003d2
3 changed files with 111 additions and 0 deletions
@@ -1 +1,56 @@
# 从零开始的火星文生活
出题&解题[源代码](./src/generate_and_solve.py)
## 思路
还原乱码。也许有人见过这张图:
![常见乱码](files/常见乱码.jpg)
如果是还原乱码小能手或者见过上面那张图就不用我多说了。如果没见过,那么 google 一下部分乱码内容(如 “脦脪鹿楼 乱码”)就能发现一些线索了。
## 过程
下载附件之后假如直接用 GBK 打开那就真的是题面里说的“夹杂着日语和数字的火星文”了,恭喜掉进坑,乱码又多了一层(逃
用 UTF-8 打开,看到形如“脦脪鹿楼”的文本,推断是上图中的“古文码”乱码。但是“古文码”明明是“以 GBK 方式读取 UTF-8 编码的中文”造成的,看来“脦脪鹿楼”本来应当是 GBK下看到的结果,却又被存成了 UTF-8。所以第一步是用 GBK 重新编码文本“脦脪鹿楼...”。
然后用 UTF-8 打开,看到形如“ÎÒ¹¥ÆÆÁË”的文本,推断是上图中的“拼音码”乱码。“拼音码”是“以 ISO8859-1 方式读取 GBK 编码的中文”,而现在文本的编码是 UTF-8。所以接下应当用 ISO8859-1 重新编码文本“ÎÒ¹¥ÆÆÁË...”。
然后用 GBK 打开,就能看到可读的汉字和 flag 了。不过这里的 flag 全部是从 ASCII 字符转成的全角字符,不能直接复制使用,可以手动替换成 ASCII 字符或者用其他简便方法变回 ASCII 字符即可。
[源代码](./src/generate_and_solve.py) 中也给出了一个全角->半角的函数。
## 实践
那么具体用什么手段来解题呢?
### 方法一(不写代码)
例如用 VSCode 的“Select Encoding”功能。
步骤(开始时 UTF-8 打开题目附件):
1. Save with Encoding -> GBK
1. Reopen with Encoding -> UTF-8
1. Save with Encoding -> ISO8859-1
1. Reopen with Encoding -> GBK
(听说 Notepad++ 很方便,蹲一个其他人的 wp)
### 方法二 (写代码)
见 [源代码](./src/generate_and_solve.py) 中的 solve 函数。
```
def solve(message):
answer=DBC2SBC(message.encode("gbk").decode("UTF-8").encode("iso-8859-1").decode('gbk'))
return answer
```
## 为什么出这道题
TBC
没事别 GBK,全盘 UTF-8 不香吗:D
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,56 @@
#全角->半角
def DBC2SBC(input_string):
ret_string = ""
for uchar in input_string:
char_code = ord(uchar)
if char_code == 0x3000:
char_code = 0x0020
else:
char_code -= 0xfee0
if not (0x0021 <= char_code and char_code <= 0x7e):
ret_string += uchar
else:
ret_string += chr(char_code)
return ret_string
#半角->全角
def SBC2DBC(input_string):
ret_string = ""
for uchar in input_string:
char_code = ord(uchar)
if char_code == 0x0020:
char_code = 0x3000
if not (0x0021 <= char_code and char_code <= 0x7e):
ret_string += uchar
else:
char_code += 0xfee0
ret_string += chr(char_code)
return ret_string
def generate(message):
dec_message=SBC2DBC(message)
output=dec_message.encode('gbk').decode("iso-8859-1").encode('UTF-8').decode('gbk')
return output
def solve(message):
answer=DBC2SBC(message.encode("gbk").decode("UTF-8").encode("iso-8859-1").decode('gbk'))
return answer
target="""
我攻破了 Hackergame 的服务器,偷到了它们的 flag,现在我把 flag 发给你:
flag{H4v3_FuN_w1Th_3nc0d1ng_4Nd_d3c0D1nG_9qD2R8hs}
快去比赛平台提交吧!
不要再把这份信息转发给其他人了,要是被发现就糟糕了!
"""
fout=open("files/gibberish_message.txt","w",encoding="UTF-8",errors='replace')
fout.write(generate(target))
fout.close()
fin=open("files/gibberish_message.txt","r",encoding="UTF-8",errors='replace')
source=fin.read()
answer=solve(source)
assert(DBC2SBC(target)==answer)
print(answer)