由于传播、利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人承担,Cyb3rES3c及文章作者不承担任何责任。如有侵权烦请告知,我们将立即删除相关内容并致歉。请遵守《中华人民共和国个人信息保护法》、《中华人民共和国网络安全法》等相关法律法规。
栅栏密码(Rail-Fence Cipher)是一种简单的置换密码,用于对文本信息进行加密和解密。其工作原理如下:
1.加密原理:
分栏:首先将需要加密的明文(即原始信息)中的字母交替排成多行(通常称为“栏”),栏数可以是任意的,但通常不会超过30个字母(大约一两句话的长度)
重新组合:接着,按照特定的顺序(例如,从上到下,再从下到上)将各栏中的字母重新组合成一行,形成密文。
以明文“THE LONGEST DAY MUST HAVE AN END”为例,如果选择两栏进行加密,过程如下:
分栏:
第一栏:T E O G S D Y U T A E N N
第二栏:H L N E T A M S H V A E D
重新组合:将第二栏的字母放在第一栏的后面,得到密文
TEOGSDYUTAENN HLNETAMSHVAED
2. 解密原理:
解密是加密的逆过程。已知密文和栏数,解密者可以按照相反的顺序将密文重新排列成多栏,然后再将各栏的字母按照原始的顺序合并成明文。
例如,对于上述密文“TEOGSDYUTAENN HLNETAMSHVAED”,已知为两栏加密,解密过程如下:
分栏:将密文分成两行
第一栏:T E O G S D Y U T A E N N
第二栏:H L N E T A M S H V A E D
重新组合:按照上下上下的顺序将两行字母合并成一行,得到明文“THE LONGEST DAY MUST HAVE AN END”。
# Rail-Fence Cipher Encode Algorithm
"""
加密信息 THE LONGEST DAY MUST HAVE AN END
key = 2
分栏
第一栏:T E O G S D Y U T A E N N
第二栏:H L N E T A M S H V A E D
将第二栏的字母放在第一栏的后面,得到密文 TEOGSDYUTAENN HLNETAMSHVAED
"""
def splitString(string, step):
length = len(string)
count = length % step
if length % step != 0:
for i in range(step - count):
string += ' '
# 将字符串分隔成若干个子串, 子串最大长度为 key
return [string[i: i + step] for i in range(0, length, step)]
if __name__ == '__main__':
string = str(input("Encode Info:"))
key = int(input("Key:"))
secret = ''
newString = string.replace(' ', '')
tempList = splitString(newString, key)
# 遍历二维数组, 取出每栏中的字符串
for i in range(key):
for j in range(len(tempList)):
secret += tempList[j][i]
secret += ' '
secretInfo = secret.replace(' ', '')
print("Encode-Secret:%s" % secretInfo)
# Rail-Fence Cipher Decode
"""
栅栏密码解密(即栅栏密码加密逆过程)
解密思路如下:
分栏
计算长度等于最大长度的栏的个数和长度等于最小长度的栏的个数
分栏之后执行加密的逆过程
"""
def splitString(string, step):
length = len(string)
if length % step == 0:
# 计算子串长度
childStringLength = int(length / step)
return childStringLength, [string[i : i + childStringLength] for i in range(0, length, childStringLength)]
else:
# 最大长度和最小长度之差恒等于1
minStringLength = int(length / step)
maxStringLength = minStringLength + 1
maxLengthCount = length % step
minLengthCount = step - maxLengthCount
maxStringLengthSum = (minStringLength + 1) * maxLengthCount
# 将长度等于最大长度的栏和长度等于最小长度的栏分离
maxStringSum = string[0 : maxStringLengthSum]
minStringSum = string[maxStringLengthSum : ]
# 将字符串彻底分栏
maxStringList = [maxStringSum[i : i + maxStringLength] for i in range(maxLengthCount)]
# 注意: 在分离最小长度栏时需要在每个子串后面加上空字符 ' ', 防止后面索引越界
minStringList = [minStringSum[i * minStringLength : i * minStringLength + minStringLength] + ' ' for i in range(minLengthCount)]
# minStringList = []
# for i in range(minLengthCount):
# start = i * minStringLength
# minStringList.append(minStringSum[start : start + minStringLength] + ' ')
# # minStringList += minStringSum[start : start + minStringLength]
# 将最大长度栏集合和最小长度栏集合进行合并
stringList = maxStringList + minStringList
return maxStringLength, stringList
if __name__ == '__main__':
encodeSecret = str(input("encodeSecret:"))
key = int(input("key:"))
childStringLength, tempList = splitString(encodeSecret, key)
secret = ''
for i in range(childStringLength):
for j in range(key):
secret += tempList[j][i]
secretInfo = secret.replace(' ', '')
print(secretInfo)
栅栏密码的加密强度相对较低,容易被破解,因此通常只用于简单的加密需求或教学目的。在实际应用中,可能会使用更复杂的加密算法来确保信息的安全性。
如果不知道密文的栏数,解密过程可能会变得困难,但可以使用解密工具中的列举解密方法来尝试不同的栏数组合。
文中文字描述以及代码编写如有不当,欢迎留言指正!
原文始发于微信公众号(Cyb3rES3c):一文了解栅栏密码
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论