Skip to content

Chaos; Child 汉化补丁 神秘编码探索

Published: at 17:47

今天闲来无事,群里245哥提到 CCLCC 的汉化出了,遂去贴吧寻找资源。资源没找到,但却发现了 CC 汉化补丁中留下的解密游戏Misc题于是浪费了一个下午的时间来摸这个(错乱)

补丁的下载链接是 https://pan.baidu.com/s/1c389nt2,待解密的内容是补丁中的 txtchscode.zip

ToC

Zip

txtchscode.zip 中有 code.jpgdata.jpg 两个文件,对二者分别进行 binwalk 又可以得到两个隐藏的 zip。这里命名为 code.zipdata.zip

code.zip 解压可以得到两个 Java 文件,对 data.zip 解压则可以得到如下文所示的文本:

待解密文本

1
22010202222012110122201
2
222502263029340278002984
3
31067065058056053032033020

data.zip 中给出的 data 是一个由三行数字构成的文本。

加密程序

code.java 中一共有两个文件,一个是主文件,另一个并没有太大意义,因此省略。

1
package chaoschild;
2
import java.io.BufferedReader;
3
import java.io.BufferedWriter;
4
import java.io.File;
5
import java.io.FileReader;
6
import java.io.FileWriter;
7
import java.io.IOException;
8
import java.text.ParseException;
9
import java.util.Scanner;
10
11
public class ChaosChild {
12
13
14
/**
15
*
16
* @param linkedList
17
* @param fileName
18
* @author 天光逸
19
*/
20
//read the file by line
21
public static void readFileByLines(ChaosChild linkedList, String fileName) {
22
String key = null;
23
String password = null;
24
String link=null;
25
File file = new File(fileName);
26
BufferedReader reader = null;
27
try {
28
reader = new BufferedReader(new FileReader(file));
29
String tempString = null;
30
int line = 0;
31
// Read one line for one time until it reads null for the end of the file
32
while ((tempString = reader.readLine()) != null) {// to find if it reads to the end of the file
33
line = line % 3;
34
switch (line) {
35
case 0:
36
key = tempString;
37
break;
38
case 1:
39
password = tempString;
40
break;
41
case 2:
42
link = tempString;
43
44
Node node = new Node(key, password, link);
45
linkedList.addNode(node);
46
break;
47
48
}
49
line++;
50
}
51
reader.close();
52
} catch (IOException e) {
53
}
54
}
55
56
private Node head = null;// Head Node
57
private Node tail = null;// Tail node(null node) as Temporary nodes which used for substitution
58
//find key
59
public static Node findlink(String link, ChaosChild myList) {
60
Node tmp = null;
61
for (tmp = myList.getHead(); tmp != null; tmp = tmp.next) {
62
if (link.equals(tmp.link))
63
return tmp;
64
}
65
return tmp;
66
}
67
68
/**
69
*
70
* initial a linked list(set head)
71
* @param node
72
*/
73
public void initList(Node node) {
74
head = node;
75
head.next = tail;
76
}
77
78
/**
79
*
80
* add node
81
* @param node
82
*/
83
//sort all cars by purchase date
84
public void addNode(Node node) {
85
Node temp = head;
86
if (head == null) {
87
initList(node);
88
} else {// Replace head node
89
node.next = head;
90
head = node;
91
92
}
93
}
94
95
/**
96
*
97
* Traverse the list and delete node
98
* @param node
99
* @param myList
100
*/
101
public void deleteNode(Node node, ChaosChild myList) {
102
if (myList == null) {
103
return;
104
}
105
Node tmp = null;
106
for (tmp = myList.head; tmp != null; tmp = tmp.next) {
107
if (tmp.next != null && node.getlink().equals(tmp.next.getlink())) {
108
if (tmp.next.next != null) {
109
tmp.next = tmp.next.next;
110
} else {
111
tmp.next = null;
112
}
113
}
114
}
115
}
116
117
public Node getHead() {
118
return head;
119
}
120
121
/**
122
*
123
*
124
* @param myList
125
*/
126
127
/**
128
*
129
* @param args
130
* @throws java.text.ParseException
131
* @throws java.io.IOException
132
*/
133
//Achieve the four main funtions and save the file to data.txt
134
public static void main(String[] args) throws ParseException, IOException {
135
String filename="C:\\Users\\lenovo\\Desktop\\data.txt";
136
ChaosChild linkedList = new ChaosChild();
137
readFileByLines(linkedList, filename);
138
System.out.println("Welcome to this game. My name is MK0034209038. Please remember you have known my name.");
139
while (true) {
140
System.out.print("Please enter one of those :(input 1 2 3 4)\n1、Input data\n2、Display the data\n3、Hint \n4、Exit\n");
141
Scanner scanner = new Scanner(System.in);
142
int i = scanner.nextInt();
143
if (i == 1) {
144
145
146
System.out.println("You are not administrator");
147
// Scanner scanner = new Scanner(System.in);
148
149
150
151
152
} else if (i == 2) {
153
printlist(linkedList);
154
} else if (i == 3) {
155
System.out.println("Where is made by Morse code and please check the picture again.");
156
System.out.println("For more hints please enter 3 again");
157
int b = scanner.nextInt();
158
if(b == 3){
159
System.out.println("Well, the next hint is my name is made by 3 kinds of code");
160
}else{
161
System.out.println("OK,think about what the hell are those numbers meaning");
162
}
163
164
} else if (i == 4) {
165
BufferedWriter out;
166
try {
167
out = new BufferedWriter(new FileWriter(filename));
168
Node tmp = null;
169
long sum = 0;
170
for (tmp = linkedList.getHead(); tmp != null; tmp = tmp.next) {
171
out.write(tmp.key);
172
out.newLine();
173
out.write(String.valueOf(tmp.password));
174
out.newLine();
175
out.write(String.valueOf(tmp.link));
176
out.newLine();
177
178
}
179
180
out.close();
181
} catch (IOException e) {
182
}
183
return;
184
}
185
}
186
}
187
public static void printlist(ChaosChild myList) {
188
Node tmp = null;
189
long sum = 0;
190
for (tmp = myList.getHead(); tmp != null; tmp = tmp.next) {
191
192
System.out.print("Where:"+tmp.key + " " +"password:" +tmp.password + " " + "link:"+tmp.link + "\n");
193
194
}
195
196
197
}
198
}

简单观察程序,data 中的三行对应分别是 keypasswordlink。其中 key 又被称作 where

Hint

1
Where is made by Morse code and please check the picture again.
2
3
Well, the next hint is my name is made by 3 kinds of code
4
5
OK,think about what the hell are those numbers meaning

提示告诉我们,Where 是由 Morse 电码表示的,并且 Name 是由三种编码构成。

Where

code 的图片告诉我们 2=00=。因此需要将 2 替换为 00 替换为空,再经过 Morse 解码得到结果为 ITEHYBT

Link

Link 的文本是 31067065058056053032033020,看上去就很像 Hex 的文本每两个被看上去就很像空格的 0 隔开。依然遵循先前的 0= 规则:

解码得到结果 1geXVS23,看上去就很像百度网盘的样子,加上 https://pan.baidu.com/s/ 前缀,果然是:

Hint 2

https://tieba.baidu.com/p/4983552973
https://tieba.baidu.com/p/4983552973

根据贴吧的讨论,NameMK0034209038 是由作者的名字 天光逸 经过三种不同的编码方式转换而来。

Name

Name 编码后的文本为 MK0034209038,原文为 天光逸。这里需要沿用 0= 的规则,将 Name 分为三部分:MK03429038

之前我四个一组分成了 MK0034209038,结果发现并非如此(

Part 3

最好解的就是这第三部分。这部分的文本是 9038,对应的是 \u9038

Part 1

下一个攻克的是第一部分。根据仓颉键盘描述,M 代表K 代表,合起来就是天字。

根据这个原理解码 WhereITEHYBT 文本,发现 ITE 代表,但 HYBT 打不出来,倒是 HEBT 能打出字来。

Part 2

这部分的内容是 0342,是中文电码编码后的字。

http://chinesecommercialcode.net/search/index/cn
http://chinesecommercialcode.net/search/index/cn

Password

有了上文 Part2 的解码方法,对 Password 字段进行解码。

Password 的文本是 222502263029340278002984,初步经过 0= 划分后得到五组:

1
2225
2
2263
3
2934
4
2780
5
2984

再应用 2=0,得到:

1
0005
2
0063
3
0934
4
0780
5
0984

再查询中文电码,得到字符:

1
0005 = 三
2
0063 = 五
3
0934 = 四
4
0780 = 唉
5
0984 = 坩

等待,坩是什么?

Hint3

Password(终)

尝试不变换 29842,查询 2984,得到汉字。于是最终的 Password 文本就是:

1
0005 = 三
2
0063 = 五
3
0934 = 四
4
0780 = 唉
5
2984 = 死

将其读出后作为提取码输入,得到:

游戏结束ww

结语

宫代

「……!」

我呆在原地,言语尽失。

在这明媚的阳光下,在跑过去用不上数秒的地方。

——『她』就站在那里。

尾上

「…………」

毫无疑问,那正是我以为今生不会再次相见的她。

她用一副不知是该笑、是该哭、还是该生气……看似很迷茫的表情,一直在注视着我。

还有一个没见过的年纪相仿的女孩子站在她的身旁。

为什么……?

宫代

(为什么,会在这里……?)

我无法移开目光,也无法挪动半步。

我们明明近在咫尺,却又隔着无法逾越的距离,只能注视着对方。

宫代

「…………」

就算在听见警察提醒我『必须快点走了』的声音后,我也未能对此作答。

回过神来时,我已握紧了双拳。

少女

「世莉架……?」

尾上

「诶? 怎么了?」

听到了她那让我心生怜爱的声音。

轻风,承载着她的声音吹拂而来。

少女

「一下子这是怎么了? 那是谁?认识的人吗?」

尾上

「…………」

宫代

「…………」

在我和她之间回荡着的是什么样的情感,连我自己也不是很清楚。

只是——她那熟悉的双瞳中所浮现的泪水,清晰地烙印在了我的双目中。

尾上

「——不。是不认识的人」

接着,无声的泪水便洒落而下。

她——在笑着。

身旁的女孩子大概是她的挚友吧,为了不让那名女孩子察觉——她擦拭了眼泪,露出了笑容。

宫代

「…………」

她转过身,背对着我走去。

停止的时间又再次流动,我的脸上也浮现出了笑容。

宫代

「嗯……我也不认识你……」

阳光刺痛了双眼。

我抬头仰望着天空。

为了不让偷偷渗出的泪水落下。

这是开心的泪水。

我相信是这样。也必须这样相信。

——所有的一切,全部,这样就好。

宫代

「对不起,我们走吧」

我向警察这样说道,迈出了脚步。

已经看不见,『她』那远去的身影了。

今生不会再见……。

我们会在绝无交汇的路上走下去……。

——我们就这样,一起走完,彼此的人生

Chaos; Child TE,文本版权归科学社及相关译者所有。