图像加密 关于二维Arnold变换,广义Arnold变换和更一般形式变换的练习(Matlab实现)

索引

  Arnold 映射定义如下
( x n + 1 y n + 1 ) = ( 1 1 1 2 ) ( x n y n )     m o d   1 \left( \begin{matrix} { {x}_{n+1}} \\ { {y}_{n+1}} \\ \end{matrix} \right)=\left( \begin{matrix} 1 & 1 \\ 1 & 2 \\ \end{matrix} \right)\left( \begin{matrix} { {x}_{n}} \\ { {y}_{n}} \\ \end{matrix} \right)\text{ }\bmod 1 (xn+1yn+1)=(1112)(xnyn) mod1
Arnold映射效果示意图

1. 将其离散化,应用到图像变换,假设图像大小为 N × N N\times N N×N ( m n ) = ( 1 1 1 2 ) ( i j )     m o d     N , i , j = 0 , 1 , ⋯   , N − 1 \left( \begin{matrix} m \\ n \\\end{matrix} \right)\text{=}\left( \begin{matrix} 1 & 1 \\ 1 & 2 \\\end{matrix} \right)\left( \begin{matrix} i \\ j \\\end{matrix} \right)\text{ }\bmod \text{ }N,i,j=0,1,\cdots ,N-1 (mn)=(1112)(ij) mod N,i,j=0,1,,N1将原始明文图像rice.png中灰度值矩阵 I I I在位置 ( i , j ) (i,j) (i,j)的灰度值变换为新的置乱矩阵 C C C在位置 ( m , n ) (m,n) (m,n)的灰度值,得到一个新的置乱矩阵 C C C,可视化得到的结果。

主程序代码 (Problem_1.m)

% 实现功能:
% 给定一个明文图像I, 对其进行一轮经典的二维Arnold变换得到置乱矩阵J
% 并可视化得到的结果

clear; clc;
I = imread('rice.png');  % 读入图像素材并作为明文图像

% 判断该图像是否符合应用Arnold变换的条件: 图像矩阵是否为方阵
[row, column] = size(I);
if row ~= column
    error('明文图像矩阵不是方阵,无法应用Arnold变换进行加密');
end
N = row;

% 展示明文图像I
figure, imshow(I); title('明文图像I');

% 对明文图像I进行一轮二维Arnold变换加密
J = I;
for i = 0 : N - 1
    for j = 0 : N - 1
        i1 = mod(i + j, N); j1 = mod(i + 2 * j, N);
        J(i1 + 1, j1 + 1) = I(i + 1, j + 1);
    end
end

% 对一轮Arnold加密后得到的密文图像J可视化
figure, imshow(J); title('密文图像C');

结果


明文图像

密文图像

2. 将映射推广为以下的形式(参数 p , q p,q p,q选择为 0 ∼ N − 1 0\sim N-1 0N1之间的整数,可以视作密钥) ( m n ) = ( 1 p q 1 + p q ) ( i j )     m o d   N , i , j = 0 , 1 , ⋯   , N − 1 \left( \begin{matrix} m \\ n \\\end{matrix} \right)=\left( \begin{matrix} 1 & p \\ q & 1+pq \\\end{matrix} \right)\left( \begin{matrix} i \\ j \\\end{matrix} \right)\text{ }\bmod N,i,j=0,1,\cdots ,N-1 (mn)=(1qp1+pq)(ij) modN,i,j=0,1,,N1实现置乱加密,设计一个函数m文件,输入变量为密钥 p , q p,q p,q,置乱轮数 i t e r iter iter,以及明文图像 I I I,输出量为密文图像 C C C,然后在主程序中调用。特别当 p = 13 , q = 129 p\text{=}13,q\text{=}129 p=13,q=129,对明文图像rice.png加密3轮得到密文图像 C C C,显示明文图像和密文图像的直方图,并计算其信息熵。

广义Arnold变换函数代码 (general_arnoldmap.m)

function C = general_arnoldmap( I, p, q, iter )
%% 说明
% 参数意义
% I : 输入的明文图像
% p, q : 构成广义Arnold变换矩阵的密钥
%        广义Arnold变换矩阵的形式为 A = [ 1, p; q, 1 + p * q ];
% iter : 置乱轮数
% C : 输出的密文图像
%
% 功能
%   按照输入的密钥p, q构建广义Arnold变换矩阵A
%   将输入的明文图像I在A的作用下进行iter轮置乱加密得到密文图像C

%% 输入参数检验

% 检验输入的图像I是否符合应用Arnold变换的前提条件: I是否是方阵
[row, column] = size(I);
if row ~= column
    error('输入的明文图像I的矩阵不是方阵, 不适用Arnold变换');
end
N = row;

% 检验参数p, q是否为整数
if floor(p) ~= p
    error('输入的参数p不是一个整数');
end
if floor(q) ~= q
    error('输入的参数q不是一个整数');
end

% 检验输入的置乱轮数iter是否是正整数
if floor(iter) ~= iter || iter < 1
    error('输入的置乱轮数不是一个正整数');
end

%% 函数主体
% 根据输入的p, q构造广义Arnold变换矩阵A
A = [ 1, p; ...
    q, 1 + p * q ];

% 将输入的明文图像I进行iter轮置乱加密
C = I;
for k = 1 : iter
    for i = 0 : N - 1
        for j = 0 : N - 1
            I_pos = [ i; j ];
            C_pos = mod( A * I_pos, N );
            C( C_pos(1) + 1 , C_pos(2) + 1 ) = ...
                I( I_pos(1) + 1, I_pos(2) + 1 );
        end
    end
    disp(['完成了第', num2str(k), '轮加密']);
    I = C;
end
end

主程序代码 (Problem_2.m)

% 目标任务
% 设置密钥p = 13, q = 129, 置乱轮数iter = 3
% 对明文图像I加密3轮得到密文图像C
% 之后显示明文图像和密文图像的直方图, 并计算其信息熵

clear; clc;
p = 13;  q = 129;  iter = 3;  % 初始化参数
I = imread('rice.png');  % 读入明文图像I

C = general_arnoldmap( I, p, q, iter );  % 对I进行广义Arnold变换加密

% 显示明文图像I和密文图像C
figure, imshow(I); title('明文图像I');
figure, imshow(C); title('密文图像C');

% 显示明文图像I和密文图像C的灰度直方图
figure, imhist(I); title('明文图像I的灰度直方图');
figure, imhist(C); title('密文图像C的灰度直方图');
if isequal(imhist(I), imhist(C))
    disp('明文图像和密文图像的灰度直方图是一致的');
else
    disp('明文图像和密文图像的灰度直方图是不一致的');
end

% 计算信息熵
disp(['明文图像I的信息熵为: ', num2str(entropy(I))]);
disp(['密文图像C的信息熵为: ', num2str(entropy(C))]);

作图结果


明文图像I

密文图像C

命令行窗口输出

完成了第1轮加密
完成了第2轮加密
完成了第3轮加密
明文图像和密文图像的灰度直方图是一致的
明文图像I的信息熵为: 7.0115
密文图像C的信息熵为: 7.0115

3. 实现第2题中加密算法的解密算法,同样设计一个函数m文件,输入变量为 p , q p,q p,q,置乱轮数 i t e r iter iter,输出量为密文图像 I I I

广义Arnold逆变换函数代码 (general_arnoldmap_inv1.m) – 逆矩阵法

function I = general_arnoldmap_inv1( C, p, q, iter )
%% 说明
% 参数意义
% C: 输入的待解密的密文图像C
% p, q: 广义Arnold变换涉及的密钥
%       广义Arnold变换矩阵 A = [ 1, p; q, 1 + p * q ];
%       其逆变换矩阵为 A_inv = [ 1 + p * q, -p; -q, 1 ];
% iter: 置乱(解密)轮数
% I: 输出的解密图像I
%
% 功能
%     按照输入的密钥p, q构造广义Arnold变换逆矩阵A_inv
%     将输入的密文图像C进行iter轮解密得到明文图像I

%% 输入参数检验
% 检验输入的密文图像C的图像矩阵是否是方阵
[row, column] = size(C);
if row ~= column
    error('输入的密文图像C的图像矩阵不是方阵,不适用Arnold逆变换');
end
N = row;

% 检验参数p, q是否为整数
if floor(p) ~= p
    error('输入的密钥p不是整数');
end
if floor(q) ~= q
    error('输入的参数q不是整数');
end

% 检验解密轮数iter是否为正整数
if floor(iter) ~= iter || iter < 1
    error('解密轮数iter不是正整数');
end

%% 函数主体
% 构造广义Arnold逆变换矩阵
A_inv = [ 1 + p * q, -p; ...
            -q, 1 ];

% 对密文图像C进行解密得到I
I = C;
for k = 1 : iter
    for i = 0 : N - 1
        for j = 0 : N - 1
            C_pos = [ i ; j ];
            I_pos = mod(A_inv * C_pos, N);
            I( I_pos(1) + 1, I_pos(2) + 1 ) = ...
                C( C_pos(1) + 1, C_pos(2) + 1 );
        end
    end
    disp(['完成了第', num2str(k), '轮解密']);
    C = I;
end

end

广义Arnold逆变换函数代码 (general_arnoldmap_inv2.m) – 回溯法

function I = general_arnoldmap_inv2( C, p, q, iter )
%% 说明
% 参数意义
% C: 输入的待解密的密文图像C
% p, q: 广义Arnold变换涉及的密钥
%       广义Arnold变换矩阵 A = [ 1, p; q, 1 + p * q ];
% iter: 置乱(解密)轮数
% I: 输出的解密图像I
%
% 功能
%     按照输入的密钥p, q构造广义Arnold变换矩阵A
%     将输入的密文图像C进行iter轮回溯得到明文图像I

%% 输入参数检验
% 检验输入的密文图像C的图像矩阵是否是方阵
[row, column] = size(C);
if row ~= column
    error('输入的密文图像C的图像矩阵不是方阵,不适用Arnold逆变换');
end
N = row;

% 检验参数p, q是否为整数
if floor(p) ~= p
    error('输入的密钥p不是整数');
end
if floor(q) ~= q
    error('输入的参数q不是整数');
end

% 检验解密轮数iter是否为正整数
if floor(iter) ~= iter || iter < 1
    error('解密轮数iter不是正整数');
end

%% 函数主体
% 构造广义Arnold变换矩阵
A = [1, p; ...
        q, 1 + p * q];

% 对密文图像C进行解密得到I
I = C;
for k = 1 : iter
    for i = 0 : N - 1
        for j = 0 : N - 1
            I_pos = [ i ; j ];
            C_pos = mod(A * I_pos, N);
            I( I_pos(1) + 1, I_pos(2) + 1 ) = ...
                C( C_pos(1) + 1, C_pos(2) + 1 );
        end
    end
    disp(['已完成第', num2str(k), '轮解密']);
    C = I;
end

end

主程序代码 (Problem_3.m)

% 目标任务
% 设置p = 13, q = 129, iter = 3 
% 对明文图像I0进行广义Arnold变换得到密文图像C
% 再对密文图像C进行广义Arnold逆变换得到明文图像I
% 比较I0与解密得到的I是否一致,有无信息缺损
% 显示I0, C, I的灰度直方图
% 分别其信息熵

clear; clc;
p = 13;  q = 129;  iter = 3;  % 初始化参数
I0 = imread('rice.png');  % 读入图像
C = general_arnoldmap(I0, p, q, iter);  % 广义Arnold变换
I = general_arnoldmap_inv1(C, p, q, iter);  
% I = general_arnoldmap_inv2(C, p, q, iter);  % 广义Arnold逆变换
if isequal(I0, I)
    disp('广义Arnold逆变换解密得到的图像与原明文图像一致');
else
    disp('广义Arnold逆变换解密得到的图像与原明文图像不一致');
end

% 显示图像I0, C, I, 以及相应的灰度直方图
figure, imshow(I0); title('明文图像I0'); 
figure, imhist(I0); title('明文图像I0灰度直方图');
figure, imshow(C); title('密文图像C'); 
figure, imhist(C); title('密文图像C灰度直方图');
figure, imshow(I); title('解密图像I'); 
figure, imhist(I); title('解密图像I灰度直方图');

% 分别计算I0, C, I的信息熵
disp(['原明文图像I0的信息熵为: ', num2str( entropy(I0) )]);
disp(['密文图像C的信息熵为: ', num2str( entropy(C) )]);
disp(['解密得到的图像I的信息熵为: ', num2str( entropy(I) )]);

结果
  明文图像 I 0 I0 I0及其灰度直方图,密文图像 C C C及其灰度直方图同第2题

解密图像I

命令行窗口输出

完成了第1轮加密
完成了第2轮加密
完成了第3轮加密
完成了第1轮解密
完成了第2轮解密
完成了第3轮解密
广义Arnold逆变换解密得到的图像与原明文图像一致
原明文图像I0的信息熵为: 7.0115
密文图像C的信息熵为: 7.0115
解密得到的图像I的信息熵为: 7.0115

4. 将变换推广到更一般的情况: ( m n ) = ( a b c d ) ( i j )     m o d   N , i , j = 0 , 1 , ⋯   , N − 1 \left( \begin{matrix} m \\ n \\\end{matrix} \right)=\left( \begin{matrix} a & b \\ c & d \\\end{matrix} \right)\left( \begin{matrix} i \\ j \\\end{matrix} \right)\text{ }\bmod N,i,j=0,1,\cdots ,N-1 (mn)=(acbd)(ij) modN,i,j=0,1,,N1其中变换矩阵的系数在 0 , 1 , ⋯   , N − 1 0,1,\cdots ,N-1 0,1,,N1中选取,其行列式 a d − b c ad-bc adbc满足与 N N N互质即可实现变换的可逆性。 假设图像大小为 N × N = 256 × 256 N\times N=256\times 256 N×N=256×256,用 ( m n ) = ( 121 10 37 217 ) ( i j )     m o d   N , i , j = 0 , 1 , ⋯   , N − 1 \left( \begin{matrix} m \\ n \\\end{matrix} \right)\text{=}\left( \begin{matrix} 121 & 10 \\ 37 & 217 \\\end{matrix} \right)\left( \begin{matrix} i \\ j \\\end{matrix} \right)\text{ }\bmod N,i,j=0,1,\cdots ,N-1 (mn)=(1213710217)(ij) modN,i,j=0,1,,N1实现rice.png的一轮加密和解密。

一般加密算法函数代码 (general_encryption.m)

function C = general_encryption( I, M, iter )
%% 说明
% 参数意义
% I : 输入的明文图像
% M : 输入的变换矩阵
% iter : 输入的变换轮数
% C : 输出的密文图像
%
% 功能
% 对输入的明文图像I在变换矩阵M的作用下加密iter轮得到密文图像C

%% 检验输入的参数

% 检验输入的明文图像是否是方阵
[row, column] = size(I);
if row ~= column
    error('输入的明文图像不是一个方阵');
end
N = row;

% 检验加密轮数iter是否为正整数
if floor(iter) ~= iter || iter < 1
    error('输入的加密轮数iter不是一个正整数');
end

% 对输入的变换矩阵进行检验
% 检验M是否是 2*2 矩阵
[row, column] = size(M);
if row ~= 2 || column ~= 2
    error('输入的变换矩阵不是2*2的方阵');
end
% 检验M中的四个元素是否均为实整数
if ~isreal(M) || ismember(1, floor(M) ~= M)
    error('输入的变换矩阵存在非实整数的元素');
end
% 检验M的行列式是否与N互素(互素时变换才可逆, 才能进行解密)
if gcd( det(M), N ) ~= 1
    error('输入的变换矩阵对应的置乱变换不可逆');
end

%% 函数主体
C = I;
for k = 1 : iter
    for i = 0 : N - 1
        for j = 0 : N - 1
            I_pos = [ i ; j ];
            C_pos = mod( M * I_pos, N );
            C( C_pos(1) + 1, C_pos(2) + 1 ) = ...
                I( I_pos(1) + 1, I_pos(2) + 1 );
        end
    end
    disp(['已完成第', num2str(k), '轮加密']);
    I = C;
end
end

一般解密算法函数代码 (general_decryption.m)

function I = general_decryption( C, M, iter )
%% 说明
% 参数意义
% C : 输入的密文图像
% M : 输入的加密变换矩阵
% iter : 输入的变换轮数
% I : 输出的明文图像
%
% 功能
% 对输入的密文图像C,根据变换矩阵M的信息,解密iter轮得到结果I

%% 检验输入的参数

% 检验输入的明文图像是否是方阵
[row, column] = size(C);
if row ~= column
    error('输入的密文图像不是一个方阵');
end
N = row;

% 对输入的变换矩阵进行检验
% 检验M是否是 2*2 矩阵
[row, column] = size(M);
if row ~= 2 || column ~= 2
    error('输入的变换矩阵不是2*2的方阵');
end
% 检验M中的四个元素是否均为实整数
if ~isreal(M) || ismember(1, floor(M) ~= M)
    error('输入的变换矩阵存在非实整数的元素');
end
% 检验M的行列式是否与N互素(互素时变换才可逆, 才能进行解密)
if gcd( det(M), N ) ~= 1
    error('输入的变换矩阵对应的加密置乱变换不可逆');
end

%% 函数主体
I = C;
for k = 1 : iter
    for i = 0 : N - 1
        for j = 0 : N - 1
            I_pos = [ i ; j ];
            C_pos = mod( M * I_pos, N );
            I( I_pos(1) + 1, I_pos(2) + 1 ) = ...
                C( C_pos(1) + 1, C_pos(2) + 1 );
        end
    end
    disp(['已完成第', num2str(k), '轮解密']);
    C = I;
end
end

主程序代码 (Problem_4.m)

% 目标任务
% 给定一个变换矩阵M和置乱轮数iter
% 对明文图像I0进行加密得到密文图像C
% 再对密文图像C解密得到I
% 比较I0与I是否一致

clear; clc;
M = [ 121, 10; 37, 217 ];  % 设置变换矩阵
iter = 1;  % 设置置乱轮数
I0 = imread('rice.png');  % 读入图片
C = general_encryption(I0, M, iter);
I = general_decryption(C, M, iter);

% 比对I0与I是否一致
if isequal(I0, I)
    disp('明文图像I0与解密得到的结果I是一致的');
else
    disp('明文图像I0与解密得到的结果I是不一致的');
end

% 展示I0, C, I
figure, imshow(I0); title('明文图像I0');
figure, imshow(C); title('密文图像C');
figure, imshow(I); title('解密图像I');

结果


明文图像I0

密文图像C

解密图像I

命令行窗口输出

已完成第1轮加密
已完成第1轮解密
明文图像I0与解密得到的结果I是一致的

猜你喜欢

转载自blog.csdn.net/qq_44261017/article/details/109729984