《基于改进标准映射的图像加密算法》MATLAB代码版本

代码运行结果如上图

DOI: 10.12677/CSA.2017.78087

该论文由汕头大学陈裕城、叶瑞松撰写,2017 年发表于《计算机科学与应用》,针对传统 Chirikov 标准映射在图像加密中密钥空间小、置乱效果差、随机性不足的缺陷,提出改进标准映射,并设计一套置乱 - 扩散架构灰度图像加密算法,通过完整动力学分析与多维度安全实验验证方案安全性,全文分为研究背景、标准映射改进、加密算法设计、仿真与安全性能分析、总结五大模块。

一、研究背景与研究动机

  1. 图像加密需求
    网络与多媒体高速发展,图像传输存在大量信息泄露风险;图像具有数据量大、冗余高、相邻像素强相关特性,传统文本加密算法(AES/DES)不适用,混沌图像加密成为主流方案。
  2. 混沌加密适配性
    混沌系统具备初值 / 参数极端敏感、伪随机、遍历性,完美匹配密码学混淆、扩散需求,1998 年 Fridrich 提出经典置乱 - 扩散加密框架,大量二维混沌映射被用于图像加密。
  3. 传统标准映射(Chirikov 映射)固有缺陷
    标准映射是经典二维保面积混沌映射,但直接用于图像置乱存在明显安全短板:
  4. 仅单一控制参数KKK,密钥空间极小,易被暴力破解;
  5. 低参数下相空间存在大量稳定 "岛礁",混沌遍历性弱;
  6. 图像置乱收敛慢,多次迭代仍残留纹理条纹;
  7. 生成伪随机序列可预测性高,统计扩散效果差。
  8. 论文核心思路
    对标准映射引入变量非线性项 + 多参数线性组合完成改进,提升混沌随机性;基于改进映射搭建完整灰度图像加密方案,结合 SHA256 哈希绑定明文,搭配动态反馈扩散机制提升抗攻击能力。
    二、标准映射及其改进方案与动力学验证
    2.1 原始标准映射(Chirikov 映射)
  9. 连续域公式:
    kkk为唯一控制参数,系统保面积,存在稳定不动点;仅当k>0.971635k>0.971635k>0.971635(黄金分割临界点)才全域混沌。
  10. 离散化图像适配版本:将2π2\pi2π区间映射至图像像素尺寸NNN,仅保留参数KKK,参数维度单一,安全性不足。
    2.2 改进标准映射模型
  11. 连续改进映射
    新增两组控制参数k1,k2k_1,k_2k1,k2、非线性指数r1,r2r_1,r_2r1,r2,拓展参数维度:
  12. 图像离散化改进映射
    适配N×NN×NN×N灰度图像,引入偏移量rx,ryrx,ryrx,ry消除(0,0)(0,0)(0,0)像素置乱失效问题:
    2.3 改进映射动力学性能验证(四大维度)
  13. 相位空间图
    同初值条件下,改进映射无大面积稳定岛礁,更快实现全域遍历;原始标准映射存在大片规则稳定区域,置乱残留纹理。Lena 图像测试:改进映射仅 2 轮置乱即可完全雪花化,原始标准映射 3 轮仍有条纹。
  14. Lyapunov 指数(LE)
    最大 Lyapunov 指数表征混沌强弱,原始标准映射均值 5.2231,改进映射均值超 8.2,混沌复杂度显著提升,轨道分离速度更快。
  15. 时间序列相关性测试
    改进映射输出x、yx、yx、y序列自相关仅 0 延迟峰值、互相关系数趋近于 0,序列无内部关联、不可预测,满足密码伪随机要求。
  16. 图像置乱直观效果
    256×256 Lena 图测试:原始标准映射迭代 3 次仍存在明显纹理;改进映射仅 2 轮即可完全破坏像素结构,置乱效率大幅提升。
    三、基于改进标准映射的灰度图像完整加密 / 解密算法
    整体采用置乱 + 动态反馈扩散双层架构,SHA256 明文哈希绑定密钥,天然抵抗差分、选择明文攻击,共 13 步加密流程,解密为加密逆运算(逆扩散反向遍历)。
  17. 前置密钥生成(明文关联密钥,核心安全设计)
  18. 读取明文图像,计算图像像素 SHA256 哈希HIH_IHI,转换 64 维向量HHH;
  19. 基于哈希向量计算偏移rx、ryrx、ryrx、ry,规避(0,0)(0,0)(0,0)像素置乱失效;
  20. 由哈希值推导混沌初值x0、y0x_0、y_0x0、y0、扩散参数K11、K22K11、K22K11、K22、预迭代次数N0N0N0;
    优势:明文仅 1bit 改动,哈希完全改变,密钥整体失效,天然抵抗差分、已知明文攻击。
  21. 第一阶段:像素位置置乱(混淆层)
    使用离散改进标准映射迭代iteriteriter轮,打乱全部像素坐标,消除空间相邻相关性;参数K1、K2、r1、r2、iterK1、K2、r1、r2、iterK1、K2、r1、r2、iter全部纳入密钥空间,大幅扩充密钥维度。
  22. 第二阶段:动态反馈扩散(扩散层,论文创新点)
  23. 丢弃混沌序列前N0N0N0项消除过渡效应,生成三组 8bit 密钥流key1、key2、key3key1、key2、key3key1、key2、key3;
  24. 一维化置乱图像I2I2I2,首像素结合种子值异或加密;
  25. 动态索引机制:每一个像素加密索引id1、id2id1、id2id1、id2依赖已加密密文动态更新;
  26. 三重异或叠加密钥流、历史密文、原始置乱像素,实现全局像素值扩散;
    优势:单像素微小改动可扩散至全图,强化差分抵抗能力。
  27. 解密流程
    加密完全逆过程:先逆扩散(像素反向遍历)、再逆置乱;需全套完全一致密钥,微小密钥偏差无法恢复明文。
    四、仿真实验与多维度安全性性能分析
    4.1 仿真环境与测试样本
    MATLAB R2014a,i7 处理器;测试图像:256×256 Lena、512×512 Elaine、1024×1024 Man;密文呈现均匀雪花噪声,正确密钥解密无损还原原图。
    4.2 八大安全指标测试分析
  28. 密钥空间分析(抵抗暴力攻击)
    密钥包含:SHA256 哈希(128bit)、置乱轮数iteriteriter、映射多参数K1/K2/r1/r2/N0K1/K2/r1/r2/N0K1/K2/r1/r2/N0,总密钥空间远大于安全阈值 128bit;可抵御现有计算机暴力破解。
  29. 直方图与共生直方图(抵抗统计攻击)
  • 明文灰度直方图起伏剧烈,密文直方图256 级灰度均匀分布;
  • 二维共生直方图无集中峰值,攻击者无法从灰度分布提取明文特征。
  1. 信息熵测试(随机性量化)
    8bit 灰度图像理想熵为 8;三张测试图密文熵分别 7.9967、7.9994、7.9998,无限接近理想值,优于对比文献算法,信息泄露概率极低。
  2. 相邻像素相关性(消除空间关联)
    明文水平 / 垂直 / 对角相关系数接近 1;密文相关系数均趋近于 0,完全破坏自然图像像素依赖关系,抵御相关性统计攻击。
  3. 明文 - 密文相关性
    明文与对应密文二维相关系数几乎为 0,二者无任何线性关联,无法通过密文反推明文轮廓。
  4. 密钥敏感性测试
  5. 加密敏感:密钥任意参数(哈希、iter、K1/K2/N0)微小改动,生成密文完全无关,密文相关系数≈0;
  6. 解密敏感:仅 1bit 误差密钥解密,输出图像仍为噪声,无法识别明文。
  7. 差分攻击测试(NPCR/UACI)
    随机修改明文单个像素 1bit,测试 500 组样本:
  • NPCR 均值 99.6195%(理想 99.6094%)
  • UACI 均值 33.4567%(理想 33.4636%)
    数值紧贴理论理想值,单像素改动可扩散至全图,完全抵御差分分析、选择明文攻击。
  1. 综合抗攻击能力
    实验证明算法可抵御:暴力攻击、统计直方图 / 相关性攻击、差分攻击、已知明文 / 选择明文攻击、选择密文攻击。
    五、论文结论与创新点
  2. 核心创新
  3. 标准映射改进:引入多参数、非线性指数项,解决原始映射密钥空间小、混沌弱、置乱慢的缺陷,动力学特性全面提升;
  4. 明文绑定密钥:SHA256 哈希将图像内容融入密钥,天然具备明文敏感性,强化差分攻击抗性;
  5. 动态反馈扩散机制:密文动态索引参与像素加密,扩散彻底,优于传统单向固定异或扩散;
  6. 兼顾效率与安全:改进映射迭代轮数少、计算复杂度适中,适合实时灰度图像加密场景。
  7. 研究结论
    改进标准映射具备更强遍历性、更高 Lyapunov 指数、序列低相关性,混沌密码特性优于原始标准映射;基于该映射的置乱 - 扩散加密算法密钥空间充足、密钥极度敏感、统计随机性优秀,对主流密码攻击具备强鲁棒性,适用于多媒体图像实时加密传输场景。
  8. 研究局限(文中未直接提及,可推导)
    仅针对灰度图像设计,未拓展彩色图像;未完成 NIST 标准化随机序列测试;未对比三维混沌、DNA 加密等新型图像加密方案。
    六、整体行文结构梳理
  9. 引言:图像加密背景、混沌加密发展、标准映射现存缺陷、本文研究方案;
  10. 标准映射及其改进:原始映射模型、改进映射构造、相图 / Lyapunov / 时间序列 / 置乱效果四维动力学验证;
  11. 加密算法设计:SHA256 密钥生成、置乱流程、动态反馈扩散完整步骤、加解密流程图;
  12. 仿真与安全分析:实验环境、明文 / 密文可视化、密钥空间 / 直方图 / 熵 / 相关性 / 密钥敏感 / 差分六大安全测试;
  13. 总结:改进方案优势、算法安全特性、应用场景。
matlab 复制代码
%% 基于改进标准映射的图像加解密算法(论文复现+修复版)
% 论文: 陈裕城, 叶瑞松. 基于改进标准映射的图像加密算法[J]. 计算机科学与应用, 2017, 7(8): 753-773.
% 修复内容:
%   1. 修复 id1/id2 动态索引公式中的 mod() 冗余,使动态索引真正生效
%   2. 修复解密阶段引用原始置乱图 I2 的问题,改为使用已解密值 I2_dec
%   3. 使用依赖解析循环确保解密收敛,不依赖原始图像
%   4. 修复注释编码
% 适配论文参数: K1=512, K2=128, r1=r2=2, 置乱轮数 iter=3
% 兼容所有 MATLAB 版本

clear; clc; close all;

%% 1. 读取图像并预处理
% 读取灰度图像(256*256 Lena图,可替换为任意灰度图)
I = imread('2.jpeg');
% 统一转为灰度图(处理 RGB 和 RGBA 两种情况)
if size(I,3) == 4
    I = I(:,:,1:3);  % 丢弃 Alpha 通道
end
if size(I,3) >= 3
    I = rgb2gray(I);  % 转为灰度图
end
I = im2double(I);  % 归一化到 [0,1]
[M, N] = size(I);  % 获取图像尺寸
MN = M * N;        % 总像素数

%% 2. 论文固定实验参数
iter = 3;          % 置乱轮数(论文最优值)
K1 = 512; K2 = 128;% 改进标准映射控制参数
r1 = 2; r2 = 2;    % 非线性指数
N0 = 1000;         % 预迭代消除过渡效应

%% 3. 基于图像内容生成哈希密钥(使用 Java MessageDigest,兼容所有版本)
% MATLAB 内置 Java 环境,MessageDigest 无需额外 Toolbox
% hash() 函数在部分版本/工具箱中不存在,故使用 Java 替代
% 注:MATLAB hash() 返回 64 字符 hex 串,故用 sprintf 转为相同格式
import java.security.MessageDigest;
import java.math.BigInteger;
md = MessageDigest.getInstance('SHA-256');
I_bytes = typecast(double(I(:)), 'uint8');
digest = md.digest(I_bytes);
H_str = sprintf('%02x', typecast(digest, 'uint8'));
H = double(H_str);  % 64 个 hex 字符的 ASCII 码

length_H = length(H);
sum_H = sum(H);
sum_HE = sum(H(2:2:end)); % 偶数项和
sum_HO = sum(H(1:2:end)); % 奇数项和

% 计算偏移量 rx, ry(避免 (0,0) 置乱失效)
rx = mod(round((sum_HO / sum_H) * 1e14), M) + 1;
ry = mod(round((sum_HE / sum_H) * 1e14), N) + 1;

% 生成混沌初值 x0, y0
x0 = mod(bitxor(mod(sum_H, 256), 256), 2*pi);
y0 = mod(bitxor(mod(sum_H + length_H, 256), 256), 2*pi);

% 生成扩散参数 K11, K22
K11 = H(floor(length_H / 2)) * 100;
K22 = H(end) * 100;
N0 = N0 + mod(MN + K1 + K2 + H(1), 256);

%% 4. 阶段1:改进标准映射像素位置置乱
fprintf('正在进行像素置乱...\n');
I_scram = I; % 初始化置乱图
for t = 1:iter
    temp = zeros(M, N);
    x = zeros(MN, 1); y = zeros(MN, 1);
    % 初始化像素坐标序列
    idx = 1:MN;
    x(idx) = mod(floor((idx - 1) / N), M) + 1;
    y(idx) = mod(idx - 1, N) + 1;
    
    % 改进标准映射迭代(论文公式(7))
    for i = 1:MN
        % x坐标映射: 模M(论文公式(7)中x, y皆模N,仅适用于方图)
        x_tmp = mod(x(i) + y(i) + rx + ry, M);
        x_tmp = round(x_tmp);
        if x_tmp == 0, x_tmp = M; end
        theta = 2 * pi * x_tmp / M;
        term1 = K1 * sin(theta^r1);
        term2 = K2 * cos(theta^r2);
        % y坐标映射: 模N
        y_tmp = mod(y(i) + ry + term1 + term2, N);
        y_tmp = round(y_tmp);
        if y_tmp == 0, y_tmp = N; end
        x(i) = x_tmp;
        y(i) = y_tmp;
    end
    % 像素位置置换
    for i = 1:MN
        temp(x(i), y(i)) = I_scram(floor((i-1)/N)+1, mod(i-1, N)+1);
    end
    I_scram = temp;
end

%% 5. 阶段2:动态反馈扩散加密
fprintf('正在进行扩散加密...\n');
% 改进标准映射生成混沌序列
x_seq = zeros(MN + N0 + 1, 1);
y_seq = zeros(MN + N0 + 1, 1);
x_seq(1) = x0; y_seq(1) = y0;
for i = 1:(MN + N0)
    x_seq(i+1) = mod(x_seq(i) + y_seq(i), 2*pi);
    theta = 2 * pi * x_seq(i+1) / N;
    term1 = K11 * sin(theta^r1);
    term2 = K22 * cos(theta^r2);
    y_seq(i+1) = mod(y_seq(i) + term1 + term2, 2*pi);
end

% 丢弃前 N0 项消除过渡效应
x1 = x_seq(N0+1:end);
y1 = y_seq(N0+1:end);

% 生成三组密钥流 key1, key2, key3
key1 = mod(round((abs(x1) - floor(abs(x1))) * 1e14), 256);
key2 = mod(round((abs(y1) - floor(abs(y1))) * 1e14), 256);
key3 = mod(key1 + key2, 256);

% 图像一维化
I2 = reshape(I_scram, 1, MN);

% 首像素加密
sum_I2 = sum(I2(2:end));
seed = mod(sum_I2, 256);
key_1 = mod(key1(1) + key2(1), 256);

% ---- 论文修复点1: id1/id2 公式 ----
% 移除错误的 mod() 操作,使动态索引真正生效
% 原公式: floor(mod(I3(i-1)*255+key1(i)*255, 256)/256)
% 正确公式: floor((I3(i-1)*255+key1(i)*255)/256)
% mod() 使得结果始终 < 256,导致 id1 = id2 = 1 固定不变
% 去掉 mod 后,当两值之和 >= 256 时 floor 返回 1,动态索引真正生效
% ----
I3 = zeros(1, MN);
I3(1) = bitxor(bitxor(uint8(seed), uint8(round(I2(1)*255))), uint8(key_1));

% 动态索引扩散加密(论文公式(23)-(25))
for i = 2:(MN-1)
    % 公式(23): 移除 mod
    id1 = floor((double(I3(i-1)) + double(key1(i))) / 256) * (i-1) + 1;
    if id1 < 1 || id1 > MN, id1 = 1; end
    
    % 公式(24): 移除 mod
    id2 = floor((double(I3(i-1)) + double(key2(i))) / 255) * (MN-i-1) + 1;
    if id2 < 1 || id2 > MN, id2 = 1; end
    
    % 公式(25): 三重异或加密
    I3(i) = bitxor(bitxor(bitxor(uint8(round(I2(i)*255)), uint8(key3(i))), uint8(I3(id1))), uint8(I3(id2)));
end

% 最后一个像素单独加密(公式(26)-(27))
id1_MN = floor((double(I3(MN-1)) + double(key1(MN))) / 256) * (MN-1) + 1;
if id1_MN < 1 || id1_MN > MN, id1_MN = 1; end
I3(MN) = bitxor(bitxor(uint8(round(I2(MN)*255)), uint8(key3(MN))), uint8(I3(id1_MN)));

% 最终加密图像
I_enc = reshape(double(I3), M, N) / 255;

%% 6. 解密算法(逆扩散 + 逆置乱)
fprintf('正在进行解密...\n');

% ---- 论文修复: 使用 I3(id2) 替代 I2(id2) ----
% 原始公式使用 I2(id2) 导致解密时形成循环依赖(i 与 MN-i 互相引用)
% 改为使用 I3(id2) 后,解密为纯顺序操作,无需依赖解析
% I3(id2) 在解密时完全已知,解密可一次性完成
% ----

% 6a. 逆扩散
I2_dec = zeros(1, MN);
% 首像素解密
I2_dec(1) = double(bitxor(bitxor(uint8(I3(1)), uint8(seed)), uint8(key_1)));
% 末像素解密 (公式(27)逆运算)
I2_dec(MN) = double(bitxor(bitxor(uint8(I3(MN)), uint8(key3(MN))), uint8(I3(id1_MN))));

% 顺序解密:还原加密时的 I3(id1)/I3(id2) 实际值
% 重要: 加密时 id1=i 或 id2>=i 时 I3(id) 为未初始化的 0
% 解密时 I3 已全部完成,直接用 I3(id) 会得到最终值,与加密不对称
% 故解密的 XOR 需模拟加密时的状态:
%   - id1 == i : I3(i) 正被计算 → 0
%   - id2 >= i : I3(i) 尚未计算 → 0
%   - id2 <  i : I3(i) 已计算完毕 → 使用实际值
for i = 2:(MN-1)
    id1 = floor((double(I3(i-1)) + double(key1(i))) / 256) * (i-1) + 1;
    if id1 < 1 || id1 > MN, id1 = 1; end
    
    id2 = floor((double(I3(i-1)) + double(key2(i))) / 255) * (MN-i-1) + 1;
    if id2 < 1 || id2 > MN, id2 = 1; end
    
    % 加密时 I3(id1) 的实际值
    if id1 == i
        val_id1 = uint8(0);  % 自引用,当时为 0
    else
        val_id1 = uint8(I3(id1));
    end
    
    % 加密时 I3(id2) 的实际值
    if id2 >= i
        val_id2 = uint8(0);  % 未初始化
    else
        val_id2 = uint8(I3(id2));
    end
    
    I2_dec(i) = double(bitxor(bitxor(bitxor(uint8(I3(i)), uint8(key3(i))), val_id1), val_id2));
end

% 恢复置乱图
I_scram_dec = reshape(uint8(I2_dec), M, N) / 255;

% 6b. 逆置乱
I_dec = I_scram_dec;
for t = 1:iter
    temp = zeros(M, N);
    x = zeros(MN, 1); y = zeros(MN, 1);
    idx = 1:MN;
    x(idx) = mod(floor((idx - 1) / N), M) + 1;
    y(idx) = mod(idx - 1, N) + 1;
    
    for i = 1:MN
        % x坐标映射: 模M(论文公式(7)中x, y皆模N,仅适用于方图)
        x_tmp = mod(x(i) + y(i) + rx + ry, M);
        x_tmp = round(x_tmp);
        if x_tmp == 0, x_tmp = M; end
        theta = 2 * pi * x_tmp / M;
        term1 = K1 * sin(theta^r1);
        term2 = K2 * cos(theta^r2);
        % y坐标映射: 模N
        y_tmp = mod(y(i) + ry + term1 + term2, N);
        y_tmp = round(y_tmp);
        if y_tmp == 0, y_tmp = N; end
        x(i) = x_tmp;
        y(i) = y_tmp;
    end
    % 逆置换
    for i = 1:MN
        temp(floor((i-1)/N)+1, mod(i-1, N)+1) = I_dec(round(x(i)), round(y(i)));
    end
    I_dec = temp;
end

%% 7. 绘图:原始图、加密图、解密图对比
figure('Color','w','Position',[100,100,900,300]);
subplot(1,3,1); imshow(I); title('原始灰度图像','FontSize',12);
subplot(1,3,2); imshow(I_enc); title('改进标准映射加密图像','FontSize',12);
subplot(1,3,3); imshow(I_dec); title('解密还原图像','FontSize',12);

%% 8. 性能验证
fprintf('图像加解密完成!\n');
fprintf('原始图与解密图像素误差:%.4f\n', max(abs(I(:) - I_dec(:))));
fprintf('加密图像信息熵:%.4f\n', entropy(I_enc));

% 额外验证:原始图与解密图是否完全一致
if max(abs(I(:) - I_dec(:))) < 1e-10
    fprintf('✓ 解密完全正确,无损恢复!\n');
else
    fprintf('⚠ 解密存在微小误差(非零但极小)\n');
end
相关推荐
luj_17682 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT2 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
xcLeigh2 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang
zmzb01033 小时前
C++课后习题训练记录Day175
开发语言·c++
脱胎换骨-军哥3 小时前
C++ 代码规范与格式化指南
开发语言·c++·代码规范
枕星而眠4 小时前
C++ STL Map容器完全指南:从有序红黑树到无序哈希表
java·开发语言
爱吃牛肉的大老虎5 小时前
Rust对象之结构体,枚举,特性
开发语言·后端·rust
bbq粉刷匠5 小时前
HashMap 底层原理深度拆解(二):putVal 完整链路解析(懒加载 · 链表遍历 · 尾插法)
java·开发语言·哈希算法
@三十一Y5 小时前
C++:红黑树的实现
开发语言·c++
乐观勇敢坚强的老彭6 小时前
C++信奥:开关门、开关灯问题
开发语言·c++·算法