前言
解密前
ZHOFRPH WR JUDYLWB IDOOV
解密后
WELCOME TO GRAVITY FALLS
小彩蛋 1
Kl! L dp Cxr Bdqj, d jxb zkr zulwhv frgh!
小彩蛋 2
FDHVDULDQ zloo eh uhsodfhg eb DWEDVK lq wkh qhaw eorj
最近左羊在看动漫《怪诞小镇》时惊奇地发现,在每集怪诞小镇的结尾,随机出现的一串数字或字母原来蕴含着神秘的密码。这些密码是通过各种不同的加密方式实现的,包括经典的凯撒密码、阿特巴希密码、A1Z26密码,以及复杂的维吉尼亚密码。
大家需要密切关注怪诞小镇每集片头,因为隐藏在那里的线索和提示将帮助你解开结局的神秘密码。特别是最后部分倒放可以听到的低语声,按照不同的加密方式变化,比如three letters back
是凯撒密码,switch A with Z
是阿特巴希密码,26 letters
是A1Z26密码,key Vigenère
是维吉尼亚密码。
怪诞小镇的不同集数中,采用了多种不同的加密方式来隐藏结局密码。具体来说,第1-6集使用的是凯撒密码,第7-13集使用阿特巴希密码,第14-19集使用A1Z26密码,第20集则采用了A1Z26、阿特巴希和凯撒三种密码的组合形式,而第21-40集则全程采用了复杂的维吉尼亚密码。
通过分析和解密这些密码,我们可以探究更多关于小镇和其中隐秘事件的秘密。由于每次加密的方法和密钥都不尽相同,解密的过程充满了挑战和乐趣。由于怪诞小镇部分剧集采用了相同的信息加密方式,所以在娱乐的同时左羊也想通过代码的方法解密重复的部分。下面左羊将通过多篇博客使用多种语言来实现怪诞小镇出现的各种加密方式。
talk is cheap ,show you the code~
简介
凯撒加密技术是一种古老的加密方法,也被称为凯撒密码,是一种单表替换密码。这种密码由古罗马将军凯撒所创造,可以将一段明文转换为暗文,实现信息保密的目的。它的原理是将明文中的每个字母按照一个固定的位数进行移位,从而实现加密的目的。
凯撒加密算法的实现非常简单,只需要使用一个整数作为密钥,然后对明文进行位移操作,即可得到密文。例如,将明文 "HELLO" 以密钥为 3 进行位移,则得到密文 "KHOOR"。
对照表
以下是使用凯撒密码以密钥为 3 进行位移加密解密时需要用到的字母对照表:
明文字母 | 密文字母 |
---|---|
A | D |
B | E |
C | F |
D | G |
E | H |
F | I |
G | J |
H | K |
I | L |
J | M |
K | N |
L | O |
M | P |
N | Q |
O | R |
P | S |
Q | T |
R | U |
S | V |
T | W |
U | X |
V | Y |
W | Z |
X | A |
Y | B |
Z | C |
Java代码实现
下面是使用 Java 实现凯撒加密算法的代码:
public class CaesarCipher {
// 加密函数
public static String encrypt(String message, int key) {
StringBuilder ciphertext = new StringBuilder();
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
if (Character.isLetter(c)) {
c = (char) ((c - 'A' + key) % 26 + 'A');
}
ciphertext.append(c);
}
return ciphertext.toString();
}
// 解密函数
public static String decrypt(String ciphertext, int key) {
return encrypt(ciphertext, 26 - key);
}
// 测试函数
public static void main(String[] args) {
String message = "HELLO";
int key = 3;
String ciphertext = encrypt(message, key);
String plaintext = decrypt(ciphertext, key);
System.out.println("明文:" + message);
System.out.println("密文:" + ciphertext);
System.out.println("解密后的明文:" + plaintext);
}
}
在上面的代码中,我们使用了两个函数 encrypt
和 decrypt
分别实现加密和解密操作。首先,我们需要将明文中的每个字母转换为大写字母,然后通过 isLetter
方法判断该字符是否是字母,然后使用公式 (c - 'A' + key) % 26 + 'A'
进行移位操作。其中,(c - 'A')
表示该字母在字母表中的位置,+ key
表示加上密钥进行移位,% 26
表示对 26 取模,最后再加上 'A'
得到移位后的字母。
解密函数与加密函数类似,只需要将加密函数中的 key
参数替换为 26 - key
即可。
shell语言实现
以下是使用shell语言实现凯撒密码加密和解密的代码示例:
#!/bin/bash
# 定义凯撒加密函数
function caesar_encrypt() {
local plaintext=$1
local shift=$2
local ciphertext=""
for ((i=0; i<${#plaintext}; i++)); do
char="${plaintext:$i:1}"
if [[ $char =~ [A-Z] ]]; then
ascii=$(( ( $(printf '%d' "'$char") - 65 + shift) % 26 + 65 ))
ciphertext+="$(printf "\\$(printf %o $ascii)")"
elif [[ $char =~ [a-z] ]]; then
ascii=$(( ( $(printf '%d' "'$char") - 97 + shift) % 26 + 97 ))
ciphertext+="$(printf "\\$(printf %o $ascii)")"
else
ciphertext+="$char"
fi
done
echo "$ciphertext"
}
# 定义凯撒解密函数
function caesar_decrypt() {
local ciphertext=$1
local shift=$2
local plaintext=""
for ((i=0; i<${#ciphertext}; i++)); do
char="${ciphertext:$i:1}"
if [[ $char =~ [A-Z] ]]; then
ascii=$(( ( $(printf '%d' "'$char") - 65 - shift + 26) % 26 + 65 ))
plaintext+="$(printf "\\$(printf %o $ascii)")"
elif [[ $char =~ [a-z] ]]; then
ascii=$(( ( $(printf '%d' "'$char") - 97 - shift + 26) % 26 + 97 ))
plaintext+="$(printf "\\$(printf %o $ascii)")"
else
plaintext+="$char"
fi
done
echo "$plaintext"
}
# 测试加密函数
plaintext="Hello, World!"
shift=3
ciphertext=$(caesar_encrypt "$plaintext" $shift)
echo "加密前: $plaintext"
echo "位移量: $shift"
echo "加密后: $ciphertext"
# 测试解密函数
shift=3
plaintext=$(caesar_decrypt "$ciphertext" $shift)
echo "解密前: $ciphertext"
echo "位移量: $shift"
echo "解密后: $plaintext"
使用方法:将上述代码保存为一个shell脚本文件,例如caesar_ciphertext.sh
,然后在终端中执行sh caesar_ciphertext.sh
即可运行脚本。脚本会将plaintext
变量中的明文使用凯撒密码加密,并输出加密后的密文。接着,再使用凯撒密码解密函数解密密文,输出解密后的明文。
Golang语言实现
以下是使用Golang语言实现凯撒密码加密和解密的代码示例:
package main
import (
"fmt"
)
// 定义凯撒加密函数
func caesarEncrypt(plaintext string, shift int) string {
ciphertext := ""
for _, char := range plaintext {
if char >= 'A' && char <= 'Z' {
ascii := ((int(char) - 'A' + shift) % 26) + 'A'
ciphertext += string(ascii)
} else if char >= 'a' && char <= 'z' {
ascii := ((int(char) - 'a' + shift) % 26) + 'a'
ciphertext += string(ascii)
} else {
ciphertext += string(char)
}
}
return ciphertext
}
// 定义凯撒解密函数
func caesarDecrypt(ciphertext string, shift int) string {
plaintext := ""
for _, char := range ciphertext {
if char >= 'A' && char <= 'Z' {
ascii := ((int(char) - 'A' - shift + 26) % 26) + 'A'
plaintext += string(ascii)
} else if char >= 'a' && char <= 'z' {
ascii := ((int(char) - 'a' - shift + 26) % 26) + 'a'
plaintext += string(ascii)
} else {
plaintext += string(char)
}
}
return plaintext
}
func main() {
// 测试加密函数
plaintext := "Hello, World!"
shift := 3
ciphertext := caesarEncrypt(plaintext, shift)
fmt.Printf("加密前: %s\n", plaintext)
fmt.Printf("位移量: %d\n", shift)
fmt.Printf("加密后: %s\n", ciphertext)
// 测试解密函数
plaintext = caesarDecrypt(ciphertext, shift)
fmt.Printf("解密前: %s\n", ciphertext)
fmt.Printf("位移量: %d\n", shift)
fmt.Printf("解密后: %s\n", plaintext)
}
使用方法:将上述代码保存为一个go文件,例如caesar_ciphertext.go
,然后在终端中执行go run caesar_ciphertext.go
即可运行代码。代码会将plaintext
变量中的明文使用凯撒密码加密,并输出加密后的密文。接着,再使用凯撒密码解密函数解密密文,输出解密后的明文。
Python语言实现
以下是使用Python语言实现凯撒密码加密和解密的代码示例:
# 定义凯撒加密函数
def caesarEncrypt(plaintext, shift):
ciphertext = ""
for char in plaintext:
if char.isalpha():
if char.isupper():
ascii = (((ord(char) - 65) + shift) % 26) + 65
ciphertext += chr(ascii)
else:
ascii = (((ord(char) - 97) + shift) % 26) + 97
ciphertext += chr(ascii)
else:
ciphertext += char
return ciphertext
# 定义凯撒解密函数
def caesarDecrypt(ciphertext, shift):
plaintext = ""
for char in ciphertext:
if char.isalpha():
if char.isupper():
ascii = (((ord(char) - 65) - shift + 26) % 26) + 65
plaintext += chr(ascii)
else:
ascii = (((ord(char) - 97) - shift + 26) % 26) + 97
plaintext += chr(ascii)
else:
plaintext += char
return plaintext
# 测试加密和解密函数
plaintext = "Hello, World!"
shift = 3
ciphertext = caesarEncrypt(plaintext, shift)
print("加密前: " + plaintext)
print("位移量: " + str(shift))
print("加密后: " + ciphertext)
plaintext = caesarDecrypt(ciphertext, shift)
print("解密前: " + ciphertext)
print("位移量: " + str(shift))
print("解密后: " + plaintext)
使用方法:将上述代码保存为一个py文件,例如caesar_ciphertext.py
,然后在终端中执行python3 caesar_ciphertext.py
即可运行代码。代码会将plaintext
变量中的明文使用凯撒密码加密,并输出加密后的密文。接着,再使用凯撒密码解密函数解密密文,输出解密后的明文。
JavaScript语言实现
以下是使用JavaScript语言实现凯撒密码加密和解密的代码示例,并附带一个使用HTML和CSS制作的加密解密页面:
HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Caesar Cipher</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="caesar_cipher.js"></script>
</head>
<body>
<div class="container">
<h1>Caesar Cipher</h1>
<h2>凯撒加密法</h2>
<div class="form-container">
<div class="form-group">
<label for="plaintext">明文:</label>
<input type="text" id="plaintext" placeholder="请输入需加密信息">
</div>
<div class="form-group">
<label for="shift">位移量:</label>
<input type="number" id="shift" min="1" max="25" value="3">
</div>
<div class="form-group">
<button onclick="encrypt()">Encrypt(加密)</button>
<button onclick="decrypt()">Decrypt(解密)</button>
</div>
<div class="form-group">
<label for="ciphertext">密文:</label>
<input type="text" id="ciphertext" placeholder="请输入需解密信息">
</div>
</div>
</div>
</body>
</html>
CSS代码:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.form-container {
display: flex;
flex-direction: column;
align-items: center;
}
.form-group {
margin-bottom: 10px;
}
label {
font-weight: bold;
}
input[type="text"], input[type="number"] {
padding: 5px;
border-radius: 5px;
border: none;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1);
font-size: 1em;
}
button {
padding: 5px 10px;
border-radius: 5px;
border: none;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1);
font-size: 1em;
margin-right: 10px;
}
button:hover {
background-color: #e1e1e1;
cursor: pointer;
}
JavaScript代码:
function caesarEncrypt(plaintext, shift) {
let ciphertext = "";
for (let i = 0; i < plaintext.length; i++) {
let char = plaintext.charAt(i);
if (char.match(/[a-z]/i)) {
let code = plaintext.charCodeAt(i);
if (code >= 65 && code <= 90) {
char = String.fromCharCode(((code - 65 + shift) % 26) + 65);
} else if (code >= 97 && code <= 122) {
char = String.fromCharCode(((code - 97 + shift) % 26) + 97);
}
}
ciphertext += char;
}
return ciphertext;
}
function caesarDecrypt(ciphertext, shift) {
let plaintext = "";
for (let i = 0; i < ciphertext.length; i++) {
let char = ciphertext.charAt(i);
if (char.match(/[a-z]/i)) {
let code = ciphertext.charCodeAt(i);
if (code >= 65 && code <= 90) {
char = String.fromCharCode(((code - 65 - shift + 26) % 26) + 65);
} else if (code >= 97 && code <= 122) {
char = String.fromCharCode(((code - 97 - shift + 26) % 26) + 97);
}
}
plaintext += char;
}
return plaintext;
}
function encrypt() {
let plaintext = document.getElementById("plaintext").value;
let shift = parseInt(document.getElementById("shift").value);
let ciphertext = caesarEncrypt(plaintext, shift);
document.getElementById("ciphertext").value = ciphertext;
}
function decrypt() {
let ciphertext = document.getElementById("ciphertext").value;
let shift = parseInt(document.getElementById("shift").value);
let plaintext = caesarDecrypt(ciphertext, shift);
document.getElementById("plaintext").value = plaintext;
}
使用方法:将上述HTML、CSS和JavaScript代码保存为三个文件,例如分别为index.html
、style.css
和caesar_cipher.js
。然后在浏览器中打开HTML文件即可看到加密解密页面。用户输入明文和位移量,点击加密按钮即可加密,点击解密按钮即可解密。
结语
虽然凯撒加密算法在古罗马时代就已经被使用,但它实际上并不安全。因为它只有 26 种可能的移位方式,非常容易被破解。现代密码学中使用的加密方法通常要比凯撒加密算法复杂得多。例如,常用的 AES 加密算法使用 128 位或 256 位的密钥。
参考文献
1. 《密码学基础》(原书名:Cryptography: Theory and Practice)作者:道格拉斯·斯汀斯(Douglas Stinson)
2. 百度百科 . 恺撒密码 . https://baike.baidu.com/item/%E6%81%BA%E6%92%92%E5%AF%86%E7%A0%81/4905284?fromtitle=%E5%87%AF%E6%92%92%E5%AF%86%E7%A0%81&fromid=1336345&fr=aladdin
3. 知乎 . 幻仔牛奶 . 怪诞小镇中都有哪些彩蛋和谜题 . https://www.zhihu.com/tardis/sogou/ans/92182104
4. 百度百科 . 怪诞小镇 . https://baike.baidu.com/item/%E6%80%AA%E8%AF%9E%E5%B0%8F%E9%95%87/8918232?fr=aladdin
5. BiliBili . 安迪视频 . 【怪诞小镇】#1第一集彩蛋,细节,密码与解析(初到重力泉镇) . https://www.bilibili.com/video/BV1VJ411w7vT/?spm_id_from=333.337.search-card.all.click&vd_source=ba50ab08f80d173365b7101b8b4e2379