0%

Image encryption based on three-dimensional bit matrix permutation

论文地址

基于三维位矩阵排列的图像加密
摘要

最近,人们提出了许多基于像素级或位级加密的图像加密算法。然而,无论是像素级排列还是位级排列都有其固有的缺陷。本文提出了一种新的密码系统来解决这些问题。首先对不同的排列算法进行了全面的分析和比较。由于从位级的角度来看,图像可以被认为是一个自然的三维(3D)位矩阵(宽度、高度和位长),因此提出了一种新的三维位矩阵排列,置乱阶段将Chen系统与3D Cat映射相结合,提出了一种新的映射规则,将3D矩阵中的一个随机位置映射到另一个随机位置(即双随机位置置换),而不是使用传统的顺序访问普通图像。仿真结果验证了该密码系统的安全性和有效性。

引言

互联网技术与社会的发展网络服务(SNS)使得数字图片和视频的在线分享越来越多。与此同时,非法访问或修改私人多媒体信息已成为数字世界中一个严重的问题。尽管这种性质的问题可以通过使用信息加密来解决,但由于这类信息的固有特征,包括相邻像素中的数据之间的高度相关性,传统的加密方案,例如DES和AES,不适用于多媒体信息加密应用程序以及实时变换的需要。因此,需要一种新的加密机制来满足多媒体信息的特殊需求。在这方面,近年来,利用混沌理论和排列-扩散体系结构的图像加密技术取得了重大进展。

到目前为止已经提出了许多图像加密算法,这些算法根据产生伪随机数的方式可以分为两类:基于混沌理论的算法和基于非混沌理论的算法。基于混沌的图像加密,是基于混沌动态系统和密码系统之间的相似性,包括伪随机行为,对初始条件的敏感性和遍历性。两种图像加密的第二种,非混沌加密,涉及到使用非混沌动态系统生成伪随机数序列,然后使用伪随机数序列对图像进行加密的方法。

然而,图像加密的问题是,图像的位矩阵是一个自然的3D矩阵,因为一个256级灰度的大小为M*N的图像可以看做一个M*N*8的矩阵,在此基础上,现有的大多数算法尝试使用多种二维排列组合来对三维矩阵进行排列。此外,使用二维混沌映射或排序算法进行排列会出现重复的模式问题,排序序列中元素数量的增加导致排序算法的执行时间迅速增加。

为了解决上述问题,本文提出了一种新的基于Chen系统和三维混沌映射耦合的三维置换算法,在新的置换算法中,不仅可以修改位的位置,而且可以同时修改每个位的权值。在此基础上,本文提出了一种新的基于Chen系统的三维明文图像随机访问机制,使用三维cat映射控制第二阶段的排列。仿真结果表明,该方案具有较高的安全性和有效性。

排列算法中的问题

排列算法在图像加密中起着重要的作用,它通常是密码系统的第一步,目的是对所有像素进行重新定位。排列算法可以根据图像加密时是否移动像素或位元分为两类或两级。位级排列算法重新定义每个像素的基本位组成,因此在像素级上产生完全不同的统计信息。对256 Gy级的明文图像的8位平面分别进行排列,然后重新组合形成密码图像;然而,这忽略了比特平面之间的区别和联系。

在算法本身的基础上,还可以对置换算法进行另一种分类,即计算置换操作后每个像素的新位置的方法。这两类算法分别是基于排序的置换算法和基于二维混沌映射置换的置换算法,第一类算法使用随机数序列来定义新的位置,一般来说,根据伪随机系统计算一个或多个随机序列,然后对序列进行排序。在此之后,在排序前后序列中的两个相对位置之间获得一个映射规则,该映射规则应用于可能是行、列或像素的排列单元。序列中的元素数等于明文图像中的比特数,长序列排序后,比特的位置就确定了。这个算法非常耗时,因为对如此大量的数字进行排序和比较是一个cpu频带例程。基于排列的排序算法的优点是易于设计和实现,缺点是通常需要过多的执行时间。第二类算法,利用由离散2D混沌映射(如Cat映射、标准映射、Henon映射和Baker映射)控制的排列过程。二维混沌系统生成随机目标位置集,并将像素映射到密码图像中。然而,在扩散操作前,由二维控制的排列总是出现重复的图案,因为输出位置的坐标不是完全随机的。二维混沌映射的排列算法,排列的图像可能会出现重复的模式,一个映射规则由混沌映射的结果,导致几乎所有的像素相似的距离在同一方向移动,尤其是当猫使用地图。因此,重复模式反映了所有像素的规律性移动。这种置换算法的优点是在实现上的时间效率,缺点是其密码系统的安全性很大程度上依赖于扩散操作,而置换算法是扩散操作的辅助步骤。然而,在基于排序的排列算法的情况下,情况是不同的。这种算法可以采用两种排列方法中的一种。第一种方法将其基本元素作为一行或一列像素进行排列,在这种情况下,只需要对少量数字进行排序。例如一个M*N的图像,需要对两个分别为M和N大小的伪随机序列进行排序,因此,执行此操作所需的时间是可以接受的。但是,随着序列中数字数量的增加,对特定序列进行排序的时间会显著增加。第二种排列方法的缺点是,用于排列的基本元素是像素或位,其随机序列的长度等于像素或位的数量。在这种情况下,对如此大的序列进行排序非常耗时。

基于以上分析,我们可以得出一个有效的位级置换算法有两个标准:(1)混淆图像不存在重复模式;(2)排列后图像的直方图应均匀分布。普通的排列算法不能满足这两个要求,上述置换算法都是在二维平面上进行的,不能在位级上提供完全随机的位置移位策略。这些算法通常将置换平面指定为一个位平面或一个像素平面组成一个颜色通道,整个置换效果被认为是多个置换平面的组合。实际上,图像的位矩阵就形成了一个自然的3D矩阵,例如,一个大小为M*N的256级灰度的图像包含一个大小为M*N*8的矩阵。因此,我们的研究目的是确定是否有可能直接排列3D矩阵,使用排列规则来确定3D位置,而不是不同排列的2D平面的组合。新的3D排列规则定义了一种随机重定位机制,允许明文图像中的每一位都有同等的可能性重定位到3D位矩阵中的任何位置。

基于三维位矩阵的混合排列结构

本节介绍我们提出的基于图像可以自然地被视为3D位矩阵的新位级排列架构,新的排列体系结构结合了基于排序和基于Cat映射的排列。

如上所述,一个大小为512*512的256级灰度图像可以被认为是一个大小为512*512*8的三维矩阵,对应的r1,r2,r3分别为512、512和24。此外,对于RGB彩色图像,r1、r2、r3的值为512、512和24。对于基于排序的排列算法,将排序序列的长度加倍将使执行时间增加两倍以上。在我们提出的方案中,我们使用一个转换后的三维位矩阵来减少排列时间。对一个标准的大小为512*512的256级灰度测试图像,转换的三维矩阵为128*128*128,因为512*512*8=128*128*128。仿真结果表明,当每个维位比特数越近,该排序算法的速度越快。需要注意的是,每个方向上的位数不需要像这里一样相同。

基于排序的排列算法和基于二维混沌映射的排列算法有各自的特点,总结如下表

Permutation Permuted element Benefit Drawback
Sorting-based Column and row sorted
Pixel or bit sorted
Fast
Permutation effect is good
Repeat patterns
Execution time is too long not acceptable
2D chaotic map-based Pixel or bit Fast Repeat patterns

基于排序的排列算法的混淆效果稍好,因为基本移动单元可以是一列、一行或一个像素。然而,当序列元素增加时,基于排序的排列的执行时间显著增加。二维混沌映射置换算法的情况则有所不同。排列效果不够好,混乱图像中出现大量重复图案,但执行时间快。无论是基于排序的算法还是基于二维混沌映射的置换算法都可以产生完全噪声的密文图像

本节介绍一种新的基于双随机位置映射(DRPM)的置换策略,它利用了基于排序和基于混沌映射的置换算法的优点。对转换后的三维位矩阵进行排列策略,利用耦合的三维混沌映射、Chen系统和三维Cat映射有效地生成混沌图像。

利用Chen系统生成第一个映射规则,对三维位矩阵进行随机访问

其中,a,b,c是控制参数。在Chen系统中,当a=35,b=3,c $\in$[20,28.4]时,动态系统是混沌的。通过欧拉公式用步长0.001得到三个大小分别为r1,r2,r3的序列,定义如下式。Chen系统的初始值为 $key_c_x_0$=0.22521231547896,$key_c_y_0$=0.58749654123587,$key_c_z_0$=0.98564123475621。

其中, $x_i,y_i,z_i$是Chen系统产生的伪随机序列并且 i $\in$[0,127]。然后对三个序列排序得到排序后的序列 $sqx_i,sqy_i,sqz_i$。

通过将排序后的序列与原始序列进行比较,可以得到映射序列X、Y、Z。经过比较,如果序列$sqx_i$的第一个数字位于序列qxi的k1位置,则映射规则X的第一个数字为k1,依次类推,得到映射规则X,Y,Z

将X、Y、Z三个映射序列组合得到第一个映射规则,将普通位映射到随机位。

其中,$1\leq bx\leq r_1,1\leq by \leq r_2,1\leq bz\leq r_3,k_{bx}^x,k_{by}^y,k_{bz}^z$定义如上X,Y,Z。(bx,by,bz)代表三维矩阵的顺序位置, $k_{bx}^x,k_{by}^y,k_{bz}^z$代表随机位置。

在混淆操作中有两个因素导致重复模式。第一种是控制混乱操作的混沌映射的内在重复模式,而第二种是由序列访问的相邻像素值的相似性引起的普通图像的顺序访问。换句话说,重复模式出现的原因是在重复模式的混沌映射下,几乎相同值的像素被顺序映射,和使用相同的程序访问大量相同或相似的像素并映射到目标位置。由于连续访问明文图像中具有相同值的像素,这将导致在混淆图像中出现重复的模式。

该方案采用了一种新的对明文图像的访问策略,试图避免这一问题。上述定义映射规则,将每个顺序位置映射到随机位置。通过反向使用这个映射规则,定义一个从随机位置到顺序位置的新映射规则成为可能,如下:

利用下面描述的第二条映射规则(3D Cat映射),定义了3D矩阵中从一个随机位置到另一个位置的新的映射规则

3D Cat映射用于控制每个比特的置换操作的第二步,定义如下:

其中,$a_x,a_y,a_z,b_x,b_y,b_z$是3D Cat 映射的6个参数,计算如下:

其中 $x_i,y_i,z_i$是由Chen系统得到的随机序列,Chen系统参数为a=35,b=3,c=28,初始条件是 $key_d_x_0$=0.22521231547896, $key_d_y_0$=0.58749654143234, $key_d_z_0$=0.98564123475621。

所提方案的扩散阶段

扩散操作在像素级执行。第一步是将被混淆的比特矩阵转化为二维像素矩阵,然后将二维像素矩阵转化为一维像素阵列。扩散操作如下:

其中,pm[i]代表排列图像的第i个像素,0<=i<=262143,cph[i]是密文图像的第i个像素。变量tmp1和tmp2是两个扩散操作期间的临时值,rdm1和rdm2是两个随机序列,定义如下。tmp2的初始条件是tmp2=$(3.99999key_{d3}(1-key_{d3})*1000)mod\ 256$),仿真模拟时, $key_{d3}$被设置为0.43263498463278。

其中,rs1和rs2是两个由逻辑映射生成的随机序列,初始值为 $key_{d1}$= 0.23465654373432, $key_{d2}$=0.34678978310437,逻辑映射定义如下:

在计算rdm1和rdm2时,如果输出数与前面的数相等,则丢弃该数,继续计算下一轮,以保证rdm1和rdm2不包含重复的数。

扩散阶段后,将一维像素序列转化为二维密码图像。该方案的每一个加密轮包括一个混淆轮和一个扩散轮。

所提出的方案

该方案是一个典型的Fridrich体系结构密码系统,其中一个加密轮包括一个混淆轮和一个扩散轮。

(1)首先将二维像素矩阵转化为三维比特矩阵;

(2)3D位矩阵是基于上述介绍的混合3D排列算法进行排列的,其中Chen系统和3D Cat映射控制整个过程。

a)随机序列qxi, qyi, qzi由Chen系统产生

b)这三个序列被排序,并与原始的三个序列进行比较得到映射序列X, Y, Z。随机访问规则 $(k_{bx}^x,k_{by}^y,k_{bz}^z)$定义了随机访问3D位矩阵的顺序。

c)根据步骤(b)定义的访问顺序,对于每一个比特,3D cat映射将计算其在置换3D矩阵中的新位置,直到所有比特都被置换。

(3)排列后的三维比特矩阵由三维比特矩阵转化为二维像素矩阵。置换阶段结束。

(4)将二维像素矩阵进一步转化为一维像素阵列。

(5)根据上述扩散描述对每个像素进行扩散操作

(6)将扩散阶段后的一维像素阵列转化为二维像素矩阵。扩散阶段结束。

在这些步骤中,混淆阶段包括步骤1、2、3,扩散阶段包括步骤4、5、6。

对于解密算法,应反向执行上述步骤。

实验结果

bit_matrix

实验代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
import cv2
import hashlib
import numpy as np
import matplotlib.pyplot as plt

'''
Chen吸引子生成函数
参数为三个初始坐标,三个初始参数,迭代次数
返回三个一维数组(坐标)
'''
def Chen(x0,y0,z0,a,b,c,T):
h=0.001
x=[]
y=[]
z=[]
for t in range(T):
xt=x0+h*(a*(y0-x0))
yt=y0+h*((c-a)*x0-x0*z0+c*y0)
zt=z0+h*(x0*y0-b*z0)
#x0、y0、z0统一更新
x0,y0,z0=xt,yt,zt
x.append(x0)
y.append(y0)
z.append(z0)

return x,y,z

def Logistic(x0,T):
#混沌系统控制参数
u=3.99999
#一个临时数组用于返回加密后的图像,可以不影响原始图像
seq=np.zeros(T)
for i in range(T):
#计算混沌序列值
x0=u*x0*(1-x0)
seq[i]=x0
return seq

def bit2pixel(bits):
return bits[0]*128+bits[1]*64+bits[2]*32+bits[3]*16+bits[4]*8+bits[5]*4+bits[6]*2+bits[7]

#传入0-255之间的一个整数,输出包含8个元素的数组
def pixel2bit(pixel):
bin_pixel=bin(pixel)[2:].zfill(8)
arr=np.zeros(8)
for i in range(8):
arr[i]=bin_pixel[i]
return arr

'''
加密函数
img:原始图像路径
key:密钥列表,大小为9(1、2为PWLCM初始条件和参数;3、4、5、6为Chen系统初值,7、8、9为Lorenz系统初值)
return:返回加密后的图像
'''
def encrypt(img,key):
#三维矩阵
im=cv2.imread(img)
#获取图像宽高和通道数
[h,w,dim]=im.shape
print(im[0][:5])

#二维明文图像转成三维比特矩阵,先设为h*w*8dim
#三维矩阵的维度
r1=h
r2=w
r3=8*dim
bin_pixels=np.zeros((r1,r2,r3))
for i in range(r1):
for j in range(r2):
bin_pixels[i][j]=np.append(np.append(pixel2bit(im[i][j][0]),pixel2bit(im[i][j][1])),pixel2bit(im[i][j][2]))
#Chen系统控制参数
a=35
b=3
c=28
#初始条件
x0=key[0]
y0=key[1]
z0=key[2]
#迭代次数,舍去前500个暂态值
T=500+r1+r2+r3
xi,yi,zi=Chen(x0,y0,z0,a,b,c,T)
#得到大小分别为r1,r2,r3的三个整数序列
qxi=[]
qyi=[]
qzi=[]
#与65536取模,而不是256是为了扩大序列值空间,兼顾效率的同时增加随机性
for i in xi[-r1:]:
qxi.append(int(i*(10**9))%65536)
for i in yi[-r2:]:
qyi.append(int(i*(10**9))%65536)
for i in zi[-r3:]:
qzi.append(int(i*(10**9))%65536)
X=np.arange(r1)
Y=np.arange(r2)
Z=np.arange(r3)
#根据qxi排序
#打包
dic=list(zip(qxi,X))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
X=list(list(zip(*dic))[1])
#根据qyi排序
dic=list(zip(qyi,Y))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
Y=list(list(zip(*dic))[1])
#根据qzi排序
dic=list(zip(qzi,Z))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
Z=list(list(zip(*dic))[1])
ax=int(xi[200]*(10**9))%64
ay=int(yi[200]*(10**9))%64
az=int(zi[200]*(10**9))%64
bx=int(xi[201]*(10**9))%64
by=int(yi[201]*(10**9))%64
bz=int(zi[201]*(10**9))%64
ax=ay=az=bx=by=bz=1
cat=np.zeros((3,3))
cat=np.array([[1+az*az*by,az,ay+ax*az+ax*ay*az*by],[bz+az*by+ax*az*by*bz,az*bz+1,ay*az+az*ay*by*bz+ax*az*bz+az*ay*by+ax],[ax*bx*by+by,bx,ax*ay*bx*by+ax*bx+ay*by+1]])
# pixels=np.zeros((r1,r2,r3))
print(cat)
#3D Cat是满射吗,二维Arnold是满射,如果不是就会出问题??
pixels=np.array(bin_pixels)
for i in range(r1):
for j in range(r2):
for k in range(r3):
posx=(X[i]*(1+az*az*by)+Y[j]*az+Z[k]*(ay+ax*az+ax*ay*az*by))%r1
posy=(X[i]*(bz+az*by+ax*az*by*bz)+Y[j]*(az*bz+1)+Z[k]*(ay*az+az*ay*by*bz+ax*az*bz+az*ay*by+ax))%r2
posz=(X[i]*(ax*bx*by+by)+Y[j]*bx+Z[k]*(ax*ay*bx*by+ax*bx+ay*by+1))%r3

pixels[i][j][k]=bin_pixels[posx][posy][posz]

#三维比特矩阵转三维RGB像素值
for i in range(r1):
for j in range(r2):
B=bit2pixel(pixels[i][j][:8])
G=bit2pixel(pixels[i][j][8:16])
R=bit2pixel(pixels[i][j][16:])
im[i][j]=np.array([B,G,R])
#扁平化为一维
pm=im.flatten(order='C')

#扩散阶段
#逻辑映射初始条件
keyd1=key[3]
keyd2=key[4]
#tmp2参数
keyd3=key[5]
tmp2=int(3.99999*keyd3*(1-keyd3)*1000)%256
rs1=Logistic(keyd1,w*h*3+2000)
rs2=Logistic(keyd2,w*h*3+2000)
rdm1=np.zeros(w*h*3,dtype=np.uint8)
rdm2=np.zeros(w*h*3,dtype=np.uint8)
for i in range(w*h*3):
rdm1[i]=int(rs1[2000+i]*(10**9))%256
rdm2[i]=int(rs2[2000+i]*(10**9))%256

for i in range(w*h*3):
tmp1=rdm1[tmp2]
pm[i]=pm[i]^rdm2[tmp1]
tmp2=pm[i]

print('密文',pm[:20])
#重新转成RGB三维图像
img_encrypt=pm.reshape((h,w,dim),order='C')
return img_encrypt[:,:,(2,1,0)]

'''
功能:加密图像解密,加密过程的逆
参数:
输入加密图像路径和密钥参数
返回:
返回解密后的图像(ndarray)
'''
def decrypt(img,key):
im=cv2.imread(img)
h,w,dim=im.shape
r1=h
r2=w
r3=8*dim
#扁平化为一维
pm=im.flatten(order='C')
print('密文:',pm[:20])

#逆扩散阶段
#逻辑映射初始条件
keyd1=key[3]
keyd2=key[4]
#tmp2参数
keyd3=key[5]
tmp2=int(3.99999*keyd3*(1-keyd3)*1000)%256
rs1=Logistic(keyd1,w*h*3+2000)
rs2=Logistic(keyd2,w*h*3+2000)
rdm1=np.zeros(w*h*3,dtype=np.uint8)
rdm2=np.zeros(w*h*3,dtype=np.uint8)
for i in range(w*h*3):
rdm1[i]=int(rs1[2000+i]*(10**9))%256
rdm2[i]=int(rs2[2000+i]*(10**9))%256

for i in range(w*h*3):
tmp1=rdm1[tmp2]
tmp2=pm[i]
pm[i]=pm[i]^rdm2[tmp1]
print(pm[:20])
#重新转成三维
im=pm.reshape((h,w,dim),order='C')

print(im[1][:10])

#三维像素矩阵转成三维比特矩阵
pixels=np.zeros((r1,r2,r3))
for i in range(r1):
for j in range(r2):
pixels[i][j]=np.append(np.append(pixel2bit(im[i][j][0]),pixel2bit(im[i][j][1])),pixel2bit(im[i][j][2]))

print('置乱后的bit矩阵:',pixels[0][0])
#Chen系统控制参数
a=35
b=3
c=28
#初始条件
x0=key[0]
y0=key[1]
z0=key[2]
#迭代次数,舍去前500个暂态值
T=500+r1+r2+r3

xi,yi,zi=Chen(x0,y0,z0,a,b,c,T)
#得到大小分别为r1,r2,r3的三个整数序列
qxi=[]
qyi=[]
qzi=[]
#与65536取模,而不是256是为了扩大序列值空间,兼顾效率的同时增加随机性
for i in xi[-r1:]:
qxi.append(int(i*(10**9))%65536)
for i in yi[-r2:]:
qyi.append(int(i*(10**9))%65536)
for i in zi[-r3:]:
qzi.append(int(i*(10**9))%65536)
X=np.arange(r1)
Y=np.arange(r2)
Z=np.arange(r3)
#根据qxi排序
#打包
dic=list(zip(qxi,X))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
X=list(list(zip(*dic))[1])
#根据qyi排序
dic=list(zip(qyi,Y))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
Y=list(list(zip(*dic))[1])
#根据qzi排序
dic=list(zip(qzi,Z))
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
Z=list(list(zip(*dic))[1])

#逆3D cat映射,这里两种解法,要么求3D cat逆矩阵,要么倒用映射规则,cat逆矩阵难求,采用第二种
ax=int(xi[200]*(10**9))%64
ay=int(yi[200]*(10**9))%64
az=int(zi[200]*(10**9))%64
bx=int(xi[201]*(10**9))%64
by=int(yi[201]*(10**9))%64
bz=int(zi[201]*(10**9))%64
ax=ay=az=bx=by=bz=1
# bin_pixels=np.zeros((r1,r2,r3))
bin_pixels=np.array(pixels)
for i in range(r1):
for j in range(r2):
for k in range(r3):
posx=(X[i]*(1+az*az*by)+Y[j]*az+Z[k]*(ay+ax*az+ax*ay*az*by))%r1
posy=(X[i]*(bz+az*by+ax*az*by*bz)+Y[j]*(az*bz+1)+Z[k]*(ay*az+az*ay*by*bz+ax*az*bz+az*ay*by+ax))%r2
posz=(X[i]*(ax*bx*by+by)+Y[j]*bx+Z[k]*(ax*ay*bx*by+ax*bx+ay*by+1))%r3
bin_pixels[posx][posy][posz]=pixels[i][j][k]

#三维比特矩阵转三维RGB像素值
for i in range(r1):
for j in range(r2):
B=bit2pixel(bin_pixels[i][j][:8])
G=bit2pixel(bin_pixels[i][j][8:16])
R=bit2pixel(bin_pixels[i][j][16:])
im[i][j]=np.array([B,G,R])
print(im[0][:5])

return im[:,:,(2,1,0)]



def main():
#原始图像路径
img_path='./Lena.png'
#Chen系统初始条件
keyc_x0=0.22521231547896
keyc_y0=0.58749654123587
keyc_z0=0.98564123475621
keyd1=0.23465654373432
keyd2=0.34678978310437
keyd3=0.43263498463278

#加密密钥参数列表
key=[]
key.append(keyc_x0)
key.append(keyc_y0)
key.append(keyc_z0)
key.append(keyd1)
key.append(keyd2)
key.append(keyd3)


#原始图像
img=cv2.imread(img_path)[:,:,(2,1,0)]

# 加密图像
img_encrypt=encrypt(img_path,key)
cv2.imwrite('./Lena_encrypt.png',img_encrypt[:,:,(2,1,0)])
encrypt_path='./Lena_encrypt.png'

#正确密钥解密图像
img_decrypt=decrypt(encrypt_path,key)
decrypt_path='./Lena_decrypt.png'
cv2.imwrite(decrypt_path,img_decrypt[:,:,(2,1,0)])

# #错误密钥解密图像
wrong_key=list(key)
wrong_key[2]+=pow(10,-5)
wrong_decrypt=decrypt(encrypt_path,wrong_key)
cv2.imwrite('./wrong_decrypt.png',wrong_decrypt[:,:,(2,1,0)])

#结果展示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文乱码
#子图1,原始图像
plt.subplot(221)
#imshow()对图像进行处理,画出图像,show()进行图像显示
plt.imshow(img)
plt.title('原始图像')
#不显示坐标轴
plt.axis('off')

#子图2,加密后图像
plt.subplot(222)
plt.imshow(img_encrypt)
plt.title('加密图像\nz3={}'.format(key[2]))
plt.axis('off')

#子图3,错误密钥解密结果
plt.subplot(223)
plt.imshow(wrong_decrypt)
plt.title('解密图像\nz3={}'.format(wrong_key[2]))
plt.axis('off')

#子图4,正确密钥解密结果
plt.subplot(224)
plt.imshow(img_decrypt)
plt.title('解密图像\nz3={}'.format(key[2]))
plt.axis('off')

# #设置子图默认的间距
plt.tight_layout()
#显示图像
plt.show()

if __name__ == '__main__':
main()
性能评估
问题
像素矩阵与比特矩阵的转换

目前代码需要优化,这块太慢了。。。

3D Cat 映射???

对于不同的参数,映射好像不是满射,所以有点问题???

Logistic映射

rdm1和rdm2两个随机序列生成时,要丢弃相同的值??这块还需要看看

参考
------------- THE END! THANKS! -------------