Jetbrains Quest第二彈第三彈解法

上篇文章我介紹了Jetbrains20週年贈送的福利,3個月全家桶的使用權。雖然需要一定的解密,但是整個解密非常有趣。解密之後,還有另外兩次解密,我順便也給大家介紹一下。


第二彈解密


首先看看推特代碼。

Jetbrains Quest第二彈第三彈解法

仔細觀察可以發現,這就是字符串逆序而已。所以解密就很簡單。

<code>fun twitterCode2() {
val twitterCode =
".spleh A+lrtC/dmC .thgis fo tuo si ti semitemos ,etihw si txet nehw sa drah kooL .tseretni wohs dluohs uoy ecalp a si ,dessecorp si xat hctuD erehw esac ehT .sedih tseuq fo txen eht erehw si ,deificeps era segaugnal cificeps-niamod tcudorp ehT"
println(twitterCode.reversed())
}/<code>

解密之後得到的密文如下。

The product domain-specific languages are specified, is where the next of quest hides. The case where Dutch tax is processed, is a place you should show interest. Look hard as when text is white, sometimes it is out of sight. Cmd/Ctrl+A helps.

這段密文指的就是Jetbrains的另一款創建領域特定語言的工具MPS,經過尋找可以在MPS的文檔頁面找到關於荷蘭稅收的例子。

Jetbrains Quest第二彈第三彈解法

點擊之後,發現文章中什麼都沒有,這時候注意到提示裡讓我們使用全選來尋找白色的隱藏文字。操作之後發現右邊確實隱藏了文字。

Jetbrains Quest第二彈第三彈解法

複製出來之後得到結果。這段密文提示我們到Jetbrains20週年年報中尋找信息,分享關於18650這個數字的章節即可獲得信息。

This is our 20th year as a company,
we have shared numbers in our JetBrains
Annual report, sharing the section with
18,650 numbers will progress your quest

在年報裡尋找相關數字的信息,可能翻遍整個頁面都找不到。其實這個18650是如下章節的所有數字之和。點擊這裡的分享即可獲得下一個提示。

Jetbrains Quest第二彈第三彈解法

這個提示很簡單,直接給了我們一個網頁,並讓我們注意Haskell編寫的HelloWorld。

Jetbrains Quest第二彈第三彈解法

翻一下網頁即可看到這張圖片,密文就是圖中的黑板報上的字符。這裡我尋找的一直不確定是不是,因為手動將圖中的字符寫下來簡直太麻煩了。其實網頁裡源代碼已經明確給出了密文的字符串,因此毫無疑問就是它了。

Jetbrains Quest第二彈第三彈解法

以下就是密文了,這次不是什麼加密的密碼了。仔細觀察可以發現下面的密文很多字符就是用相近的字符做了替換,可以簡單看做英文版的火星文。

d1D j00 kN0w J378r41n2 12 4lW4Y2 H1R1N9? ch3CK 0u7 73h K4r33r2 P493 4nD 533 1f 7H3r3 12 4 J08 F0r J00 0R 4 KW357 cH4LL3n93 70 90 fUr7h3r @ l3457.

正確的密文如下,這次指引我們去Jetbrains的招工頁面尋找線索。

Did you know Jetbrains is always hiring? Check our ten careers page and see if there is a job for you or a quest challenge to go further at least.

在招工頁面裡有很多職位,在其中還真找到了一個Quester。

Jetbrains Quest第二彈第三彈解法

點擊看看這個職位的要求,可以看到這個用人要求非常有趣,要我們明白Konami遊戲的作弊指令。

Jetbrains Quest第二彈第三彈解法

這次在按著提示訪問Jetbrains的遊戲開發頁面,輸入經典的遊戲作弊碼上上下下左右左右BA,即可看到彈出了一個遊戲框,完成遊戲即可獲得兌換碼PlayGames,兌換可得3個月Jetbrains全家桶或者6個月的IDEA。

Jetbrains Quest第二彈第三彈解法

第三彈解密

好了,來看看最後一組解密吧。這次的推特代碼不太一樣,是沒有任何規律的字符串。之前我研究過某個軟件的分享配置功能,它用的是base64加密配置文件的方式,這次的字符串看著也挺像base64的編碼。

Jetbrains Quest第二彈第三彈解法

試一試看看能不能解出有意義的字符串,果然成功了。

<code>fun twitterCode3() { 

val sss = "SGF2ZSB5b3Ugc2VlbiB0aGUgcG9zdCBvbiBvdXIgSW5zdGFncmFtIGFjY291bnQ/"
println(Base64.getDecoder().decode(sss).map { it.toChar() }.joinToString(separator = ""))
}/<code>

解出來的內容如下。

Have you seen the post on our Instagram account?

這次要我們去Instagram看看,那我們就去看看吧。果然有一幅圖片,圖片旁邊的備註要我們去看看另外一個網頁。

Jetbrains Quest第二彈第三彈解法

這次是一個Kotlin編碼,如果你解過第一個謎題的話,應該可以很容易的發現n是3,就算不知道也可以很輕鬆的編碼嘗試出來。

<code>fun tryDecrypt() {
val tryFunc = fun(n: Int) {
val s =
"Zh#kdyh#ehhq#zrunlqj#552:#rq#wkh#ylghr#iru#wkh#iluvw#hslvrgh#ri#wkh#SksVwrup#HDS1#Li#zh#jdyh#|rx#d#foxh/#lw#zrxog#eh#hdv|#dv#sl1"
for (c in s) {
print(c - n)
}
println()
}
(1..3).forEach { tryFunc(it) }
}/<code>

這次解出來的密文如下。

We have been working 22/7 on the video for the first episode of the PhpStorm EAP. If we gave you a clue, it would be easy as pi.

大意是說我們在PhpStorm EAP的視頻里弄了點東西,你們去看看,提示是圓周率π。谷歌一下,找到了這個YouTube上的視頻,這是2月份發的一個PhpStorm介紹視頻。在視頻3分14秒的時候,有一秒鐘左右的時間閃出了另外一個地址。

Jetbrains Quest第二彈第三彈解法

訪問該地址,發現這是一個答題頁面,需要我們回答正確5道題,答案就在前面的Jetbrains20週年年報裡,重點關注以下信息即可。

  • 創始人圖片
  • Jetbrains僱員數目
  • Jetbrains主要工作國家
  • 接受額外基金支持
  • 最新推出的Jetbrains產品
  • 增長最快的國家和地區

回答正確就會看到下面的提示,告訴我們在某個Jetbrains IDEA社區版的每日提示中隱藏了信息,但是版本號並不清除。想知道版本號需要解開第二段的謎題。

Jetbrains Quest第二彈第三彈解法

這個第二段是寫的不明不白的一段英文,我在谷歌翻譯裡對照著看了半天也沒搞清楚。但是注意到每個單詞的首字母都是大寫的,嘗試把首字母連接起來,然後分一下詞,發現這是一段話。

.Net day call for speakers blog post image hides the next clue.

跟隨著線索,谷歌搜索一下關鍵詞,發現這是Jetbrains .NET的一篇博客,標題是Call for speakers,其中的圖片暗藏玄機,查看網頁源代碼即可發現隱藏信息。

Jetbrains Quest第二彈第三彈解法

現在知道了版本號,就可以訪問Confluence查找這個版本的IDEA軟件了。不過其實也不用專門查找,因為Jetbrains Quests熱度的關係,這個版本號已經被頂到第一位了。

Jetbrains Quest第二彈第三彈解法

下載安裝軟件,查看每日提示即可看到最後一個謎題。這次要我們想辦法獲得斐波那契數列的第五千萬項的前4位和最後4位數字。

JETBRAINS QUEST: LAST PUZZLE
You have discovered our JetBrains Quest! If you don’t know what this is, you should start from the beginning.
This is it. The last puzzle. You are just one step away from glory!
Now you just need the Key to unlock the Quest page.


The Key is the first and last 4 digits of the 50 * 10^6 position of the Fibonacci sequence (F(50 Million)).
As you may know by now, not all that glitters is gold, and to solve this puzzle you should not go straight for the obvious answer. May you make a glorious choice.
Remember that you have until the 15th of March 12:00 CEST.

這個問題可以說是相當有難度,沒有高深數學知識是完全無法做出來的,因為不論是常規的遞歸還是循環,還是保存了計算結果的遞歸,都無法得出這個結果。因為這項的數量級是10的一千萬次方,就算保存成文本也足足有10兆大小。所以偷懶的同學可以使用Wolfram Alpha搜索fib(5e7)以及fib(5e0)mod10000來獲取結果。


如果硬要計算的話也不是沒辦法,需要利用一種優化過的斐波那契數列解法,計算的時候是平方下降的,極大的降低了計算難度。在我的電腦上,這個算法僅需35秒就可以得到結果。

<code>// https://www.maplesoft.com/applications/download.aspx?SF=154362/fibonaccinumbers.pdf
// duplication formula
// f(2n) = f(n)^2 + 2f(n-1)f(n)
// f(2n-1)= f(n)^2 + f(n-1)^2
fun fibonacci2(n: Int, cache: HashMap): BigInteger {
if (n <= 1) {
return BigInteger.valueOf(n.toLong())
}

return if (n % 2 == 0) {
val b = cache.getOrPut(n / 2, { fibonacci2(n / 2, cache) })
val a = cache.getOrPut(n / 2 - 1, { fibonacci2(n / 2 - 1, cache) })
b * b + BigInteger.TWO * b * a
} else {
val b = cache.getOrPut((n + 1) / 2, { fibonacci2((n + 1) / 2, cache) })
val a = cache.getOrPut((n - 1) / 2, { fibonacci2((n - 1) / 2, cache) })
a * a + b * b
}


}
fun main() {
val profile = fun(task: () -> Unit) {
val t1 = LocalDateTime.now()
task()
val t2 = LocalDateTime.now()
println(Duration.between(t1, t2))
}
val c = HashMap()
val n = 5e7.toInt()
//profile { println(fibonacci1(n)) }
profile { println(fibonacci2(n, c)) }
}
/<code>

最終結果的前4位是4602,最後4位是3125,所以最終結果是46023125,這就是本次謎題的答案。利用它可以獲得Jetbrains全家桶的八折優惠券,可以說是很良心了。


分享到:


相關文章: