• transpositionEncrypt and decrypt


    换位加密算法


    打乱明文的顺序的一种方法:

      列数即作为key值,这里key=8

      列表中对应有key个字符串

      末尾不用读

      确定每个字符串的值,最后再把他们连接起来   形成密文 

      有个小问题是若结尾后面有若干个空格,需要加上一个识别符号来确定

    加密“zhe ge she ji lie biao zhong de zi fu chuan si xiang.”,其中(s)为空格的标记 避免看成空

    0  1  2  3  4  5  6 7
     z  h  e  (s)  g  e  (s)
     h  e  (s)  j  i  (S)  l
     e  (s)  b  i  a  o  (s)
     h (s)  (s) 
     z (s)  (s) 
    a n (s) s i (s) x i
    a n g .        

    读出第一列[0]:'zhehzaa'

    读出第二列[1]:'he(s)oinn'

    读出第三列[2]:'e(s)bn(s)(s)g'

    读出第四列[3]:'(s)jigfs.'

    读出第五列[4]:'gia(s)ui'

    读出第六列[5]:'e(s)od(s)(s)'

    读出第七列[6]:'(s)l(s)ecx'

    读出第八列[7]:'siz(s)hi'

    密文:'zhehzaa'+'he(s)oinn'+'e(s)bn(s)(s)g'+'(s)jigfs.'+'gia(s)ui'+'e(s)od(s)(s)'+'(s)l(s)ecx'+'siz(s)hi'='zhehzaahe oinne bn  g jigfs.gia uie od   l ecxsiz hi'


    加密算法:

    # Transposition Cipher Encryption
    # http://inventwithpython.com/hacking (BSD Licensed)
    
    import pyperclip
    
    def main():
        myMessage = 'Common sense is not so common.'
        myKey = 8
    
        #得到整个密文字符串
        ciphertext = encryptMessage(myKey, myMessage)
    
        # Print the encrypted string in ciphertext to the screen, with
        # a | (called "pipe" character) after it in case there are spaces at
        # the end of the encrypted message.
        print(ciphertext + '|')
    
        # Copy the encrypted string in ciphertext to the clipboard.
        pyperclip.copy(ciphertext)
    
    #形参(parameter)是在函数被调用时包含被传递实参(argumrnt)的变量,形参会在函
    #数返回时候自动删除  形参在def语句中   实参在调用中  实参的实际上在调用的时候
    #赋值给了形参,对形参的修改只存在于函数内 也就是说形参如果被修改,提供实参值的
    #变量不会改变
    def encryptMessage(key, message):
        # Each string in ciphertext represents a column in the grid.
        #列表list   [项,项,项,项,项...]  有索引操作和分片操作 注意第一项的索引是0
        #注意切片操作是字符串的拷贝,列表里面的项也可以是列表:多重列表myList[0][1]
        #for可以迭代列表里的项  list上有len()和in运算  使用+和* 链接和复制列表
        #先记住这个就好了,能对字符操作的大多数事情也能对列表list操作
        '''
            list()函数zai区间对象上构造列表
            myList = list(range(10)) -->  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
            myList = list('Hello world!') -->  ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!']
        '''
        #创建列表,使之包含正确的空字符串
        ciphertext = [''] * key
    
        # Loop through each column in ciphertext.
        for col in range(key):
            pointer = col
    
            # Keep looping until pointer goes past the length of the message.
            while pointer < len(message):
                # Place the character at pointer in message at the end of the
                # current column in the ciphertext list.
                ciphertext[col] += message[pointer]
    
                # move pointer over
                pointer += key
    
        # Convert the ciphertext list into a single string value and return it.
        return ''.join(ciphertext)
    
    
    # If transpositionEncrypt.py is run (instead of imported as a module) call
    # the main() function.
    if __name__ == '__main__':
        main()

    输出:Cenoonommstmme oo snnio. s s c|

    =====================================================================分割线================================================================================================

    P.S.  用join()方法接受一个字符串列表返回一个字符串   即合并,调用jion()的字符串会放到列表里的各字符串之间作为分隔符   常用''.jion(myList)不要分割直接连接起来

    >>> eggs = ['dogs', 'cats', 'mose']
    >>> ''.jion(eggs) 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'str' object has no attribute 'jion'
    >>> ''.join(eggs) 
    'dogscatsmose'
    >>> '*'.join(eggs) 
    'dogs*cats*mose'

    P.S. 当一个python程序运行时,在第一行代码运行前,有一个特殊的叫做__name__的变量会被赋值为字符串值'__main__',如果这个文档transpositionEncrypt.py被其他.py程序导入,

    执行import transpositionEncrypt时,会加上.py来查找文件transpositionEncrypt.py,当一个transpositionEncrypt.py程序被导入时,

    那么__name__会被赋值为字符串值’transpositionEncrypt‘,然后运行这个程序,但我们只是希望所有的def被执行而不运行main()函数,

    # the main() function.
    if __name__ == '__main__':
        main()

    这种单独的main()方法,使我们的程序可以作为一个程序单独运行,也可以作为一个模块导入另一个程序。

    =====================================================================分割线================================================================================================


    解密算法:

    当收到'zhehzaahe oinne bn  g jigfs.gia uie od   l ecxsiz hi'并且知道key=8,我们来进行破译:

    z

     h  e  h  z  a  a
     h  e  (s)  o  i  n  n
     e  (s)  b  n  (s)  (s) g
     (s)  j  i  g  f  s  .
     g  i  a  (s)  u  i  
     e  (s)  o  d  (s)  (s)  
     (s)  l  (s)  e  c  z  
     s  i  z  (s)  h  i  

      

    然后依次对每列向下读出,连接起来:'zhe ge she ji lie biao zhong de zi fu chuan si xiang.'

    首先需要明白怎么画格子,解密时的格子和加密时候有很大不同,但是有相关的性质

        1、将消息的长度除以密钥并向上取整数计算需要的列数

        2、画出一定数量的格子,列数第一部计算,行数和密钥一样长

        3、将总格子数减去密文长度得到最右边的那一列要涂黑的格子数

        4、填入密文,从最上面一行开始,从左向右填入,跳过黑色的格子

        5、获取明文,从最左边一列开始读取,从上往下读,依次对每列读取

    # Transposition Cipher Decryption
    # http://inventwithpython.com/hacking (BSD Licensed)
    #同时导入多个模块用,分隔即可
    import math, pyperclip
    
    def main():
        myMessage = 'Cenoonommstmme oo snnio. s s c'
        myKey = 8
    
        plaintext = decryptMessage(myKey, myMessage)
    
        # Print with a | (called "pipe" character) after it in case
        # there are spaces at the end of the decrypted message.
        print(plaintext + '|')
    
        pyperclip.copy(plaintext)
    
    
    def decryptMessage(key, message):
        # The transposition decrypt function will simulate the "columns" and
        # "rows" of the grid that the plaintext is written on by using a list
        # of strings. First, we need to calculate a few values.
    
        # The number of "columns" in our transposition grid:
        #/除法表达式返回浮点数21 / 3 = 7.0   
        #四舍五入    向下取整    和   向上取整  
        #四舍五入   round(22/5)=4
        #向上取整   math.ceil()          math.ceil(9.5) = 10
        #向下取整   math.floor()         math.floor(9.5) = 9
        numOfColumns = math.ceil(len(message) / key)
        # The number of "rows" in our grid will need:
        numOfRows = key
        # The number of "shaded boxes" in the last "column" of the grid:
        numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)
    
        # Each string in plaintext represents a column in the grid.
        #最后我们是要把所有的列读出来连接到一起
        plaintext = [''] * numOfColumns
    
        # The col and row variables point to where in the grid the next
        # col和raw 来跟踪massge里的下一个字符所在的行和列
        # character in the encrypted message will go.
        col = 0
        row = 0
    
        # 调整col和raw, 把symbol连接带plaintext列表里的所有字符串
        for symbol in message:
            plaintext[col] += symbol
            col += 1 # point to next column
    
            # If there are no more columns OR we're at a shaded box, go back to
            # the first column and the next row.
            # and 和 or 运算用来简化代码
            #有两种情况需要把col重新赋值为0,以便进行下一行的赋值
            #1递增之后col超过了plaintext的最后一个索引numOfColumns-1   所以  col == numOfColumns
            #2col等于最后一个索引但是这时候不能填入格子因为这时的格子是黑的
            if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
                col = 0
                row += 1
    
        return ''.join(plaintext)
    
    
    # If transpositionDecrypt.py is run (instead of imported as a module) call
    # the main() function.
    if __name__ == '__main__':
        main()

    输出:Common sense is not so common.


    暴力破译的话,在一定的范围内遍历key就好了。


    尝试写一个自动测试加解密方案的小程序来确定算法的可行性:

    # Transposition Cipher Test
    # http://inventwithpython.com/hacking (BSD Licensed)
    
    import random, sys, transpositionEncrypt, transpositionDecrypt
    
    def main():
        #random.seed(数)是设置伪随机种子,特定的算法,所以一个种子产生的随机数都是可以预测的
        random.seed(42) # set the random "seed" to a static value
        #测试20次
        for i in range(20): # run 20 tests
            # Generate random messages to test.
    
            # The message will have a random length:
            message = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' * random.randint(4, 40)
    
            # Convert the message string to a list to shuffle it.
            # 随机打乱一个字符串66666666666666666666
            # 先使用list()把这个字符串转化成列表mylist,每一个项都是一个字母,
            # 然后使用random.shuffle(mylist)打乱这个列表,请记住random.shuffle()是就地修改,
            #                                           而不是某个对象的调用,是random的方法。
            # 最后再用''.join(mylist)把这个列表里的每一个字符串连接起来形成一个大的字符串#done
            message = list(message)
            random.shuffle(message)
            message = ''.join(message) # convert list to string
    
            #字符串的切片操作是字符串的拷贝message[:50]  不改变原massage
            print('Test #%s: "%s..."' % (i+1, message[:50]))
    
            # Check all possible keys for each message.
            for key in range(1, len(message)):
                encrypted = transpositionEncrypt.encryptMessage(key, message)
                decrypted = transpositionDecrypt.decryptMessage(key, encrypted)
    
                # If the decryption doesn't match the original message, display
                # an error message and quit.
                if message != decrypted:
                    print('Mismatch with key %s and message %s.' % (key, message))
                    print(decrypted)
                    # 这里的sys.exit()是让整个程序提前退出,立刻中止
                    sys.exit()
    
        print('Transposition cipher test passed.')
    
    
    # If transpositionTest.py is run (instead of imported as a module) call
    # the main() function.
    if __name__ == '__main__':
        main()

    输出:

    Test #1: "JEQLDFKJZWALCOYACUPLTRRMLWHOBXQNEAWSLGWAGQQSRSIUIQ..."
    Test #2: "SWRCLUCRDOMLWZKOMAGVOTXUVVEPIOJMSBEQRQOFRGCCKENINV..."
    Test #3: "BIZBPZUIWDUFXAPJTHCMDWEGHYOWKWWWSJYKDQVSFWCJNCOZZA..."
    Test #4: "JEWBCEXVZAILLCHDZJCUTXASSZZRKRPMYGTGHBXPQPBEBVCODM..."
    Test #5: "DMMEDKAHCZJDBNCCCZNENAOSJUKGHGUANOCHFGSEVDOMYHVBRK..."
    Test #6: "WPOWKFRGLWZFRPXYPDUQADOXPGEABHKNMDLYTITYOBEATVLAIB..."
    Test #7: "KVNJOCYPGIUNVLPRZFFAESDUTZRMDKRSSAWQIWXWCPGWUISLHP..."
    Test #9: "PVHJOFQJRGXYXFFRRJZTQXRFLWVHPQSHNYOZRJSKJFNRIGQYCH..."
    Test #10: "CFWPWYEKXSREXTZZLITJIXIXESHFJCSPLVZQTMWBRTSYBEDCHK..."
    Test #11: "QNUZXADCRFYBODYWYJZTPFMGYNWNKGYUBCJXHSSPIIWYYRXCXK..."
    Test #12: "DZSEKFURFHNLMFRITPTNQWEVVJVDSBOUUFKXZJNRXHANWCBEYX..."
    Test #13: "FXCAYLCKJIACMGATEPYLHAHVSMTHIHDHNBBNFWVXURLVADSGDB..."
    Test #15: "WHXYUOUIJQLVDKKSZBTPYOHHGAJFUGILNMQAWTMUOICNFIOJXO..."
    Test #16: "GMZMPQAMZDMWCMDMCLUOSWDRJZBVPKYGZDXCWOUVIQLLECWSMU..."
    Test #17: "KPKHHLPUWPSSIOULGKVEFHZOKBFHXUKVSEOWOENOZSNIDELAWR..."
    Test #18: "OYLFXXZENDFGSXTEAHGHPBNORCFEPBMITILSSJRGDVMNSOMURV..."
    Test #19: "SOCLYBRVDPLNVJKAFDGHCQMXIOPEJSXEAAXNWCCYAGZGLZGZHK..."
    Test #20: "JXJGRBCKZXPUIEXOJUNZEYYSEAEGVOJWIRTSSGPUWPNZUBQNDA..."
    Transposition cipher test passed.

  • 相关阅读:
    Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    dubbo初探(转载)
    基于ZooKeeper的Dubbo注册中心
    kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
    HBase权威指南 高清中文版 PDF(来自linuxidc)
    Hadoop + HBase (自带zookeeper 也可单独加) 集群部署
    zookeeper 入门讲解实例 转
    eclipse 配置黑色主题
    myeclipse 2016 激活,myeclipse 2016 激活
    界面上传文件js包【AjaxUpload.js】
  • 原文地址:https://www.cnblogs.com/PiaYie/p/13469532.html
Copyright © 2020-2023  润新知