这是一段机器翻译的文本,可能包含错误!
Om kryptografioppgavene
这些任务的结构与其他 Piggy 上的任务略有不同,想知道你们更喜欢哪种方式! 😎
首先会有一部分关于主题的信息,然后才会有一些任务!
此任务的“关卡”与之前的关卡略有不同,这里的内容更多地是按主题划分的。
什么是“Cipher”?
你有没有想过给朋友写一条秘密信息,让其他人无法理解? 那你就需要一个 Cipher,或者在挪威语中称为 chiffer! Cipher 仅仅是一种将普通文本转换为“代码”的方法,通过用其他字符替换字符(通常是字母)。 对于那些不知道代码如何工作的人来说,结果看起来像胡言乱语。 重点是只有那些知道密钥(替换字母的规则)的人才能再次使代码可理解。 换句话说:cipher 使秘密信息成为可能,无论是童年时期的秘密语言游戏,还是真正的间谍发送加密消息。 😄
Visste du?
事实上, “密码” 这个词实际上来源于一个阿拉伯语单词:sifr,意思是“零”。 也许是因为秘密代码在人们无法破解时看起来像什么都没有(零意义)!
存在许多类型的密码——有些使用数字,有些使用符号,而现代数据加密则使用非常复杂的算法。这些复杂的算法需要非常复杂的数学,所以我们可以先看一些更简单的算法!
单字母密码
让我们首先看看一些最简单(也是最古老)的密码方法:单字母密码。
单字母密码可能听起来像一个很难的词,但我们可以将其分解:mono 意思是“一”,而 alphabet 指的是字母表。
因此,单字母密码是指使用一个单一的“加密字母表”来加密整个消息的密码。也就是说,原始文本中的每个字母都会在整个加密消息中始终被替换为相同的字母。
例如,如果你已经决定将 A 替换为 X,那么文本中的所有 A 都会被替换为 X。
凯撒密码
经典的单字母替换密码的例子是凯撒密码(以尤利乌斯·凯撒命名)。 这基本上是一个规则,即在字母表中将所有字母移动一定数量的位置。 据说凯撒本人在他的秘密信息中使用了一个 3 个字母的移动。 它的工作方式是 A 变成 D,B 变成 E,C 变成 F,以此类推,直到字母表结束。(当超过 Z 时,从 A 重新开始。) 因此,如果使用凯撒的方法,消息 ABC 将变成 DEF。
凯撒密码的实际运作方式:
- 选择一个密钥:确定一个秘密数字(例如 3),该数字表示您要移动每个字母的位数。
- 替换每个字母:对于原始消息中的每个字母,在字母表中找到该字母之后那么多位置的字母(对于密钥 3,A 变为 D,B 变为 E,等等 - 请记住,如果需要,在 Z 之后回到 A)。您也可以包含 Æ、Ø 和 Å,但这会变得更复杂。
- 加密消息:替换字母并用“移位”的字母编写新消息。瞧——您就获得了一段难以阅读的秘密文本,只有拥有密钥的人才能理解!
- 要解密(即将其转换回可读文本),只需执行相反的移位即可。如果您知道密钥(例如 3),那么通过将字母在字母表中向后移动 3 位,读取消息就同样容易。
Sikkerhet?
这些代码从长远来看并不是特别安全。 因为模式(替换)是固定的,有耐心的人或一些巧妙的技巧很容易揭示秘密。 例如,凯撒密码只有几种可能的偏移量,就像字母表一样多,所以任何人都可以尝试所有偏移量,直到消息有意义——或者使用字母频率来猜测。 换句话说,也许不要用凯撒密码来记录超级秘密的日记或国家机密 😉。
单字母密码是一种学习加密原理的绝佳方式。它们简单易懂,展示了我们如何使用一条简单的规则(密钥)将可理解的文本转换为神秘且无法理解的内容——然后再转换回来。所以下次你想给朋友发送一条秘密消息时,可以使用凯撒密码!也许你们可以创建自己版本的凯撒秘密字母表? 🔐✨
任务
编程语言?
像之前一样,请随意使用您喜欢的任何编程语言!这里的示例将使用 Python。
任务 1.1 - 凯撒密码加密
现在我们实际上要编写一些代码了!我们将从简单地实现加密开始,基于理论,这应该相当简单明了。
通过使用一个函数来实现凯撒密码加密,该函数接收文本和一个数字作为“密钥”,即字母表应该旋转多少。
Tips til framgangsmåte.
- 创建一个名为
caesar的函数,该函数接收要加密的文本和“移位”作为输入,即文本在字母表中要移动的位数。 - 逐个遍历文本中的每个字母。
- 我们不想“移位”其他字符,只想移位字母:找出如何检查文本中的字符是否为字母。
- 我们需要将字母“旋转” n 位,这意味着我们需要 添加 旋转值:找出如何将文本转换为数字,以便可以添加移位值。 提示:
ord()函数。 - 记住! 你会根据是大写字母还是小写字母获得不同的值。参考 ASCII 表格。
- 在获得值之后,只需 添加 n 值即可。但是,如果在字母表的末尾会发生什么?在字母 Z 之后只会得到乱码。如何修复这个问题?这需要一些思考。
Fikse enkrypteringen.
For å fikse krypteringen helt krever litt tenking.
- 第一个步骤是考虑使用 模数 运算符
%。 - 由于字母表(英语)包含 26 个字母,我们可以对 26 取模。
- 但这并不完全有效,你明白原因吗?
- 尝试使用
print打印一个字符的ord()值,你会得到什么? - 对于
a,你会得到 97。如果用 26 取模,你会得到 19。记住 模数 总是会给出一个介于 0 和该数字之间的答案。 - 这可以通过存储大写和小写字母的起始值来修复,从字母中减去该值,然后取模。这将是:
(ord(bokstav) - ord('a')) % 26 - 要获得正确的字母,只需再次添加起始值即可。
- 在完成所有这些操作之后,你终于可以将数字转换回字母。你可以使用
chr()函数。 - 现在,你可以将字母添加到结果中并返回加密后的文本!
Løsning:
def caesar_cipher(text, shift):
result = ""
for char in text:
if char.isalpha():
# 找出基于大写和小写的起始点
start = ord('A') if char.isupper() else ord('a')
# 艰难的移位计算
result += chr((ord(char) - start + shift) % 26 + start)
else:
result += char
return result
任务 1.2 - 凯撒密码解密
解密只是对加密进行相反的计算。 你减去偏移量而不是添加它。
Tips til framgangsmåte.
使用你在任务 1 中创建的函数来完成此操作。只需使用相同的函数,但反向执行。你可以通过在 26 - shift 处进行移位来实现。
Løsning:
def caesar_decrypt(text, shift):
return caesar_cipher(text, 26 - shift)
解答:
def caesar_decrypt(text, shift):
return caesar_cipher(text, 26 - shift)
其他单字母密码/Ciphers (例如 Atbash)
还有其他的单字母密码!其中一个比较简单的叫做“Atbash”密码。
Atbash 如何运作?
这个非常简单,不是旋转,而是将字母映射到相反的字母表。以下是一个显示映射的表格:
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| z | y | x | w | v | u | t | s | r | q | p | o | n | m | l | k | j | i | h | g | f | e | d | c | b | a |
任务 1.3 - Atbash 密码加密和解密
Atbash 的优点在于,由于加密是一种 1 对 1 的转换,因此它可以直接反向使用。 也就是说,如果你创建了加密方法,那么你也自动创建了解密方法。
如何在实践中做到这一点?
您可以选择从 Z 中减去字母,或者创建一个“查找”表。也就是说,创建一个包含字母 a 到 z 以及它们应该变成什么样子的表格或字典。如果你们想创建另一种类型的加密,这可能是一个好的解决方案。
Lookup-table implementasjon.
letters = {
'a': 'z'
'b': 'y'
'c': 'x'
'd': 'w'
# ... 添加剩余字母向下
}
通过这个表格,你可以逐个字母地遍历,然后从查找表中提取每个字母对应的值,并将其输出。对于大写和小写字母,你需要做什么?
Del 2 - 单字母密码的密码分析
在这部分中,你们将尝试创建一个算法来“破解”凯撒密码,即接收加密文本,然后,在不知道密钥的情况下获得原始文本。
这*可以*手动完成,或者你可以尝试使用简单的“密码分析”。这是一个我们稍后将深入研究的概念,但现在我们只关注最简单的方法之一:频率分析 (frequency analysis)。 你可以在这里阅读更多关于这个概念的信息:Frequency Analysis 或者这里 Wikipedia - frequency analysis。
这种方法不仅可以用于凯撒密码,还可以用于更复杂的算法,但凯撒密码非常简单,以至于频率分析是*微不足道的*。
频率分析是如何运作的?
频率分析,顾名思义,是一种检查文本中字母频率的方法。 为什么这可能有用? 想象一下,你有一段很长的文本,我们假设这是一段英文文本,来自 Wikipedia - frequency analysis:
In cryptanalysis, frequency analysis is the study of the frequency of letters or groups of letters in a ciphertext. The method is used as an aid to breaking classical ciphers.
Frequency analysis is based on the fact that, in any given stretch of written language, certain letters and combinations of letters occur with varying frequencies. Moreover, there is a characteristic distribution of letters that is roughly the same for almost all samples of that language. For instance, given a section of English language, E, T, A and O are the most common, while Z, Q, X and J are rare. Likewise, TH, ER, ON, and AN are the most common pairs of letters termed bigrams or digraphs), and SS, EE, TT, and FF are the most common repeats. The nonsense phrase ETAOIN SHRDLU represents the 12 most frequent letters in typical English language text.
In some ciphers, such properties of the natural language plaintext are preserved in the ciphertext, and these patterns have the potential to be exploited in a ciphertext-only attack.
如果我们将这段文本用凯撒密码进行转换(同时移除逗号、空格和其他特殊字符),我们将得到以下密文:
xcrgneipcpanhxhugtfjtcrnpcpanhxhxhiwthijsnduiwtugtfjtcrnduatiitghdgvgdjehduatiitghxcprxewtgitmiiwtbtiwdsxhjhtsphpcpxsidqgtpzxcvraphhxrparxewtghugtfjtcrnpcpanhxhxhqphtsdciwtupriiwpixcpcnvxktchigtirwdulgxiitcapcvjpvtrtgipxcatiitghpcsrdbqxcpixdchduatiitghdrrjglxiwkpgnxcvugtfjtcrxthbdgtdktgiwtgtxhprwpgpritgxhixrsxhigxqjixdcduatiitghiwpixhgdjvwaniwthpbtudgpabdhipaahpbeathduiwpiapcvjpvtudgxchipcrtvxktcphtrixdcdutcvaxhwapcvjpvttippcsdpgtiwtbdhirdbbdclwxatofmpcsypgtgpgtaxztlxhtiwtgdcpcspcpgtiwtbdhirdbbdcepxghduatiitghitgbtsqxvgpbhdgsxvgpewhpcshhttiipcsuupgtiwtbdhirdbbdcgtetpihiwtcdchtchtewgphttipdxchwgsajgtegthtcihiwtbdhiugtfjtciatiitghxcinexrpatcvaxhwapcvjpvtitmixchdbtrxewtghhjrwegdetgixthduiwtcpijgpaapcvjpvteapxcitmipgtegthtgktsxciwtrxewtgitmipcsiwthtepiitgchwpktiwteditcixpaidqttmeadxitsxcprxewtgitmidcanpiiprz
这段文本看起来 不可能 被破解,但借助“频率分析”,这不仅可行,而且 简单。
这张图显示了英语字母的分布。我们可以看到,字母 E 是最常见的字母,其次是 T、A 和 O。
这可以转换为表格,然后用于统计和 分析 给定的密文,从而“破解”它。在下面的任务中,你将创建一个程序,可以自行“破解”凯撒密码。诚然,凯撒密码很简单,你可以手动检查所有 26 种可能性,但在这里我们将自动找到解决方案。
任务 2.1 - 创建频率表
在一个 Python 文件中,创建英语字母的频率表。你可以尝试自己找到它,但如果你不想这样做,我们也理解!
如果你绝对想自己找到它,你可以像在任务 2.2 中那样做,但处理一个非常大的文本。
English Letter Frequency (Svaret)
english_letter_frequency = {
'E': 12.70,
'T': 9.06,
'A': 8.17,
'O': 7.51,
'I': 6.97,
'N': 6.75,
'S': 6.33,
'H': 6.09,
'R': 5.99,
'D': 4.25,
'L': 4.03,
'C': 2.78,
'U': 2.76,
'M': 2.41,
'W': 2.36,
'F': 2.23,
'G': 2.02,
'Y': 1.97,
'P': 1.93,
'B': 1.29,
'V': 0.98,
'K': 0.77,
'J': 0.15,
'X': 0.15,
'Q': 0.10,
'Z': 0.07
}
任务 2.2 - 统计文本中字母的频率
现在我们将创建一个算法来查找给定文本中字母的频率。
Tips til framgangsmåte
- 首先从一个接收文本的函数开始(可以是任何内容)。
- 在函数中,创建一个“字典”(Python Dictionaries),其中包含字母表中的每个字母的条目,设置为
0。 ({'A' = 0, 'B' = 0, 'C' = 0, ..., 'Z' = 0}) - 遍历整个文本并计算每个字母(在字典中相应的条目中增加 1)。您可能需要忽略非字母字符,并记住大小写。
- 跟踪已计算的字母总数。
- 完成计数后,将表中的每个值除以
/文本的长度,然后乘以 100,这将为您提供百分比频率。(或者,您可以让您的表保持在 0 到 1 之间)。 - 现在您应该有一个文本的频率表。
任务 2.3 - 将文本的频率与真实频率进行比较
当你找到文本中所有字母的频率后,你可以创建一个函数来寻找“距离”。什么?这是什么意思?!
你可以想象一下,文本中例如 E 的频率会是一个数字。你可以找到它与实际频率的“距离”,实际频率是 12.70。例如:频率是 9.63,距离是多少?距离将是这两个值之间的绝对值(负数变为正数):\(12.70 - 9.63 = 3.07\)。
创建一个函数来遍历每个字母并找到距离。然后将所有距离加起来得到一个“总”距离。
数学函数?
如果您想知道这个数学函数是什么样的,那么它看起来像这样:
\(\sum_{n=0}^{N} \lvert a - b\rvert\)
Tips til framgangsmåte
- 使用
for循环遍历整个频率表。 - 对于频率表中的每个字母,找到它与实际频率的绝对值。 使用 Python 中的
abs()函数来实现。 - 将所有值加起来,你将得到最终结果。
任务 2.4 - “破解”凯撒密码
现在我们将把我们所做的一切都整合起来!现在我们将“破解”一个凯撒密码。
编写一个“破解”凯撒密码的程序!在没有用户干预的情况下,你应该能够输入一段加密文本并提取解密文本*而无需*密钥。
Test data
这里有一些测试数据,你们可以使用,这些数据说明了什么?
| 测试数据 |
|---|
cqrbvnbbjpnrbjenahbnlancxwnqxynoduuhhxdjanjkuncxmnlxmnrclxvyuncnuhjwmqnanjanbxvnfxamboaxvxdaojexarcnsnmrqnuuxcqnanrcbxenajwjtrwrqjencqnqrpqpaxdwmhxdfnanarpqccqnwnpxcrjcrxwbfnanbqxac |
lsaizivxlmwqiwwekimwuymxiwlsvxwsmxqmklxrsxasvoewibtigxihlsaizivmjmxhsiwksshnsf |
bmtxymjwjsfdfsxbjwrjxyfsifsizsktqidtzwxjqkqtslqnajymjpnslgfwsfwitmjdtzhtrjrtxyhfwjkzqqdzutsdtzwmtzwynxstbxywzhpybjqajljyymjjytgjikwfshnxhtktwymnxwjqnjkrzhmymfspxynxgnyyjwhtqifsinfrxnhpfymjfwymfajdtzmfivznjylzfwistyfrtzxjxynwwnslbjqqlttisnlmynkdtzitrjjymtwfyntfsirfwhjqqzxymjwnafqxtkrdbfyhmgniymjrrfpjmfxyj |
zwkyvivrivrepzuzfkjzekyviffdnzcckyvpgcvrjvjkreulgjrzukyvjritrjkztkvrtyvirwkvircfexjzcvetvfevwivjydreifjvkfyzjwvvkefnkyvedzjkvinypufpfltfejzuvipflijvcwrezuzfkzehlzivukyvkvrtyvinzkyrjevvinvccrtklrccpzufekjrzukyvjkluvekslkzyrkvkfjvvpfljkreuzexlgkyvivrccsppflijvcw |
uwwilxchaniuffehiqhfuqmizupcuncihnbylycmhiqusuvyymbiofxvyuvfynizfscnmqchamulyniimguffniayncnmzunfcnnfyvixsizznbyaliohxnbyvyyizwiolmyzfcymuhsqusvywuomyvyymxihnwulyqbunboguhmnbchecmcgjimmcvfysyffiqvfuwesyffiqvfuwesyffiqvfuwesyffiqvfuweiibvfuweuhxsyffiqfynmmbueycnojufcnnfyvullsvlyuezumncmlyuxswigcha |
Tips til framgangsmåte
- 首先创建一个接收文本的函数。
- 使用凯撒密码的解密函数,对文本进行 N 次旋转,N 从 0 开始。
- 创建结果的频率表。
- 找出结果与实际频率表的距离。
- 要么:a) 将距离存储在列表中,或者 b) 跟踪最小值和旋转次数(这将是密钥)。
- 将旋转次数增加 1 并重复步骤 2 到 6,直到 N 达到 26(完全旋转)。
- 返回解密后的文本,即最小距离是正确的密钥。

