好像把明文水平翻转180度的效果。例如将“Hello World” 加密成 “dlroW olleH”
这是一种非常弱的加密方式。
message = "Three can keep a secret,if two of them are dead."
translated = ''
i = len(message) - 1
while i >= 0:
translated = translated + message[i]
i = i - 1
print translated
message = "this is my secret message"
key = 13
mode = "encrypt"
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
translated = ''
message = message.upper()
for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
if mode == "encrypt":
num = num + key
elif mode == "decrypt":
num = num - key
if num >= len(LETTERS):
num = num - len(LETTERS)
elif num < 0:
num = num + len(LETTERS)
translated = translated + LETTERS[num]
else:
translated = translated + symbol
print translated
message = "GUVF VF ZL FRPERG ZRFFNTR"
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for key in range(len(LETTERS)):
translated = ''
for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
num = num - key
if num < 0:
num += len(LETTERS)
translated += LETTERS[num]
else:
translated += symbol
print "Key %s : %s"%(key , translated)
我们打印出了26中可能的解密。
换位加密法不是替换字符,而是搞乱消息符号的顺序。
例如消息 Common sense is not so common.
假设使用数字 8 作为秘钥。也就是我们将在每一行放最多8个字符。(包含空格和标点)
对于上面这条消息,我们可以画出这样一个方格图
C | o | m | m | o | n | s | |
e | n | s | e | i | s | ||
n | o | t | s | o | c | ||
o | m | m | o | n | . |
最后一行的两个格子涂黑忽略它们。
正常的阅读方式应该是横向去读。如果我们把消息用列向表示出来,它的混乱程度足以让别人看不清原来的消息
密文是:Cenoonommstmme oo snnio. s s c(表中的空格需要表示,黑色方格直接忽略)
def main():
myMessage = "Common sense is not so common."
myKey = 8
ciphertext = encryptMessage(myKey , myMessage)
print ciphertext + "|"
def encryptMessage(key , message):
ciphertext = ['']*key
for col in range(key):
pointer = col
while pointer < len(message):
ciphertext[col] += message[pointer]
pointer += key
return ''.join(ciphertext)
if __name__ == "__main__":
main()
具体到 encryptMessage 函数。我们首先创建了一个 list ,其中包含了 8(key)个空元素。这对应了上面表格中的8 (key) 列。
我们遍历这 8 列。
在第一列,我们依次拼接 原 message 中的 第 0,8,16,24......个字符。直到超出了 message 的长度。
在第二列,我们依次拼接 原 message 中的 第 1,9,17,25......个字符。直到超出了 message 的长度。
以此类推。
.join 方法将 list 转换为字符串然后 return。
当我们收到密文和秘钥之后。我们需要画一个表格。表格行数等于秘钥,列数等于密文长度除以秘钥然后向上取整。
例如 密文 “Cenoonommstmme oo snnio. s s c”长度30,秘钥key = 8,我们需要画8行4列的表格
从左上角开始向右填。那么从上往下阅读时我们会看到明文(其实这两个表格的关系就类似于矩阵的倒置)
C | e | n | o |
o | n | o | m |
m | s | t | m |
m | e | o | |
o | s | n | |
n | i | o | . |
s | |||
s | c |
import math
def main():
myMessage = "Cenoonommstmme oo snnio. s s c"
myKey = 8
ciphertext = decryptMessage(myKey , myMessage)
print ciphertext + "|"
def decryptMessage(key , message):
numOfColumns = int(math.ceil(len(message) / float(key)))
numOfRows = key
numOfShadeBoxes = (numOfColumns * numOfRows) - len(message)
plaintext = [''] * numOfColumns
col = 0
row = 0
for symbol in message:
plaintext[col] += symbol
col += 1
if col == numOfColumns or col == numOfColumns - 1 and row >= numOfRows - numOfShadeBoxes:
col = 0
row += 1
return ''.join(plaintext)
if __name__ == "__main__":
main()
这个程序完全按照和前面填表格的方式进行。
先从第0行开始,依次填第零列,第一列,第二列,第三列
然后跳到下一行,依次进行
其中。numOfShadedboxes 表示的是黑方格数,也就是默认不填字符的位置。程序会跳过这些地方填字符。
好的。现在让我们来写一个测试程序证明前面的加密和解密程序在对应不同的 message 和 key 时确实能正常工作。
import random,sys,transpositionEncrypt,transpositionDecrypt
def main():
random.seed(42)
for i in xrange(20):
message = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" * random.randint(4,40)
message = list(message)
random.shuffle(message)
message = ''.join(message)
print "Test #%s : %s..."%(i+1,message[:50])
for key in xrange(1,len(message)):
if message != transpositionDecrypt.decryptMessage(key , transpositionEncrypt.encryptMessage(key, message)):
print "Mismatch with key %s and message %s"%(key , message)
sys.exit()
print "Transposition cipher test passed."
if __name__ == "__main__":
main()