最近,Jetbrains没事搞事,搞了一个解谜活动,成功解答出谜题的同学可以获得三个月Jetbrains全家桶的正版使用权。就算没有这个奖励,光是这个解谜过程就非常有意思,所以我就来给大家介绍一下。当然其实我也是看别人的文章介绍之后才发现有这个活动的,光凭我自己肯定是解不出来的,所以在此给出原作者的博客链接,这是一位外国小哥。
线索一:推特神秘代码
早在3月9日,Jetbrains推特上就发了一条神秘代码,当然不是我们开车的那个神秘代码,它是一串不规律字符。
如果你对反汇编之类的技术有所了解,或者你查看过某些软件的原始代码,又或者你注意力惊奇,发现这些代码里仅有数字以及A-F字母,应该就会明白这是十六进制的数字。当然其实早就有人发现了,并将答案写在了这条推特下面。不过我觉得既然是解Jetbrains的谜,自然应该使用Jetbrains推出的语言Kotlin。下面就是将神秘代码转换成字符串的Kotlin代码。
fun clueOne(): String {
val twitterCode =
"48 61 76 65 20 79 6f 75 20 73 65 65 6e 20 74 68 65 20 73 6f 75 72 63 65 20 63 6f 64 65 20 6f 66 20 74 68 65 20 4a 65 74 42 72 61 69 6e 73 20 77 65 62 73 69 74 65 3f"
return twitterCode.split(' ')
.map { ch -> ch.toInt(16).toChar() }
.joinToString(separator = "")
}
// 翻译过来就是:Have you seen the source code of the JetBrains website?
翻译过来恰好就是一段英文语句,你看过Jetbrains的网站源代码吗?
线索二:Jetbrains官网源代码
浏览器打开Jetbrains官网,右键点击查看网站源代码。幸运的是,Jetbrains网站没有使用什么压缩技术,网站源代码格式化显示,可以很轻松的查看网站代码。在400行左右,我还真找到了相关信息。
文字大意就是欢迎来解开这些谜题,这些谜题不仅需要一定的思维能力,而且需要利用各种Jetbrains产品完成解谜。可见这些谜题不仅是为了给大家发福利,最重要的是顺便推广一下自家产品。很有趣的一点就是Jetbrains还允许适当的作弊,可以说是非常贴心了。
最后一段话提醒了我们下一个谜题隐藏在Jetbrains的产品页面里,而且顺带提醒我们拿好钥匙(Key既是钥匙也是激活码的意思)。这里要注意密码Good luck! == Jrrg#oxfn$
,他可以说是整个解谜的关键所在。
线索三:官网神秘工具
下面到Jetbrains产品页面看一下有什么神秘东西,如果你对Jetbrains的各项产品比较熟悉的话,应该很容易就可以发现多了一个奇怪的东西。没错,这个JK是干什么的?
点开看看,发现了一条新提示。它给了我们一个网页地址,地址最后缺失了最后3个数字,答案就是下面的问题,500-5000之前有多少个素数?
这当然难不倒我们这些程序员,照例使用Kotlin计算一下问题答案。说实话这里花了我不少时间,代码倒是很简单,但是Kotlin语法和标准库我很久没用了,忘得一干二净,花了一些时间重新学习了一下, 然后用筛法实现了素数计数程序。
fun countPrimes(lowerBound: Int, upperBound: Int): Int {
// 假设下标就是数本身,元素代表是否是素数
val numbers = Array<Boolean>(upperBound + 1) { true }
numbers[0] = false
numbers[1] = false
for (i in 2..(sqrt(upperBound.toDouble()).toInt() + 1)) {
if (numbers[i]) {
for (j in i * i..upperBound step i) {
numbers[j] = false
}
}
}
return numbers.copyOfRange(lowerBound, upperBound)
.count { it }
}
然后就可以得到500-5000之前有多少个素数了,程序运行结果是574。
线索四:神秘网页
用574替换掉三个井号,就可以得到新的网址了,访问可知这是PyCharm的在线帮助网站。注意网页上有一个图片,是一张台球桌,上面有一张打印了神秘代码的纸。
这个产品的图标相信很多同学不会陌生,这是Jetbrains旗下一款issue收集工具YouTrack的图标。而神秘代码就是某个issue的代号。所以我们访问Jetbrains的官方YouTrack网站看看这个issue到底说了啥。这里其实很简单,谷歌这串代码即可,强大的谷歌会直接给出我们这个issue的地址。
访问地址发现这个网页又给了一串神秘密码,提示很简单:回想一下刚开始的密码。说实话这里如果让我解得话我肯定解不出来,看到这个密码样式我可能会尝试使用BASE64之类的去解谜,然后就进了死胡同。但是有了先行者的提示,其实也不是很难。
关键就在前面的钥匙里。注意这个钥匙看起来就是一个编程判断语句,==
就是等于号,那么是不是说前后两串字符是相等的呢?
Good luck! == Jrrg#oxfn$
如何判断字符相等呢?我们首先想到的自然是判断其字符的ASCII码是否相等,所以自然而然,需要写个函数测试一下两个字符串的码。果然,两个字符串值相差了3,也就是说这是一个简单的位移密码。解密方法就是将密文向左移动三格。如果比较博学的同学应该听说过这种密码,古代罗马的统治者凯撒就使用过这种密码,虽然现在这种简单密码已经被淘汰了,但是作为游戏来说的话刚刚好,毕竟解谜方法弄得太难没人解出来那就尴尬了。
fun printStringValue() {
val string1 = "Good luck!"
val string2 = "Jrrg#oxfn\$"
println(string1.map { it.toInt().toString() }.joinToString(separator = " "))
println(string2.map { it.toInt().toString() }.joinToString(separator = " "))
}
// 71 111 111 100 32 108 117 99 107 33
// 74 114 114 103 35 111 120 102 110 36
好了,已经确认了解密方法,可以对密文进行解密了。在这里再次吹一波Kotlin语言,lambda写起来是真的爽,比Java、Python之流舒服多了。
fun decryptCipher() {
val sss =
"Qlfh\$#Li#|rx#duh#uhdglqj#wklv#|rx#pxvw#kdyh#zrunhg#rxw#krz#wr#ghfu|sw#lw1#Wklv#lv#rxu#lvvxh#wudfnhu#ghvljqhg#iru#djloh#whdpv1#Lw#lv#iuhh#iru#xs#wr#6#xvhuv#lq#Forxg#dqg#iru#43#xvhuv#lq#Vwdqgdorqh/#vr#li#|rx#zdqw#wr#jlyh#lw#d#jr#lq#|rxu#whdp#wkhq#zh#wrwdoo|#uhfrpphqg#lw1#|rx#kdyh#ilqlvkhg#wkh#iluvw#Txhvw/#qrz#lw“v#wlph#wr#uhghhp#|rxu#iluvw#sul}h1#Wkh#frgh#iru#wkh#iluvw#txhvw#lv#‟EhfdxvhFrgh†1#Jr#wr#wkh#Txhvw#Sdjh#dqg#xvh#wkh#frgh#wr#fodlp#|rxu#sul}h1#kwwsv=22zzz1mhweudlqv1frp2surpr2txhvw2"
val cipher = sss.map { (it.toShort() - 3).toChar() }.joinToString(separator = "")
println(cipher)
}
解密结果如下,奖励代码我已经去掉了,大家最好还是自己研究一下,享受一下解密的快感。
Nice! If you are reading this you must have worked out how to decrypt it. This is our issue tracker designed for agile teams. It is free for up to 3 users in Cloud and for 10 users in Standalone, so if you want to give it a go in your team then we totally recommend it. you have finished the first Quest, now it’s time to redeem your first prize. The code for the first quest is “XXXX”. Go to the Quest Page and use the code to claim your prize. https://www.jetbrains.com/pro...
兑换奖励
访问网页,输入奖励代码以及邮箱,Jetbrains就会将注册链接发送到你的邮箱中。然后遵循邮件里面的说明,即可兑换3个月的Jetbrains全家桶使用权。本次活动截止时间到明天位置,大家没领取的赶快领取吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。