Bootstrap

混沌加密的理解及应用,附代码

目录

 

1.定义

2.混沌映射

3.加密函数

4.用python实现文本的加密


1.定义

混沌加密:主要是利用由混沌系统迭代产生的序列,作为加密变换的一个因子序列。混沌加密的理论依据是混沌的自相似性,使得局部选取的混沌密钥集,在分布形态上都与整体相似。混沌系统对初始状态高度的敏感性,复杂的动力学行为,分布上不符合概率统计学原理,是一种拟随机的序列,其结构复杂,可以提供具有良好的随机性、相关性和复杂性的拟随机序列,使混沌系统难以重构、分析和预测。

听起来很复杂,起始理解起来不难。一种简单的混沌加密模型,是用混沌映射函数模型产生一组随机的0,1序列。我们都知道,任何数据存储在计算机中都是0,1数据,那么我们将产生的0,1混沌序列和文本的0,1数据做一次运算是不是就将文本打乱了,也就是密码学中的混淆和扩散的作用,怎么样是不是很好理解。关键是由于混沌序列是随机的、复杂的,因此得到的密文的破解难度极大,使得这种方式加密的安全性极好。

2.混沌映射

混沌加密中最重要的是混沌映射函数,不同于y=ax+b这种,混沌映射函数是非线性的,如:

        

     

i=1,2,3.....,n,初始c(0)输入映射函数(c(0)的域为[0,1]),定义域[0,1]被控制参数r和0.5切割为三个域:[0,r]内将c(0)映射为距离值比c/r;[r,0.5]内映射为距离值比(c(0)-r)/(0.5-r);[0.5,1]内通过(1-c(0))回到[0,0.5]递归F函数。

不难得出c(i)的值是两个点到轴的距离的比值,故值域为[0,1]的有理数,且c(i)的数量可以无限多,而且值与值之间是非线性的混沌映射。

由输入c(0)开始,可以得到由一个个介于[0,1]的数组成的无限长的输出序列,具体要使用的长度取决于我们需要加密的数据的长的,将这些值映射到0,1序列,比如我们设置一个值T1(0<T1<1),规定小于T1的为0,大于T1的为1。于是我们得到了一个随机的0,1混沌序列。

 以T1为界,小于T1的映射为0,大于T1的映射为1。由无序的c(i)可得c*(i)也是无序的,虽然不是真正的随机序列,但比伪随机序列性能要好得多。

3.加密函数

以混沌序列为加密因子的加密函数有很多,我选择了一种常用的作为例子,见图:

    

b(i)为加密信息的一维序列,如文本的比特流。与所得的混沌序列c*(i)做异或运算得到加密后的序列W(i)。这种加密算法的其中一个优点是解密算法简单,将加密后的密文丢到加密算法中再加密一次就得到了原文,十分简单。从异或运算上也可以理解,和同一个值两次异或结果不变。

4.用python实现文本的加密

(1)文本转换为十进制

python只提供整数的异或,故我们要完成加密需要将文本转换为数字,这种转换虽然麻烦但并不复杂。转换的思路如下:

文本读取出来是字符串格式的,我们通过三步得到数字:取字符转换为ascii码,ascill码转化为十六进制,再将十六进制的字符转化为十进制的整数。

过程中用到的函数:

ord(s),s为字符,返回ascaii编码

hex(9),将9转换为16进制,返回一个以0x开头的字符串如'0x9'

hex(ord(s)).replace('0x','')将转化为16进制的字符串再去掉开头的0x

#将每个字节转成hex,0x顺便去掉,对于不足两位的补0
def str2hex(str):
    hexs = []
    for s in str:
        tmp = (hex(ord(s)).replace('0x',''))
        if len(tmp) == 2:
            hexs.append(tmp)
        else:
            hexs.append('0'+tmp)
    return hexs

#将字符形式存在的16进制转换为十进制整形数字
arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
arr2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
def tran(r):
    for i in range(len(arr)):
        if r == arr[i]:
            return arr2[i]

(2)混沌映射函数

实现混沌映射函数,输入为c(0)、r、T1。一次输出8位二进制并且转化为十进制参与运算。

#生成并返回一个16进制的混沌序列和下一个混沌序列的起始参数
def chaos_hex(c0,r,T1):
    k,j = chaos(c0,r,T1)
    num=j*2
    for i in range(6):
        k,j = chaos(k)          #调用处理一位的函数,并将返回结果每8位组成十进制返回
        num= num*2 + j
    return k,num
def chaos(c0,r,T1):            #一次处理一位的函数,返回生成的值和生成下一次的参数
    c1=0
    if 0 <= c0 <= r:
        c1 = c0 / r
    elif r < c0 <= 0.5:
        c1 = (c0 - r) / (0.5 - r)
    else:
        return chaos(1-c0,r,T1)
    if c1<=T1:
        c2=0
    else:
        c2=1
    return c1,c2    #下一个的值和结果

(3)文件处理

读文件-->文本转换为十进制--->加入混沌序列---->密文---->写入结果文件

输入参数:file_decode加密文件名,file_out保存的文件名, c0=0.4默认为0.4, r=0.3默认为0.3, T1=0.5 默认为0.5。

def chaos_decode(file_decode,file_out, c0=0.4, r=0.3, T1=0.5 ):
    try:
        with open(file_decode, 'r') as file:        #打开文件
            hexs = []                            
            while True:
                t = file.readline()                  #读文件保存到hexs
                if not t:
                    break
                hexs.extend(str2hex(t))

    except Exception as e:
        print('文件名有错,文件格式有错或文件内有中文解码错误')        
                                                #注意不要提供中文文本,最好为.txt格式
    try:
        with open(file_out,'wb') as file:            #保存文件
            k=c0
            for i in range(len(hexs)):
                a = tran(hexs[i][0]) * 16 + tran(hexs[i][1])
                k,b = chaos(k,r,T1)
                B = struct.pack('B', a ^ b)           
                               #这里用struct库的pack函数用来将异或后的结果打包成字节流便于保存
                file.write(B)
    except Exception as e:
        print('write file error')

(4)完整代码

import struct

#生成并返回一个16进制的混沌序列和下一个混沌序列的起始参数
def chaos_hex(c0,r,T1):
    k,j = chaos(c0,r,T1)
    num=j*2
    for i in range(6):
        k,j = chaos(k)
        num= num*2 + j
    return k,num
def chaos(c0,r,T1):
    c1=0
    if 0 <= c0 <= r:
        c1 = c0 / r
    elif r < c0 <= 0.5:
        c1 = (c0 - r) / (0.5 - r)
    else:
        return chaos(1-c0,r,T1)
    if c1<=T1:
        c2=0
    else:
        c2=1
    return c1,c2    #下一个的值和结果

#将每个字节转成hex,0x顺便去掉,对于不足两位的补0
def str2hex(str):
    hexs = []
    for s in str:
        tmp = (hex(ord(s)).replace('0x',''))
        if len(tmp) == 2:
            hexs.append(tmp)
        else:
            hexs.append('0'+tmp)
    return hexs

#将字符形式存在的16进制转换为十进制整形数字
arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
arr2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
def tran(r):
    for i in range(len(arr)):
        if r == arr[i]:
            return arr2[i]

def chaos_decode(file_decode,file_out, c0=0.4, r=0.3, T1=0.5 ):
    try:
        with open(file_decode, 'r') as file:
            hexs = []
            while True:
                t = file.readline()
                if not t:
                    break
                hexs.extend(str2hex(t))

    except Exception as e:
        print('文件名有错,文件格式有错或文件内有中文解码错误')
    try:
        with open(file_out,'wb') as file:
            k=c0
            for i in range(len(hexs)):
                a = tran(hexs[i][0]) * 16 + tran(hexs[i][1])
                k,b = chaos(k,r,T1)
                B = struct.pack('B', a ^ b)
                file.write(B)
    except Exception as e:
        print('write file error')
decode_file = input('加密的文件名:')
out_file = input('保存的文件名:')
chaos_decode(decode_file,out_file)

如有错误欢迎大家指出

;