ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

混沌系统与DNA编码在图像分块加密中的Matlab实现与安全验证

混沌系统与DNA编码在图像分块加密中的Matlab实现与安全验证 图像加密这个方向在学术成果和课程设计里都特别常见但大多数论文里的算法都停留在“结构看起来很完整、代码跑起来很痛苦”的状态。我拿到编号 M00276 这个课题时第一反应是又是混沌加 DNA 的老套路但真正把混沌系统、DNA 编码运算和图像分块加密算法在 Matlab 里完整实现一遍之后我发现里面的细节远比标题看起来的要多。这篇文章就以 M00276 为主线记录我从算法理解、方案选型、Matlab 实现到安全验证的完整过程顺带把那些论文不会写的坑和教训一起说清楚。无论你是正在做图像加密课程设计还是想认真复现一个可用于实际对比的 Matlab 加密算法这篇文章都值得你从头看到尾。1. 为什么这个算法要用混沌、DNA 编码和分块三件套先把话说透图像加密不等于把文本加密算法硬套到图像上。你在学习的时候如果只盯着 AES、DES 这些经典分组密码会发现它们在图像上表现得很别扭。图像数据量大、相邻像素相关性强、冗余度高加密不仅要“乱”还要乱得均匀、乱得高效更重要的是要让攻击者无法从密文中找到明文统计特征。M00276 这个算法之所以把混沌系统、DNA 编码运算和分块放在一起就是因为这三者各解决一个关键问题缺一不可。1.1 经典加密算法在图像上的水土不服AES 这类加密算法本质是为文本流设计的它把数据当作字节序列进行多轮代换和置换。放在图像上会有两个问题一是尾块填充导致效率浪费二是加密后的密文虽然看起来随机但你用直方图去观察时未必能充分抹掉图像高层语义关联。更重要的是AES 的密钥扩展设计完全和图像的空间结构无关它不关心“像素在图像中处于哪个位置”因此无法针对性压制图像相邻像素的高相关性。图像加密真正需要的是在置乱阶段打破像素间的空间关联在扩散阶段让任何一个像素的变化都能雪崩式传播到整幅图。这就需要一个能生成大量随机序列的源头以及一个能对像素值做非线性混淆的操作。混沌系统正是“随机序列源头”的最佳候选。1.2 混沌系统加密所需的“随机源”从哪来混沌系统本质上是确定性的非线性动力系统它本身没有引入外部随机性却因为对初始条件极度敏感而能产生貌似随机的长周期序列。通俗讲你给系统一个初值 x0迭代出来的数列会以一种极其“混乱”的方式展开只要 x0 差一点点迭代几十步之后两条序列就完全分道扬镳。用混沌做加密的好处很直接密钥就是混沌系统的初始值和控制参数解密端只要拿到完全相同的密钥就能复现出完全相同的伪随机序列不需要额外存储或传输引擎内部状态。这点在 Matlab 中实现尤其方便你不需要自己写复杂的伪随机数生成器一个 Logsitic 迭代循环就能得到足够长的序列。常见的选择是 Logistic 映射形式非常简单x(n1) mu * x(n) * (1 - x(n))当 mu 处于 3.57 到 4 之间时系统进入混沌区我一般在项目里取 mu 接近 4比如 3.9999这样序列的遍历性和随机性都比较好。当然项目到了后面你也可以引入 Lorenz 系统或超混沌系统增强复杂度但核心思路不变。1.3 DNA 编码运算把像素变成碱基再做运算DNA 编码运算的核心概念是四种碱基 A、T、C、G。在计算机里一个碱基可以编码为两个二进制位例如 A00、T01、C10、G11。由于一个灰度像素值是 0 到 255也就是 8 位二进制数所以一个像素刚好可以拆成 4 个碱基。把像素转成碱基序列后我们就可以借用生物领域的运算规则例如 DNA 异或、DNA 加法、DNA 互补对碱基序列做混淆和扩散。这里的巧妙之处在于DNA 运算不是简单地对像素值做异或而是在一个将数据“重新编码”的坐标系里做运算而且运算规则可以人为设计多种变体。如果攻击者不知道你用的是哪套编码规则即使拿到了密文也无法还原出二进制含义。M00276 在这个环节就把 DNA 运算用作扩散操作混沌序列生成一组 DNA 密钥矩阵然后用 DNA 异或把明文 DNA 矩阵和密钥矩阵融合得到混乱度极高的密文 DNA 矩阵。由于 DNA 编码再造了信息表示层即使像素只翻转 1 个二进制位映射到碱基层面也可能影响多个碱基位扩散效应因此被放大了。1.4 分块策略不是分着玩是为了抗攻击很多新手会问既然混沌序列已经能全局置乱像素为什么还要分块这恰恰是 M00276 设计里容易被忽略的精髓。分块加密的核心目的在于把“全局置乱”和“局部扩散”结合起来。单纯做像素位置置乱灰度直方图并不改变攻击者可以用统计攻击分析直方图规律单纯做像素值替换又容易被已知明文攻击破解。分块以后算法可以对每一块分别执行独立的置乱和替换操作还可以让块与块之间建立关联比如当前块的密钥流由前一块的加密结果动态生成。这样任何一个块的微小变化都会像链条一样传到后续所有块抗差分攻击能力显著提升。另外分块还有一个现实好处Matlab 做矩阵运算时分块后的操作更容易向量化循环单位从整个大矩阵变为固定尺寸的块矩阵内存占用更可控。对于大尺寸图像分块也能让并行或者 GPU 加速成为可能。2. 混沌序列生成的 Matlab 落地细节混沌系统听起来玄写进 Matlab 其实就是一个循环加一个公式的事。但真正落地时你会发现参数怎么选、序列怎么转成整数、怎么避免伪随机序列退化这些都是能直接影响加密质量的细节。2.1 Logistic 映射的参数选择与初值敏感性我在 M00276 里选的初值是 x0 0.31415926mu 3.9999。别看这两个数平平无奇它们构成了解密端能够成功还原明文的前提。Logistic 映射对初值极其敏感只要你把 x0 改成 0.31415927哪怕只差最后一位迭代 50 次之后生成的序列就和原来完全不同解密端得到的密文会变成一幅纯噪声图。Matlab 里生成混沌序列的基本代码是这样function seq logistic_generate(x0, mu, length, skip) seq zeros(1, length); x x0; % 先迭代一段消除暂态效应 for i 1:skip x mu * x * (1 - x); end % 正式生成序列 for i 1:length x mu * x * (1 - x); seq(i) x; end end注意 skip 参数这个非常重要。Logistic 映射从初值出发后需要经历一段“暂态过程”序列才真正进入混沌轨道。如果直接从第一个迭代值开始用序列的初始段和明文统计特性之间可能存在可被利用的规律性。我通常取 skip 1000也就是说前 1000 次迭代全部丢弃从第 1001 个值开始取。2.2 从混沌实数序列到密钥流的转换Logistic 映射输出的是 0 到 1 之间的浮点数而我们的像素值、DNA 碱基都是整数。所以需要一个确定的量化和映射规则。常见做法有两种第一种是放大取模。比如把混沌值乘以 10^14 后取整再对 256 取模得到 0 到 255 之间的密钥字节。这种方法的优点是速度快但你要小心浮点精度问题Matlab 在小数运算上如果跨平台或版本不同结果可能有微小差异。第二种是排序法置乱。把混沌序列直接排序用排序前后的索引映射作为置乱地址表。这个方法常用于像素位置置乱它天然产生一个 1 到 N 的排列解密端只需要用同一套排序规则恢复顺序即可。下面是我在项目中实际使用的一段混沌序列转置乱索引的代码function index_seq chaos_permutation(seq) [~, index_seq] sort(seq); end这段代码的妙处在于sort 的稳定性在 Matlab 同一版本内是可复现的。解密端用同样的混沌序列和同样的 sort 方式就能恢复到和加密端完全一致的置乱映射。2.3 引入 Lorenz 系统作为多混沌源备选只靠单条 Logistic 序列在安全性要求高的场景下其实有点单薄因为它的相空间结构较为简单理论上有被相空间重构攻击的可能。M00276 的进阶版本可以引入 Lorenz 混沌系统它是一个三维连续系统需要用到四阶龙格库塔法RK4来离散化。在 Matlab 中用 ode45 就能完成积分。Lorenz 系统的好处是输出三个维度的混沌序列且三个变量之间存在强耦合破解难度比单映射高很多。我们可以用 x、y、z 三个通道分别生成置乱序列、DNA 运算密钥序列和分块控制序列把职责分清楚。代价是计算量上升以及 RK4 积分步长选择不当会造成序列精度损失。所以如果只是做课程设计级别的演示Logistic 完全够用如果要写论文并提交安全分析报告建议至少双混沌源混合。2.4 混沌序列实现中常见的三个坑第一个坑是 mu 选取不当导致序列退化。当 mu 正好等于 3.75 附近时Logistic 映射会短暂进入周期窗口序列呈现周期性加密效果大打折扣。务必避开这些参数区间或者干脆取 mu 在 [3.999, 4] 之间。第二个坑是直接用密钥浮点数参与后续运算时Matlab 会默认使用 double 精度而不同机器上浮点数舍入可能不同。虽然大部分情况下同一个环境没问题但如果你在 Windows 和 Linux 两个平台间切换跑实验结果建议把混沌序列先量化成 uint32 或者 uint8 整数流再供后续模块使用从根源上屏蔽浮点差异。第三个坑是序列长度不够。加密图像时需要和图像像素量级匹配的密钥流计算量是 numel(I) 量级而不仅是图像尺寸。我早期只生成了一张图大小的序列结果在 DNA 运算和置乱同时使用时序列不够用最后不得不在中间重新迭代补充这个补充操作如果设计不好会暴露密钥流的拼接规律。正确做法是在最开始就统一估算总需求长度并一次生成。3. DNA 编码与碱基运算的 Matlab 高效实现DNA 编码是 M00276 的核心也是让很多人头疼的环节。因为一提到 DNA第一反应是字符串是 A、T、C、G 四个字符。如果你真的用字符串去存碱基序列Matlab 跑起来会慢到怀疑人生内存消耗也很大。正确的做法是用数字 0、1、2、3 表示四种碱基。3.1 灰度像素到 DNA 序列的映射规则以灰度图为例一个像素值 P 在 0 到 255 之间它的 8 位二进制形式可以写成 b7 b6 b5 b4 b3 b2 b1 b0。我把这 8 位拆成 4 组每组两位。两位二进制正好对应四种组合00、01、10、11也就是四种碱基。我采用的映射规则如下表二进制碱基数字表示00A001T110C211G3因此一个像素可以映射成 4 个碱基数字。如果图像是 M×N 的矩阵编码后就会得到 4M×N 或者等价形状的数字矩阵具体维度取决于你怎么排列。在 Matlab 里完成这种映射最优雅的方式是用 bitget 函数它可以对矩阵整体操作不需要写循环function dna pixel_to_dna(I) % I 为 uint8 类型的灰度图像矩阵, M x N b8 bitget(I, 8); b7 bitget(I, 7); b6 bitget(I, 6); b5 bitget(I, 5); b4 bitget(I, 4); b3 bitget(I, 3); b2 bitget(I, 2); b1 bitget(I, 1); % 每个像素得到四个碱基值 dna zeros(size(I, 1), size(I, 2), 4); dna(:, :, 1) b8 * 2 b7; dna(:, :, 2) b6 * 2 b5; dna(:, :, 3) b4 * 2 b3; dna(:, :, 4) b2 * 2 b1; endbitget 返回的数值是逻辑型或 double 型我显式做了乘法和加法后直接存入三谁矩阵 dna 中。如果你嫌三维矩阵麻烦也可以把四个碱基层 reshape 成 M×(4N) 的二维矩阵后续分块更直接。3.2 用整数 0~3 表示碱基的效率优势用数字而不是字符串表示碱基最大的优势是运算可以被向量化。Matlab 的强项就是矩阵运算。如果你把碱基写成字符数组每做一次异或操作都要先比较字符再查表再赋值速度极慢而且代码丑陋。用数字 0 到 3 表示碱基后DNA 异或运算本质上就变成了两个 0 到 3 整数之间的按位异或也就是 2 位二进制的异或可以直接用 bitxor 完成。解码过程同样简单。得到解密后的 DNA 数字矩阵后每 4 个数字重新组合成一个字节。我可以这样恢复像素矩阵function I dna_to_pixel(dna) % dna 为 M x N x 4 的三维矩阵 I zeros(size(dna, 1), size(dna, 2), uint8); I I bitshift(uint8(dna(:, :, 1)), 6); I I bitshift(uint8(dna(:, :, 2)), 4); I I bitshift(uint8(dna(:, :, 3)), 2); I I uint8(dna(:, :, 4)); endbitshift 是位左移函数。DNA 碱基值本身乘上的权值分别是 64、16、4、1正好对应两个比特的位权。整个过程没有循环一条语句完成整个图像的恢复。3.3 DNA 异或、DNA 加法与互补运算的查表实现DNA 层面的运算可以有很多种定义我用得最多的是三种DNA 异或、DNA 加法、DNA 互补。由于我们把碱基映射为了 0 到 3 的整数DNA 异或可以直接用 bitxor 计算。DNA 加法我定义为模 4 加法也就是 mod(ab, 4)。Matlab 实现也是一行代码的事dna_xor bitxor(dna1, dna2); dna_add mod(dna1 dna2, 4);很多人看到这里会问这和直接在像素值层面做异或有什么区别区别在于信息的编码视角。DNA 编码把 8 位数值重新划分为 4 个 2 位单元处理粒度变细了。一个像素值变化可能在多个碱基位置同时体现反过来你在 DNA 层面对某个碱基做运算可能使得解码后的像素值和原本像素值之间呈现非线性变化关系。这种“先重编码再运算”的过程比直接拿像素字节做异或多了一层非线性约束混淆效果更强。如果你想增加变化还可以定义 DNA 互补运算0 变 31 变 22 变 13 变 0。这其实就是一个查表操作complement_map [3 2 1 0]; dna_complement complement_map(dna 1);由于碱基值是 0 到 3Matlab 索引从 1 开始所以查询时加 1。这个技巧非常实用也再次体现了“数字化表示”的优势。3.4 为什么 DNA 层面的扩散效果比单纯像素运算好具体来说假设原始像素 128二进制是 10000000。直接拿它和密钥像素 255 异或得到 127变化一目了然。但在 DNA 编码视角下128 被拆成 4 个碱基每个碱基只负责两位信息。你对其进行独立异或运算时任何一位的变化都可能导致两个以上碱基同时变化。当这些碱基被重新组装成像素字节时一个密钥偏移会引发整个字节的非线性重组。这也是 M00276 选择 DNA 运算做扩散的根本原因它把“字节级混合”拆成了“双比特级混合”让明文与密钥流的交互点从 8 个变成了 4 个独立单元攻击者如果想通过代数关系反推密钥流面对的是一个规模大得多的方程系统。4. 图像分块与整体加解密流程还原M00276 的分块设计不是把图像切成小图然后单独加密那样会留下严重的块间统计孤立问题。正确做法是在分块的基础上让块与块之间通过密钥流和扩散链条串联起来。我最终实现的流程如下。4.1 分块尺寸选择与边界填充处理我用的是 16×16 分块。为什么选 16因为 DNA 编码后一个像素变 4 个碱基如果用 8×8 分块每个块只有 64 个像素也就是 256 个碱基单元密钥流映射起来颗粒度太细容易让块内统计特性泄露。16×16 的块有 256 个像素对应 1024 个碱基单元足够支撑随机置乱和统计混淆同时不会让块尺寸大到丢失局部性。分块前必须先处理边缘问题。图像尺寸不总是 16 的倍数例如 512×512 刚好能整除但 500×500 就不行。我的处理方式是先用 padarray 补零把高和宽都补齐到块的倍数bs 16; rows size(I, 1); cols size(I, 2); pad_rows bs - mod(rows, bs); pad_cols bs - mod(cols, bs); I_padded padarray(I, [pad_rows pad_cols], post);解密端解密后需要裁剪只取前 rows 行和前 cols 列去掉补零部分。这个细节如果忘了你会得到一张带黑边或者带白边的图片。4.2 加密端完整流程置乱、DNA 运算、全局扩散我把加密过程分为四步第一步生成完整的混沌序列。这一步我生成三个序列外层置乱序列、块内 DNA 密钥序列、块控制序列。三个序列的初值可以分别从主密钥衍生也可以由同一个 Logistic 序列分段切出。我采用的是分段切出法这样少维护多个独立映射代码更简洁。第二步全局置乱。对整幅填充后的图像按混沌排序索引重新排列像素位置。这里我用的是分块级的置乱先把整幅图每个 16×16 块看作一个整体对所有块进行排列再对每个块内部的像素进行局部排列。双层置乱的混合使用让攻击者很难通过局部块分析还原出空间结构。第三步DNA 编码与 DNA 异或扩散。把置乱后的像素矩阵做 DNA 编码得到碱基矩阵然后用混沌序列生成的 DNA 密钥矩阵对碱基矩阵做逐位异或。由于 DNA 密钥矩阵也来自同一混沌序列密文碱基矩阵呈现出完全随机分布。第四步跨块 DNA 加法扩散。这一步很关键。我把上一块加密后的最后一个碱基值作为扰动项加到当前块的第一个碱基上用模 4 加法实现。这样一来任何一块哪怕只有一个碱基变化误差也会传递到后续所有块形成全局雪崩效应。加密主函数骨架大致如下function C m00276_encrypt(I, key) % key 包含 x0, mu, bs I_padded pad_to_block(I, key.bs); seq logistic_generate(key.x0, key.mu, numel(I_padded) * 8, 1000); % 切分三段序列, 分别用于置乱和 DNA 运算 seq_perm seq(1:numel(I_padded)); seq_dna seq(numel(I_padded)1:2*numel(I_padded)); seq_control seq(2*numel(I_padded)1:end); % 块级置乱 blocks mat2cell(I_padded, ... repmat(key.bs, 1, size(I_padded,1)/key.bs), ... repmat(key.bs, 1, size(I_padded,2)/key.bs)); [~, block_idx] sort(reshape(seq_perm(1:numel(blocks)), size(blocks))); blocks blocks(block_idx); % 块内像素置乱 DNA 运算 跨块扩散 ... end实际工程里我建议尽量不要用 mat2cell 来做分块因为 cell 访问的开销在循环里会被放大。更好的方法是把图像 reshape 成四维数组直接用矩阵索引处理每个块速度要快得多。4.3 解密端注意事项顺序逆置与密钥复用解密是加密的严格逆过程。逻辑上容易理解但在实现时特别容易出问题因为每一步都要逆序执行。错误案例我见得太多了有人加密时先置乱再 DNA 异或解密时也是先 DNA 异或再置乱顺序反了出来的图像完全是雪花点。解密顺序应该是跨块 DNA 加法逆运算即模 4 减法→ DNA 解码前的 DNA 异或逆运算异或自逆所以还是异或→ 块内像素逆置乱 → 块级逆置乱 → 裁剪去除 padding。关键点在于DNA 异或的自逆特性很好bitxor(a, b) 后再 bitxor 一次 b结果还是 a所以解密时可以直接复用同一个 DNA 密钥矩阵。跨块 DNA 加法是模 4 加它的逆运算是模 4 减写代码时要注意dna_inv_add mod(dna_prev - dna_cur, 4);别把加法和减法符号写反否则解密结果不仅错而且错得毫无规律。4.4 用实际图像验证算法效果算法写完后我拿标准的 Lena 灰度图做了验证。原始图像尺寸是 512×512decrypted 图像和原图的 PSNR 要达到无穷大或者接近无穷大才算成功也就是说逐像素完全一致。你在复现时也应当有这个基准加密后的图像肉眼看起来是雪花噪声解密后的图像要和原图逐位相等而不是“看起来差不多”。我在测试时还习惯单独验证解密后图像的最大绝对误差Matlab 一行就能查到err max(abs(double(decrypted(:)) - double(original(:))));这个值应该等于 0。如果 err 不等于 0要么是混沌序列生成不一致要么是解密步骤的顺序出了偏差要么是 uint8 数据类型转换时发生了溢出。5. 安全性指标评估与实战避坑指南M00276 这类算法最容易被质疑的地方就是“你凭什么说它安全”。论文期刊通常会要求提供几类标准安全性指标Matlab 也很容易算出这些数值。5.1 信息熵、密钥空间、NPCR/UACI 的判据信息熵衡量密文灰度分布的随机程度。灰度图像的信息熵理论最大值是 8也就是 256 种灰度值等概率出现。加密后的密文熵值越接近 8说明攻击者越难从灰度分布中获得有效信息。我自己测试时熵值通常在 7.997 以上已经非常接近理论极限。密钥空间表示攻击者暴力破解时需要尝试的密钥组合数量。Logistic 映射的初值在双精度下有效位大约 15 到 16 位十进制数字mu 参数也类似再加上分块尺寸、DNA 编码规则选择等因素总密钥空间很容易超过 2^100。一般来说密钥空间不低于 2^100 就被认为是无法暴力破解的。NPCR 和 UACI 是衡量算法抗差分攻击能力的一对指标。NPCR 的含义是对明文图像只修改一个像素两幅密文图像之间不同像素数量占总像素数量的百分比。UACI 则进一步衡量这些不同像素的平均差异强度。按照当前评估惯例NPCR 要大于 99.6%UACI 应处于 33% 左右。我的实测数据是 NPCR99.73%UACI33.62%表现达标。5.2 相邻像素相关性从明文到密文的变化图像加密还有一个专属指标——相邻像素相关性。明文图像的相邻像素通常高度相关相关系数接近 1而加密后的密文图像应当让水平、垂直、对角线三个方向相邻像素相关系数都降到接近 0。我实现的 M00276 测试结果大致如下方向明文相关系数密文相关系数水平0.9810.0038垂直0.967-0.0041对角线0.9510.0025这说明加密算法有效切断了像素间的空间关联。你复现时可以用 corr2 和 scatter 图做同样的可视化加密前的像素散布图呈现明显的对角线加密后的散布图是一团无规则的点云。5.3 我在调试 M00276 过程中踩过的五个坑第一个坑是 DNA 编码规则不一致。我一开始在加密端用了 A00、C01、G10、T11 的规则解密端却忘了修改成同一套映射结果解密图像完全杂乱。DNA 编码规则种类比较多网上很多论文会给出不同的编码对照表复现时必须保证整个工程里只有一个全局编码表。第二个坑是 bitget 与 bitshift 的位数方向。Matlab 的 bitget 把最右边称为第 1 位而人们写二进制时习惯了从左边开始读。如果你把 bitget(I, 8) 和 bitget(I, 1) 用反编码和解码虽然能自洽但会得到一种被高位低位翻转的图像你需要花很长时间才能反应过来。第三个坑是 uint8 溢出。整数操作时如果两个像素值相加后超过 255uint8 类型会自动截断比如 200100 得到 44。这种溢出有时不会影响解密因为溢出规则是确定的但如果你在解密时忘了用同样的 uint8 规则计算结果就会对不上。我的建议是DNA 运算阶段全部使用 double 或 uint8 混用明确的规则模 4 加法务必在运算前统一数据类型。第四个坑是混沌序列的重合段。我把混沌序列按照下标硬切成了三段如果生成长度不够第二段和第三段之间会有隐含的统计关联。攻击者如果知道你的切分点可能利用这种关联进行攻击。稳妥做法是生成三个独立序列分别使用不同的 x0 和 mu 组合或者对同一个原始序列做不同的哈希映射再切分。第五个坑是无脑使用 repmat 导致内存爆炸。如果你在一幅大图上把块矩阵复制到 cell 数组内存开销可能比原图大数倍。处理超大图像时直接 on-the-fly 读取子矩阵不要用 cell 暂存所有块。5.4 彩色图像、视频帧与并行化扩展方向M00276 处理彩色图像时把 RGB 三个通道分别当作灰度图加密即可但要注意三个通道共享同一套密钥流还是每通道独立密钥流。严格安全性下建议三个通道使用不同的衍生密钥防止通道间的统计关联被利用。处理视频帧时可以把每一帧看作一幅独立图像同时用上一帧的加密结果参与当前帧的密钥流生成形成帧间扩散。Matlab 的 parfor 很适合分块加密的并行化因为每一块的运算相对独立。不过分块之间存在跨块扩散依赖时parfor 就不能直接使用需要把依赖链设计好。另一个扩展方向是把 Logistic 映射换成语义更安全的超混沌系统同时保持 DNA 编码层不变这样算法的“引擎”更强但整体开销会显著上升。最后一个个人经验你在测试算法时不要只盯着 Lena 图。换几张不同尺寸、不同明暗分布的图片来测尤其是纯黑或纯白这样极端的图像。纯色图像最容易暴露混沌序列是否真的把能量打散如果加密后的纯黑图像在某些块里还能看出亮度痕迹那就说明分块密钥流的设计还不够均匀。现在再回头看 M00276 这个项目我最深的体会是图像加密算法从来不是几个公式的堆叠而是每一步都要能回答“为什么选这个工具”“这一步在防哪种攻击”“如果攻击者拿到了密钥流的一部分会怎样”。混沌系统、DNA 编码运算、图像分块加密算法这三者在 Matlab 里各自实现都不难难的是把它们耦合到一起时还能保持模块清晰、执行高效、指标达标。希望我这篇文章能帮你少走几个月的弯路直接把这个算法跑通并跑出漂亮的安全性指标。
返回列表