R30 異世界網站挑戰-簡短紀錄

留個紀錄。

簡述

首先這遊戲是來自:r3:0 異世界網站挑戰

這篇不是攻略文,只是單純把我卡特別久的關卡做紀錄。如果想看詳細的攻略文直接 Google 遊戲名稱就會看到一大堆了。

關卡五

https://r30challenge.herokuapp.com/lv5.php?token=csspersona!

這關其實我早就用 devtool > network 發現 https://r30challenge.herokuapp.com/js/lv5.js 裡面寫著:

1
window.location='./lv6.php?token=fail';

就是因為執行了這一行才被轉址。

讓我卡很久的地方是我想不到怎麼阻止 JS 做壞事,看完攻略文後才知道原來是在轉址前就 ESC 來阻止,有夠殘念…

關卡十

https://r30challenge.herokuapp.com/lv10.php?token=EFEFABMN

這一關就是把這個 function 解出來:

1
2
3
4
5
6
7
8
9
10
11
12
function isTokenValid($token) {
if (strlen($token) !== 8) return false;
for($i = 1; $i <= 7; $i+=2) {
if ((
ord($token[$i]) *
ord($token[$i - 1])
) % $i !== 0) {
return false;
}
}
return true;
}

if (strlen($token) !== 8) return false;

意思是 token 是長度為 8 的字串。

至於迴圈的部分可以先照著寫,這樣就比較好分析邏輯了:

1
2
3
4
5
6
7
8
# 第一圈
char[0] * char[1] % 1 === 0
# 第二圈
char[2] * char[3] % 3 === 0
# 第三圈
char[4] * char[5] % 5 === 0
# 第四圈
char[6] * char[7] % 7 === 0

所以這邊能看出是找出相乘結果是 1, 3, 5, 7 倍數的兩個數字

知道邏輯後 function 就不難寫了:

備註:因為 0 ~ 32 的 ASCII 是系統字元,所以這邊不考慮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function findCommonMultiple(n) {
let collection = [];
// 從 33 ~ 126 找出倍數
for (let i=34; i<=126; i++) {
// 前一個數字 x 目前數字求餘數
if ((i-1) * i % n === 0) {
// 是倍數就轉成字元 push 到陣列裡
collection.push([String.fromCharCode(i-1), String.fromCharCode(i)]);
}
}
// 所有符合的字串
return collection;
}
// 儲存結果
const total = []
// 分別找出 1, 3, 5, 7 的倍數
for (let i=1; i<=7; i+=2) {
total.push(findCommonMultiple(i));
}
// 印出結果
console.log(total);

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
[
// 1 的倍數
[
[ '!', '"' ], [ '"', '#' ], [ '#', '$' ], [ '$', '%' ], [ '%', '&' ],
[ '&', "'" ], [ "'", '(' ], [ '(', ')' ], [ ')', '*' ], [ '*', '+' ],
[ '+', ',' ], [ ',', '-' ], [ '-', '.' ], [ '.', '/' ], [ '/', '0' ],
[ '0', '1' ], [ '1', '2' ], [ '2', '3' ], [ '3', '4' ], [ '4', '5' ],
[ '5', '6' ], [ '6', '7' ], [ '7', '8' ], [ '8', '9' ], [ '9', ':' ],
[ ':', ';' ], [ ';', '<' ], [ '<', '=' ], [ '=', '>' ], [ '>', '?' ],
[ '?', '@' ], [ '@', 'A' ], [ 'A', 'B' ], [ 'B', 'C' ], [ 'C', 'D' ],
[ 'D', 'E' ], [ 'E', 'F' ], [ 'F', 'G' ], [ 'G', 'H' ], [ 'H', 'I' ],
[ 'I', 'J' ], [ 'J', 'K' ], [ 'K', 'L' ], [ 'L', 'M' ], [ 'M', 'N' ],
[ 'N', 'O' ], [ 'O', 'P' ], [ 'P', 'Q' ], [ 'Q', 'R' ], [ 'R', 'S' ],
[ 'S', 'T' ], [ 'T', 'U' ], [ 'U', 'V' ], [ 'V', 'W' ], [ 'W', 'X' ],
[ 'X', 'Y' ], [ 'Y', 'Z' ], [ 'Z', '[' ], [ '[', '\\' ], [ '\\', ']' ],
[ ']', '^' ], [ '^', '_' ], [ '_', '`' ], [ '`', 'a' ], [ 'a', 'b' ],
[ 'b', 'c' ], [ 'c', 'd' ], [ 'd', 'e' ], [ 'e', 'f' ], [ 'f', 'g' ],
[ 'g', 'h' ], [ 'h', 'i' ], [ 'i', 'j' ], [ 'j', 'k' ], [ 'k', 'l' ],
[ 'l', 'm' ], [ 'm', 'n' ], [ 'n', 'o' ], [ 'o', 'p' ], [ 'p', 'q' ],
[ 'q', 'r' ], [ 'r', 's' ], [ 's', 't' ], [ 't', 'u' ], [ 'u', 'v' ],
[ 'v', 'w' ], [ 'w', 'x' ], [ 'x', 'y' ], [ 'y', 'z' ], [ 'z', '{' ],
[ '{', '|' ], [ '|', '}' ], [ '}', '~' ]
],
// 3 的倍數
[
[ '!', '"' ], [ '#', '$' ], [ '$', '%' ], [ '&', "'" ],
[ "'", '(' ], [ ')', '*' ], [ '*', '+' ], [ ',', '-' ],
[ '-', '.' ], [ '/', '0' ], [ '0', '1' ], [ '2', '3' ],
[ '3', '4' ], [ '5', '6' ], [ '6', '7' ], [ '8', '9' ],
[ '9', ':' ], [ ';', '<' ], [ '<', '=' ], [ '>', '?' ],
[ '?', '@' ], [ 'A', 'B' ], [ 'B', 'C' ], [ 'D', 'E' ],
[ 'E', 'F' ], [ 'G', 'H' ], [ 'H', 'I' ], [ 'J', 'K' ],
[ 'K', 'L' ], [ 'M', 'N' ], [ 'N', 'O' ], [ 'P', 'Q' ],
[ 'Q', 'R' ], [ 'S', 'T' ], [ 'T', 'U' ], [ 'V', 'W' ],
[ 'W', 'X' ], [ 'Y', 'Z' ], [ 'Z', '[' ], [ '\\', ']' ],
[ ']', '^' ], [ '_', '`' ], [ '`', 'a' ], [ 'b', 'c' ],
[ 'c', 'd' ], [ 'e', 'f' ], [ 'f', 'g' ], [ 'h', 'i' ],
[ 'i', 'j' ], [ 'k', 'l' ], [ 'l', 'm' ], [ 'n', 'o' ],
[ 'o', 'p' ], [ 'q', 'r' ], [ 'r', 's' ], [ 't', 'u' ],
[ 'u', 'v' ], [ 'w', 'x' ], [ 'x', 'y' ], [ 'z', '{' ],
[ '{', '|' ], [ '}', '~' ]
],
// 5 的倍數
[
[ '"', '#' ], [ '#', '$' ], [ "'", '(' ],
[ '(', ')' ], [ ',', '-' ], [ '-', '.' ],
[ '1', '2' ], [ '2', '3' ], [ '6', '7' ],
[ '7', '8' ], [ ';', '<' ], [ '<', '=' ],
[ '@', 'A' ], [ 'A', 'B' ], [ 'E', 'F' ],
[ 'F', 'G' ], [ 'J', 'K' ], [ 'K', 'L' ],
[ 'O', 'P' ], [ 'P', 'Q' ], [ 'T', 'U' ],
[ 'U', 'V' ], [ 'Y', 'Z' ], [ 'Z', '[' ],
[ '^', '_' ], [ '_', '`' ], [ 'c', 'd' ],
[ 'd', 'e' ], [ 'h', 'i' ], [ 'i', 'j' ],
[ 'm', 'n' ], [ 'n', 'o' ], [ 'r', 's' ],
[ 's', 't' ], [ 'w', 'x' ], [ 'x', 'y' ],
[ '|', '}' ], [ '}', '~' ]
],
// 7 的倍數
[
[ '"', '#' ], [ '#', '$' ],
[ ')', '*' ], [ '*', '+' ],
[ '0', '1' ], [ '1', '2' ],
[ '7', '8' ], [ '8', '9' ],
[ '>', '?' ], [ '?', '@' ],
[ 'E', 'F' ], [ 'F', 'G' ],
[ 'L', 'M' ], [ 'M', 'N' ],
[ 'S', 'T' ], [ 'T', 'U' ],
[ 'Z', '[' ], [ '[', '\\' ],
[ 'a', 'b' ], [ 'b', 'c' ],
[ 'h', 'i' ], [ 'i', 'j' ],
[ 'o', 'p' ], [ 'p', 'q' ],
[ 'v', 'w' ], [ 'w', 'x' ],
[ '}', '~' ]
]
]

備註:這邊建議挑英文數字的組合比較不會出錯。

接著兩兩湊對就是答案了,例如:EFEFABMN

關卡十四

https://r30challenge.herokuapp.com/lv14.php?token=5371

這一題要猜四位數字(0000~9999),所以我一開始就暴力解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 這段只能在 Node.js 上跑
const request = require('request');
~async function() {
for (let i=0; i<10000; i++) {
let query = i;
if (query < 10) {
// 0001 ~ 0009
query = '000' + query;
} else if (query < 100) {
// 0010 ~ 0099
query = '00' + query;
} else if (query < 1000) {
// 0100 ~ 0999
query = '0' + query;
}
// 顯示目前猜的數字
console.log(query);
await new Promise((resolve) => {
request(`https://r30challenge.herokuapp.com/lv14.php?token=${query}`
, (err, res, body) => {
console.log(body);
resolve();
})
})
}
}()

這裡用 Promise 來處理非同步的問題,看不懂話可以參考 Promise 的小技巧

不過這個 response 的回傳時間明顯怪怪的,像出現 1 3 5 7 的時候會特別慢。所以一樣查了攻略,發現原來是 幾 A 幾 B 猜數字 的小遊戲。話說回來我還真的沒有玩過這種猜數字遊戲 (´-ω-`)

所以這題的正確解法應該是先找出所有對的數字,在排成對的順序。

關卡十五

https://r30challenge.herokuapp.com/lv15.php?token=ssGAAAAA

這一題要把這個 function 解出來:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function isTokenValid($token) {
// 幾點
$h = date('H');
// 幾分
$m = date('i');
// 幾點 * 幾分 + 42
$a = $h * $m + 42;
// 儲存 token 轉成 ASCII 後的總和
$count = 0;
// 從 0~7,代表 token 是 8 個字
for($i = 0; $i < 8; $i++) {
// 轉成 ASCII 後要在減 65
$count += ord($token[$i]) - 65;
}
// 當 $a <= 100 的時這題就無解
if ($count <= 100) {
return false;
}
// token 的總和要是 $a 的因數
return $a % $count === 0;
}

這題我想不出暴力解的解法,所以我是用最笨的方法來解:

  1. 先算出下一次 $a 的值(比較不用趕時間)
  2. 找出 $a 的所有因數
  3. 查 ASCII 表湊出因數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 找出下一次的 $a
function getCode () {
$h = date('H');
$m = date('i') + 1;
$a = $h * $m + 42;
return $a;
}
// 找因數
function getFactors($n) {
$result = '';
for($i=101; $i<=$n; $i++) {
if ($n % $i === 0) {
$result .= ' ' . $i;
}
}
return $result;
}
// 計算 token 的總和
function getCount($token) {
$count = 0;
for($i = 0; $i < 8; $i++) {
$count += ord($token[$i]) - 65;
}
return $count;
}

function getASCII() {
for ($i=65; $i<=90; $i++) {
echo chr($i) . '=' . $i-65 . '<br>';
}

echo '<hr>';

for ($i=97; $i<=122; $i++) {
echo chr($i) . '=' . $i-65 . '<br>';
}

}
// 下一次的 A
$nextA = getCode();
echo '下一次的 $a = ' .
date('H') .
' x ' .
date('i') + 1 .
' + ' .
'42' .
' = ' .
$nextA . '<br>';
echo '所有 $a 的因數:' . getFactors($nextA) . '<br>';
echo 'token 的 ASCII 總和:' . getCount('sssBAAAA') . '<br>';
echo '是不是正確的 token:';
var_dump(isTokenValid('sssBAAAA'));
echo '<hr>';
getASCII();
echo '<hr>';
echo date('H-i');

下面只是為了讓 output 比較好讀才寫那一長串:

output

總之,就是查到對為止就破關了。

mentor-program-day60 mentor-program-day59
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×