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 |
0 | 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 |
1.加密原理
所谓的“凯撒加密法”,就是将需要加密的原文,逐个字符转化成其他字符的之后,形成新的密文。
如上图,第一行,是所有可以被转换的字符(为方便显示,只列举了26个小写英文字符),
第二行,为第一行每个字符对应的索引。
接着,从1~X(X为需要加密的字符的最大索引值)中,选取一个数字,作为密钥。
当我们拿到需要加密的字符串时,将字符串中每个字符逐一去上图中寻找,找到其对应的索引,
之后,将得到的索引与密钥相加,得到的新索引对应的字符,就是转换后的新字符;
如果索引与密钥相加后大于索引的最大值,则需要从头寻找对应的新字符。
举个例子:
我们将“helloworld”通过“凯撒加密法”进行加密,密钥为10,
我们从第一个字符“h”开始,在上图中找到h的索引为7,
将h的索引与密钥相加,得到17,从上图找到索引为17的字符为r;
根据上面的步骤,我们将每个字符按照顺序逐个进行转化,最终得到密文:“rovvygybvn”
需要注意的是:
字符“w”的索引22,加上密钥后得到32,大于了加密源字符个数26,于是会从0开始继续寻找,
直到找到索引为6(32 - 26 = 6)的字符“g”
2.解密原理:
由于“凯撒加密法”只是将原文中的每个字符进行转化得到密文;
所以在拿到密文后,只要根据密钥,反推加密过程,即可得到加密前的原文;
举个例子:
密文为“rovvygybvn”,密钥为10,
我们先找到密文的第1个字符r的索引,17;
通过密钥,反推加密过程,我们可以知道密文在加密前的原文字符索引为7 (17 - 10 = 7),
从上图中可知,索引为7的字符为 h;
需要注意:
如果密文字符的索引小于密钥时,
需要将密文字符的索引与加密源字符个数(上图最大索引值为26)相加,在减去密钥,得到原文字符索引,
例如:
在解密密文字符g时,由于g的索引为6,小于密钥10,
为了找到原文字符,我们需要将g的索引与26(加密源字符个数)相加,
再与密钥10相减,即(6 + 26) - 10 = 22,由上图可知,对应原文字符为w
通过上述过程,我们将每个字符逐一解密,得到原文“helloworld”
具体代码实现如下(python实现):
#密文源字符串
#encryptSource = r"abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNPOQRSTUVWXYZ1234567890 ,.\"'!"
encryptSource = r"abcdefghigklmnopqrstuvwxyz"
#加密源字符个数
encryptSourceMaxIndex = len(encryptSource)
#密钥
key = 10
#原文
#source = "Hello,World!"
source = "helloworld"
cryptograph = "rovvygybvn"
#加密方法
def encryptByCaesar(source):
#密文
newSource = ""
#循环原文中的每个字符,
#将每个字符在密文源字符串中的索引加上密钥,得到一个新的索引值
#如果新索引值大于密文源字符个数,则取新索引与密文源字符个数的差的绝对值
#根据新索引值,得到加密后的字符,并加入到密文字符串的末尾
for index in range(len(source)):
#找到原文字符的索引
oldEncryptSourceIndex = encryptSource.find(source[index])
#计算转换后字符的索引
newEncryptSourceIndex = (oldEncryptSourceIndex + key) if (oldEncryptSourceIndex + key) <= encryptSourceMaxIndex else abs((oldEncryptSourceIndex + key) - encryptSourceMaxIndex)
#找到新字符,并拼接密文
newSource += encryptSource[newEncryptSourceIndex]
return newSource
#解密方法
def unencryptByCaesar(cryptograph):
#保存原文字符串
sourceStr = "";
#循环密文中的每个字符,
#将每个字符在密文源字符串中的索引减上密钥,得到一个新的索引值
#如果密文索引值小于密钥,则将密文索引与密文源最大索引值相加,再减去密钥,得到原文字符索引
#根据新索引值,得到加密后的字符,并加入到密文字符串的末尾
for index in range(len(cryptograph)):
#获取密文字符的索引值
cryptographIndex = encryptSource.find(cryptograph[index])
#计算原文字符的索引值
SourceIndex = (cryptographIndex - key) if cryptographIndex >= key else (cryptographIndex + encryptSourceMaxIndex) - key
#得到原文字符,拼接原文字符串
sourceStr += encryptSource[SourceIndex]
return sourceStr
print("source:" + source + ", new source:" + encryptByCaesar(source))
print("cryptograph:" + cryptograph + ", source:" + unencryptByCaesar(cryptograph))