加密算法学习总结---柱状换位加密

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jdhellfire/article/details/79680286

柱状换位加密

换位密码使用某种加密算法重新排列明文消息中的字母,从而形成密文消息。解密算法只需要反演加密转换的过程就能得到原始消息。

一.柱状换位加密它的加密算法:

1.给定加密的KEY,并按ASCII字母顺序给KEY的每一个字符标号:

选择ATTACKER作为加密的KEY,按照字母顺序给KEY每个字符进行编号得到如下结果:
这里写图片描述

2.将明文以KEY的长度为单位进行拆分,按行排列:

假设当明文为:The fighters will strike the enemy bases at noon 那么重新拆分和排列后的结果如下(本例忽略了空格):
这里写图片描述

3.按照KEY的字母标号为先后顺序,按列读取明文,进行重新组装得到密文:

这里写图片描述

二.柱状换位加密它的解密算法:

1.解密的算法和加密的算法正好相反,将密文按照KEY标号的顺序进行还原。

这里写图片描述
将得到的明文按行读取并组合即可。

三柱状换位密码的实现:

"""
柱状换位加密 Python Demo
"""


class PosReplace:
    def __init__(self, key):
        self.__key = key
        self.__key_index = self.__get_key_index()


    def encrypt(self, clear_text):

        fragement_len = len(self.__key)
        fragement_cnt = int(len(clear_text) / fragement_len)
        left_tail_char_cnt = int(len(clear_text) % len(self.__key))
        pading_char_cnt = len(self.__key) - left_tail_char_cnt

        # 明文字符串按秘钥长度进行分片存储
        clear_text_fragements = [list(clear_text[i:i + fragement_len]) for i in
                                 range(0, len(clear_text), fragement_len)]

        # 最后不足一分片的字符填充后存储
        clear_text_fragements[fragement_cnt] += list(' ' * pading_char_cnt)

        # 按key每个字符index的顺序,按列取明文字符,转换为密文的行,形成加密效果。
        cipher_text = self.__fragements_col_to_txt_line(clear_text_fragements, self.__key_index)

        return cipher_text

    def decrypt(self, cipher_text):

        cipher_text_fragements = []
        fragement_cnt = len(self.__key)
        fragement_len = int(len(cipher_text) / fragement_cnt)
        left_tail_char_cnt = int(len(cipher_text) % len(self.__key))

        # 不足一个分片长度的也要占一个分片
        fragement_len = fragement_len + 1 if left_tail_char_cnt != 0 else fragement_len

        # 以秘钥的长度分片并存储密文
        cipher_text_fragements = [list(cipher_text[i:i + fragement_len]) for i in
                                  range(0, len(cipher_text), fragement_len)]

        # 根据key每一位的index 排序每一个分片的内容
        cipher_text_fragements = sorted(cipher_text_fragements,
                                        key=lambda x: self.__key_index[cipher_text_fragements.index(x)])

        # 以排序后的分片的列作为行读取密文,并组成字符串即为明文
        clear_text = self.__fragements_col_to_txt_line(cipher_text_fragements, range(fragement_len))

        return clear_text

    def __get_key_index(self):
        # 根据Ascii码,计算key中每一个位的index
        key_index_lst = list(map(lambda key_char: sorted(self.__key).index(key_char), self.__key))

        # 处理重复的index,重复的加1
        key_index_adjust = []
        for index in key_index_lst:
            key_index_adjust.append(index + 1 if index in key_index_adjust else index)

        return key_index_adjust

    def __get_fragements_col(self, text_fragements, index):
        text_line = ''
        for fragment in text_fragements:
            text_line += fragment[index]

        return text_line

    def __fragements_col_to_txt_line(self, text_fragements, trans_seq):
        text_line = ''
        for seq in trans_seq:
            text = self.__get_fragements_col(text_fragements, seq)
            text_line += text

        return text_line


if __name__ == '__main__':

    clear_txt1 = \
    '''
    北京时间2月21日,2018赛季亚冠联赛小组赛G组第二轮赛事上演,广州恒大客场0-0战平大阪樱花,恒大遭遇2连平,大阪樱花小组赛前两战取得1胜1平战绩。比赛中恒大在场面上形成一定优势,阿兰曾连获得分良机,但均未能把握。
    '''

    cipher_txt = PosReplace(key='liuwei').encrypt(clear_txt1)

    print(cipher_txt)

    print(PosReplace(key='liuwei').decrypt(cipher_txt))

执行结果:

#机密后的密文
 22亚赛赛州-樱遇阪前胜比场定曾机把  时日赛小二,场大大,组得绩大成阿分未  月0冠G事恒02樱两1赛面优连,握 北21联组上大战,连花战平中上势获但。 
京18赛第演客平恒平小取战恒形,得均
 间,季组轮广0阪遭大赛1。在一兰良能 

#还原后的明文
  北京时间221日,2018赛季亚冠联赛小组赛G组第二轮赛事上演,广州恒大客场0-0战平大阪樱花,恒大遭遇2连平,大阪樱花小组赛前两战取得11平战绩。比赛中恒大在场面上形成一定优势,阿兰曾连获得分良机,但均未能把握。

猜你喜欢

转载自blog.csdn.net/jdhellfire/article/details/79680286