基于LSB匹配的隐写术MATLAB实现程序

基于LSB匹配(LSB Matching)的隐写术MATLAB实现程序。LSB匹配(也称为±1隐写)是比传统LSB替换更先进的隐写方法,它能更好地抵抗统计检测。

LSB匹配隐写术原理

LSB替换 vs LSB匹配

方法 原理 优点 缺点
LSB替换 直接修改像素最低位为秘密比特 实现简单,容量大 引入统计可检测性
LSB匹配 随机选择±1调整像素值以匹配秘密比特 统计特性更好,更安全 实现稍复杂

核心思想

  • 当秘密比特 ≠ 像素LSB时,随机选择+1或-1来调整像素值
  • 这保持了像素值的自然分布,难以被统计方法检测

完整MATLAB实现

1. 主程序框架

matlab 复制代码
%% 基于LSB匹配的隐写术 - 完整MATLAB实现
clear; close all; clc;
fprintf('========== LSB匹配隐写术 ==========\n');

%% 1. 参数设置
cover_image_path = 'lena.png';      % 载体图像路径
secret_message = 'MATLAB LSB Matching Steganography - A secure information hiding technique!';  % 秘密信息
output_stego_path = 'stego_lena.png'; % 隐写图像输出路径

% 隐写参数
bits_per_pixel = 1;                  % 每个像素嵌入比特数(通常为1)
use_lsb_matching = true;             % true: LSB匹配, false: 传统LSB替换(用于对比)

%% 2. 载入载体图像
fprintf('载入载体图像...\n');
if exist(cover_image_path, 'file')
    cover_image = imread(cover_image_path);
else
    % 如果没有找到图像,生成一个测试图像
    fprintf('未找到图像文件,生成测试图像...\n');
    cover_image = uint8(randi([0, 255], 256, 256, 3));
    imwrite(cover_image, 'test_cover.png');
    cover_image_path = 'test_cover.png';
end

% 显示图像信息
[height, width, channels] = size(cover_image);
total_pixels = height * width * channels;
fprintf('载体图像: %dx%dx%d, 总像素数: %d\n', height, width, channels, total_pixels);
fprintf('最大嵌入容量: %.2f KB (%.2f bits)\n', total_pixels/8192, total_pixels);

%% 3. 准备秘密信息
fprintf('\n准备秘密信息...\n');
% 将文本转换为比特流
secret_bits = text_to_bits(secret_message);
secret_length = length(secret_bits);

% 添加长度信息和校验位(前32位存储秘密信息长度)
length_bits = dec2bin(secret_length, 32) - '0';
secret_bits_with_header = [length_bits(:)', secret_bits];

% 计算所需像素数
pixels_needed = ceil(length(secret_bits_with_header) / bits_per_pixel);

if pixels_needed > total_pixels
    error('秘密信息太大!需要%d像素,但只有%d像素可用。', pixels_needed, total_pixels);
end

fprintf('秘密信息: "%s"\n', secret_message(1:min(50, length(secret_message))));
if length(secret_message) > 50, fprintf('...\n'); end
fprintf('信息长度: %d 字符, %d 比特\n', length(secret_message), secret_length);
fprintf('带长度头的总比特数: %d\n', length(secret_bits_with_header));
fprintf('所需像素数: %d (%.2f%% 图像容量)\n', pixels_needed, pixels_needed/total_pixels*100);

%% 4. 执行隐写(LSB匹配或传统LSB替换)
fprintf('\n执行隐写嵌入...\n');
if use_lsb_matching
    fprintf('使用LSB匹配方法\n');
    [stego_image, embedding_map] = lsb_matching_embed(cover_image, secret_bits_with_header, bits_per_pixel);
else
    fprintf('使用传统LSB替换方法\n');
    [stego_image, embedding_map] = lsb_replacement_embed(cover_image, secret_bits_with_header, bits_per_pixel);
end

%% 5. 保存隐写图像
imwrite(stego_image, output_stego_path);
fprintf('隐写图像已保存: %s\n', output_stego_path);

%% 6. 从隐写图像提取秘密信息
fprintf('\n提取秘密信息...\n');
extracted_bits_with_header = lsb_extract(stego_image, length(secret_bits_with_header), bits_per_pixel);

% 提取长度信息
extracted_length = bin2dec(char(extracted_bits_with_header(1:32)' + '0'));
fprintf('提取的长度信息: %d 比特\n', extracted_length);

% 提取秘密信息比特
if extracted_length > 0 && extracted_length <= length(extracted_bits_with_header)-32
    extracted_bits = extracted_bits_with_header(33:32+extracted_length);
    extracted_message = bits_to_text(extracted_bits);
    
    fprintf('提取的秘密信息: "%s"\n', extracted_message(1:min(50, length(extracted_message))));
    if length(extracted_message) > 50, fprintf('...\n'); end
    
    % 验证提取是否正确
    if strcmp(secret_message, extracted_message)
        fprintf('✓ 信息提取成功且完全正确!\n');
    else
        fprintf('✗ 信息提取有误!\n');
        fprintf('原始信息长度: %d, 提取信息长度: %d\n', length(secret_message), length(extracted_message));
    end
else
    fprintf('✗ 长度信息无效,提取失败!\n');
end

%% 7. 性能分析与可视化
fprintf('\n========== 性能分析 ==========\n');
analyze_steganography_performance(cover_image, stego_image, secret_bits_with_header, ...
                                  embedding_map, use_lsb_matching);

%% 8. 鲁棒性测试(可选)
fprintf('\n========== 鲁棒性测试 ==========\n');
test_steganography_robustness(cover_image, stego_image, secret_bits_with_header, ...
                             output_stego_path, use_lsb_matching);

fprintf('\nLSB匹配隐写术演示完成!\n');

2. LSB匹配核心嵌入函数

matlab 复制代码
function [stego_image, embedding_map] = lsb_matching_embed(cover_image, secret_bits, bits_per_pixel)
% LSB匹配嵌入算法
% 输入:
%   cover_image: 载体图像 (uint8)
%   secret_bits: 秘密比特流 (逻辑向量)
%   bits_per_pixel: 每个像素嵌入比特数
% 输出:
%   stego_image: 隐写图像 (uint8)
%   embedding_map: 嵌入位置和方式映射

    % 获取图像尺寸
    [height, width, channels] = size(cover_image);
    stego_image = cover_image;  % 初始化隐写图像
    total_pixels = height * width * channels;
    
    % 计算最大嵌入容量
    max_bits = total_pixels * bits_per_pixel;
    if length(secret_bits) > max_bits
        error('秘密信息过长: %d > %d 比特', length(secret_bits), max_bits);
    end
    
    % 初始化嵌入映射(记录每个像素的修改方式)
    % 0: 未修改, 1: LSB匹配+1, -1: LSB匹配-1, 2: LSB替换
    embedding_map = zeros(height, width, channels);
    
    % 将图像展平为一维以便处理
    flat_cover = cover_image(:);
    flat_stego = stego_image(:);
    
    % 生成随机数种子(用于决定±1的随机选择)
    rng(42);  % 固定种子确保可重复性
    
    fprintf('开始LSB匹配嵌入...\n');
    
    % 嵌入每个比特
    for i = 1:length(secret_bits)
        % 计算像素索引
        pixel_idx = ceil(i / bits_per_pixel);
        
        % 获取当前像素值
        pixel_value = flat_cover(pixel_idx);
        
        % 确定要修改的位(对于bits_per_pixel>1的情况)
        bit_position = mod(i-1, bits_per_pixel);
        
        % 提取该位的当前值
        current_bit = bitget(pixel_value, bit_position+1);
        secret_bit = secret_bits(i);
        
        % 如果需要修改
        if current_bit ~= secret_bit
            % LSB匹配核心:随机选择+1或-1
            if rand() < 0.5
                % 尝试+1
                if pixel_value < 255
                    new_value = pixel_value + 1;
                    embedding_type = 1;  % +1修改
                else
                    % 如果已经是255,则只能-1
                    new_value = pixel_value - 1;
                    embedding_type = -1; % -1修改
                end
            else
                % 尝试-1
                if pixel_value > 0
                    new_value = pixel_value - 1;
                    embedding_type = -1; % -1修改
                else
                    % 如果已经是0,则只能+1
                    new_value = pixel_value + 1;
                    embedding_type = 1;  % +1修改
                end
            end
            
            % 检查新值的对应位是否正确
            new_bit = bitget(new_value, bit_position+1);
            
            % 如果新值还不匹配,使用LSB替换作为备选
            if new_bit ~= secret_bit
                % 直接修改特定位(LSB替换)
                if secret_bit
                    new_value = bitset(new_value, bit_position+1, 1);
                else
                    new_value = bitset(new_value, bit_position+1, 0);
                end
                embedding_type = 2;  % LSB替换
            end
            
            % 更新像素值
            flat_stego(pixel_idx) = new_value;
            
            % 计算在原始矩阵中的位置
            [row, col, ch] = ind2sub([height, width, channels], pixel_idx);
            embedding_map(row, col, ch) = embedding_type;
        else
            % 不需要修改
            [row, col, ch] = ind2sub([height, width, channels], pixel_idx);
            embedding_map(row, col, ch) = 0;  % 未修改
        end
        
        % 显示进度
        if mod(i, 1000) == 0
            fprintf('  已嵌入 %d/%d 比特 (%.1f%%)\n', i, length(secret_bits), i/length(secret_bits)*100);
        end
    end
    
    % 重塑为原始图像尺寸
    stego_image = reshape(flat_stego, height, width, channels);
    
    % 统计修改类型
    modifications = embedding_map(embedding_map ~= 0);
    if ~isempty(modifications)
        fprintf('修改统计: +1: %d次, -1: %d次, LSB替换: %d次, 总计: %d次\n', ...
                sum(modifications == 1), sum(modifications == -1), ...
                sum(modifications == 2), length(modifications));
        fprintf('修改比例: %.4f%%\n', length(modifications)/total_pixels*100);
    else
        fprintf('未进行任何修改!\n');
    end
end

3. 传统LSB替换函数(用于对比)

matlab 复制代码
function [stego_image, embedding_map] = lsb_replacement_embed(cover_image, secret_bits, bits_per_pixel)
% 传统LSB替换嵌入算法(用于对比)
    
    [height, width, channels] = size(cover_image);
    stego_image = cover_image;
    total_pixels = height * width * channels;
    
    max_bits = total_pixels * bits_per_pixel;
    if length(secret_bits) > max_bits
        error('秘密信息过长: %d > %d 比特', length(secret_bits), max_bits);
    end
    
    embedding_map = zeros(height, width, channels);
    flat_cover = cover_image(:);
    flat_stego = stego_image(:);
    
    fprintf('开始传统LSB替换嵌入...\n');
    
    for i = 1:length(secret_bits)
        pixel_idx = ceil(i / bits_per_pixel);
        pixel_value = flat_cover(pixel_idx);
        bit_position = mod(i-1, bits_per_pixel);
        
        current_bit = bitget(pixel_value, bit_position+1);
        secret_bit = secret_bits(i);
        
        if current_bit ~= secret_bit
            % 直接修改特定位
            if secret_bit
                new_value = bitset(pixel_value, bit_position+1, 1);
            else
                new_value = bitset(pixel_value, bit_position+1, 0);
            end
            
            flat_stego(pixel_idx) = new_value;
            
            % 记录修改
            [row, col, ch] = ind2sub([height, width, channels], pixel_idx);
            embedding_map(row, col, ch) = 1;  % 标记为LSB替换修改
            
            % 检查是否修改了其他位(理论上不应该)
            if new_value ~= pixel_value
                % 检查是否只是目标位的变化
                xor_val = bitxor(pixel_value, new_value);
                if sum(bitget(xor_val, 1:8)) > 1
                    fprintf('警告: 像素%d的多个位被修改!\n', pixel_idx);
                end
            end
        end
        
        if mod(i, 1000) == 0
            fprintf('  已嵌入 %d/%d 比特 (%.1f%%)\n', i, length(secret_bits), i/length(secret_bits)*100);
        end
    end
    
    stego_image = reshape(flat_stego, height, width, channels);
    
    modifications = sum(embedding_map(:) ~= 0);
    fprintf('修改统计: %d个像素被修改 (%.4f%%)\n', modifications, modifications/total_pixels*100);
end

4. 信息提取函数

matlab 复制代码
function extracted_bits = lsb_extract(stego_image, num_bits, bits_per_pixel)
% 从隐写图像提取秘密比特
    
    [height, width, channels] = size(stego_image);
    total_pixels = height * width * channels;
    
    if num_bits > total_pixels * bits_per_pixel
        error('请求提取的比特数超过容量!');
    end
    
    % 展平图像
    flat_stego = stego_image(:);
    extracted_bits = false(1, num_bits);
    
    fprintf('提取秘密比特...\n');
    
    for i = 1:num_bits
        pixel_idx = ceil(i / bits_per_pixel);
        pixel_value = flat_stego(pixel_idx);
        bit_position = mod(i-1, bits_per_pixel);
        
        % 提取特定位
        extracted_bits(i) = bitget(pixel_value, bit_position+1);
        
        if mod(i, 1000) == 0
            fprintf('  已提取 %d/%d 比特 (%.1f%%)\n', i, num_bits, i/num_bits*100);
        end
    end
    
    fprintf('提取完成。\n');
end

function bits = text_to_bits(text)
% 将文本转换为比特流
    bits = false(1, length(text) * 8);
    for i = 1:length(text)
        char_bits = bitget(uint8(text(i)), 8:-1:1);
        bits((i-1)*8+1:i*8) = char_bits;
    end
end

function text = bits_to_text(bits)
% 将比特流转换回文本
    num_chars = length(bits) / 8;
    text = '';
    for i = 1:num_chars
        char_bits = bits((i-1)*8+1:i*8);
        char_code = 0;
        for j = 1:8
            if char_bits(j)
                char_code = char_code + 2^(8-j);
            end
        end
        text(i) = char(char_code);
    end
end

5. 性能分析与可视化

matlab 复制代码
function analyze_steganography_performance(cover_image, stego_image, secret_bits, ...
                                          embedding_map, use_lsb_matching)
% 分析隐写术性能
    
    fprintf('分析隐写术性能...\n');
    
    % 1. 计算PSNR(峰值信噪比)
    mse = mean(double(cover_image(:)) - double(stego_image(:))).^2;
    if mse == 0
        psnr = Inf;
    else
        max_pixel = 255;
        psnr = 10 * log10(max_pixel^2 / mse);
    end
    fprintf('PSNR: %.2f dB\n', psnr);
    
    % 2. 计算修改统计
    total_pixels = numel(cover_image);
    modified_pixels = sum(embedding_map(:) ~= 0);
    modification_rate = modified_pixels / total_pixels * 100;
    fprintf('修改像素比例: %.4f%% (%d/%d)\n', modification_rate, modified_pixels, total_pixels);
    
    if use_lsb_matching
        plus_mod = sum(embedding_map(:) == 1);
        minus_mod = sum(embedding_map(:) == -1);
        lsb_replace_mod = sum(embedding_map(:) == 2);
        fprintf('LSB匹配修改: +1: %d次, -1: %d次, LSB替换: %d次\n', ...
                plus_mod, minus_mod, lsb_replace_mod);
    end
    
    % 3. 计算嵌入效率(每修改像素的嵌入比特数)
    if modified_pixels > 0
        embedding_efficiency = length(secret_bits) / modified_pixels;
        fprintf('嵌入效率: %.2f 比特/修改像素\n', embedding_efficiency);
    end
    
    % 4. 可视化对比
    figure('Position', [100, 100, 1400, 600]);
    
    % 子图1: 载体图像和隐写图像
    subplot(2, 4, [1, 2]);
    if size(cover_image, 3) == 3
        % 彩色图像 - 显示RGB
        imshowpair(cover_image, stego_image, 'montage');
        title('载体图像 (左) vs 隐写图像 (右)');
    else
        % 灰度图像 - 并排显示
        subimage1 = subplot(2, 4, 1);
        imshow(cover_image, []);
        title('载体图像');
        
        subplot(2, 4, 2);
        imshow(stego_image, []);
        title('隐写图像');
    end
    
    % 子图2: 差异图
    subplot(2, 4, 3);
    diff_image = double(stego_image) - double(cover_image);
    diff_image_abs = abs(diff_image);
    
    if size(diff_image, 3) == 3
        % 彩色差异图
        diff_display = uint8(abs(diff_image) * 10);  % 放大差异以便观察
        imshow(diff_display);
    else
        % 灰度差异图
        imagesc(diff_image);
        colorbar;
        colormap('jet');
    end
    title('差异图 (放大显示)');
    
    % 子图3: 修改类型分布
    subplot(2, 4, 4);
    if use_lsb_matching
        mod_types = embedding_map(embedding_map ~= 0);
        if ~isempty(mod_types)
            unique_types = unique(mod_types);
            counts = histcounts(mod_types, [unique_types; max(unique_types)+1]);
            bar(unique_types, counts, 'FaceColor', [0.2, 0.6, 0.8]);
            set(gca, 'XTick', unique_types);
            xlabel('修改类型'); ylabel('次数');
            title('LSB匹配修改类型分布');
            grid on;
        else
            text(0.5, 0.5, '无修改', 'HorizontalAlignment', 'center');
            title('无修改');
        end
    else
        % 传统LSB替换的修改分布
        modified = embedding_map ~= 0;
        if any(modified(:))
            imagesc(modified);
            title('修改位置图 (黄色为修改)');
            colormap([0 0 0; 1 1 0]);  % 黑色: 未修改, 黄色: 修改
        else
            text(0.5, 0.5, '无修改', 'HorizontalAlignment', 'center');
            title('无修改');
        end
    end
    
    % 子图5: 直方图对比
    subplot(2, 4, 5);
    if size(cover_image, 3) == 1
        % 灰度图像直方图
        histogram(cover_image(:), 0:255, 'FaceColor', 'b', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
        hold on;
        histogram(stego_image(:), 0:255, 'FaceColor', 'r', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
        xlabel('像素值'); ylabel('频数');
        title('像素值直方图对比');
        legend('载体图像', '隐写图像', 'Location', 'best');
        grid on;
    else
        % 彩色图像 - 显示亮度直方图
        cover_gray = rgb2gray(cover_image);
        stego_gray = rgb2gray(stego_image);
        histogram(cover_gray(:), 0:255, 'FaceColor', 'b', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
        hold on;
        histogram(stego_gray(:), 0:255, 'FaceColor', 'r', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
        xlabel('亮度值'); ylabel('频数');
        title('亮度直方图对比');
        legend('载体图像', '隐写图像', 'Location', 'best');
        grid on;
    end
    
    % 子图6: LSB分布对比
    subplot(2, 4, 6);
    % 提取LSB位
    cover_lsb = bitget(cover_image(:), 1);
    stego_lsb = bitget(stego_image(:), 1);
    
    % 计算LSB分布
    cover_lsb_ones = sum(cover_lsb) / length(cover_lsb) * 100;
    stego_lsb_ones = sum(stego_lsb) / length(stego_lsb) * 100;
    
    bar([1, 2], [cover_lsb_ones, stego_lsb_ones], 'FaceColor', [0.8, 0.4, 0.2]);
    set(gca, 'XTickLabel', {'载体图像', '隐写图像'});
    ylabel('LSB=1的比例 (%)');
    title('LSB分布对比');
    ylim([40, 60]); grid on;
    
    % 添加理想线(50%)
    hold on;
    plot([0.5, 2.5], [50, 50], 'r--', 'LineWidth', 1.5);
    legend('LSB=1比例', '理想值(50%)', 'Location', 'best');
    
    % 子图7: 像素值变化统计
    subplot(2, 4, 7);
    pixel_changes = double(stego_image(:)) - double(cover_image(:));
    unique_changes = unique(pixel_changes);
    change_counts = histcounts(pixel_changes, [unique_changes; max(unique_changes)+1]);
    
    bar(unique_changes, change_counts, 'FaceColor', [0.3, 0.7, 0.3]);
    xlabel('像素值变化'); ylabel('频数');
    title('像素值变化分布');
    grid on;
    
    % 子图8: 修改位置的空间分布
    subplot(2, 4, 8);
    if size(cover_image, 3) == 1
        % 灰度图像
        mod_map = embedding_map ~= 0;
        spy(mod_map, 'b.', 5);  % 显示稀疏矩阵
    else
        % 彩色图像 - 显示第一个通道
        mod_map = embedding_map(:, :, 1) ~= 0;
        spy(mod_map, 'b.', 5);
    end
    title('修改位置空间分布');
    
    sgtitle(sprintf('LSB匹配隐写术性能分析 (PSNR: %.2f dB)', psnr), 'FontSize', 14);
end

6. 鲁棒性测试

matlab 复制代码
function test_steganography_robustness(cover_image, stego_image, secret_bits, ...
                                       stego_path, use_lsb_matching)
% 测试隐写术的鲁棒性
    
    fprintf('\n鲁棒性测试...\n');
    
    % 测试不同攻击下的提取成功率
    tests = {
        '无攻击', @(x) x;
        '高斯噪声(σ=0.01)', @(x) imnoise(x, 'gaussian', 0, 0.01);
        '高斯噪声(σ=0.02)', @(x) imnoise(x, 'gaussian', 0, 0.02);
        '椒盐噪声(密度=0.01)', @(x) imnoise(x, 'salt & pepper', 0.01);
        'JPEG压缩(质量=90)', @(x) jpeg_compress(x, 90);
        'JPEG压缩(质量=75)', @(x) jpeg_compress(x, 75);
    };
    
    num_tests = length(tests);
    extraction_success = zeros(1, num_tests);
    ber_results = zeros(1, num_tests);  % 误比特率
    
    for t = 1:num_tests
        test_name = tests{t}{1};
        attack_func = tests{t}{2};
        
        fprintf('  测试%d/%d: %s... ', t, num_tests, test_name);
        
        % 应用攻击
        if strcmp(test_name, '无攻击')
            attacked_image = stego_image;
        else
            attacked_image = attack_func(stego_image);
        end
        
        % 尝试提取秘密信息
        try
            extracted_bits = lsb_extract(attacked_image, length(secret_bits), 1);
            
            % 计算误比特率
            ber = sum(extracted_bits ~= secret_bits) / length(secret_bits);
            ber_results(t) = ber;
            
            % 提取前32位长度信息
            extracted_length_bits = extracted_bits(1:32);
            extracted_length = bin2dec(char(extracted_length_bits' + '0'));
            
            % 检查提取是否成功
            if extracted_length > 0 && extracted_length <= length(secret_bits)-32
                % 提取实际信息
                extracted_message_bits = extracted_bits(33:32+extracted_length);
                
                % 简单验证:检查提取长度是否正确
                if extracted_length == length(secret_bits)-32
                    extraction_success(t) = 1;
                    fprintf('成功 (BER=%.4f)\n', ber);
                else
                    extraction_success(t) = 0;
                    fprintf('失败 (长度不匹配, BER=%.4f)\n', ber);
                end
            else
                extraction_success(t) = 0;
                fprintf('失败 (长度信息无效, BER=%.4f)\n', ber);
            end
            
        catch ME
            fprintf('失败 (错误: %s)\n', ME.message);
            extraction_success(t) = 0;
            ber_results(t) = 1;  % 完全错误
        end
    end
    
    % 显示鲁棒性测试结果
    figure('Position', [100, 100, 1000, 400]);
    
    % 子图1: 提取成功率
    subplot(1, 2, 1);
    bar(1:num_tests, extraction_success * 100, 'FaceColor', [0.2, 0.6, 0.8]);
    set(gca, 'XTick', 1:num_tests, 'XTickLabel', cellfun(@(x) x{1}, tests, 'UniformOutput', false));
    ylabel('提取成功率 (%)');
    title('鲁棒性测试 - 提取成功率');
    ylim([0, 110]); grid on;
    xtickangle(45);
    
    % 添加数值标签
    for i = 1:num_tests
        text(i, extraction_success(i)*100 + 2, sprintf('%.0f%%', extraction_success(i)*100), ...
             'HorizontalAlignment', 'center', 'FontWeight', 'bold');
    end
    
    % 子图2: 误比特率
    subplot(1, 2, 2);
    bar(1:num_tests, ber_results * 100, 'FaceColor', [0.8, 0.4, 0.2]);
    set(gca, 'XTick', 1:num_tests, 'XTickLabel', cellfun(@(x) x{1}, tests, 'UniformOutput', false));
    ylabel('误比特率 (%)');
    title('鲁棒性测试 - 误比特率');
    ylim([0, 100]); grid on;
    xtickangle(45);
    
    % 添加数值标签
    for i = 1:num_tests
        text(i, ber_results(i)*100 + 2, sprintf('%.2f%%', ber_results(i)*100), ...
             'HorizontalAlignment', 'center', 'FontWeight', 'bold');
    end
    
    sgtitle('LSB匹配隐写术鲁棒性测试结果', 'FontSize', 14);
    
    % 总结
    fprintf('\n鲁棒性测试总结:\n');
    fprintf('%-25s %-15s %-15s\n', '攻击类型', '提取成功', '误比特率');
    fprintf('%s\n', repmat('-', 1, 55));
    for t = 1:num_tests
        fprintf('%-25s %-15s %-15.2f%%\n', tests{t}{1}, ...
                ifelse(extraction_success(t), '是', '否'), ber_results(t)*100);
    end
end

function output_image = jpeg_compress(input_image, quality)
% JPEG压缩攻击
    % 保存为临时JPEG文件
    temp_file = 'temp_jpeg.jpg';
    imwrite(input_image, temp_file, 'Quality', quality);
    
    % 重新读取
    output_image = imread(temp_file);
    
    % 删除临时文件
    delete(temp_file);
end

function result = ifelse(condition, true_val, false_val)
% 简单的if-else函数
    if condition
        result = true_val;
    else
        result = false_val;
    end
end

参考代码 基于LSB匹配的隐写术 www.3dddown.com/csa/97471.html

安全增强建议

  1. 加密预处理:在隐写前对秘密信息进行AES/DES加密
  2. 伪随机嵌入:使用密码学安全的随机数生成器确定嵌入位置
  3. 自适应嵌入:根据图像纹理复杂度调整嵌入强度
  4. 多层隐写:结合DCT域或小波域隐写提高安全性

性能指标

  • 不可见性:PSNR > 40dB 通常认为不可察觉
  • 容量:理论最大容量 = 图像像素数 × bits_per_pixel
  • 鲁棒性:LSB匹配对轻微处理(如压缩、噪声)有一定抵抗力
  • 安全性:抵抗统计检测(如卡方检测、RS分析)
相关推荐
Scott9999HH6 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社7 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海7 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖8 小时前
JDK 26 新特性详解
java·开发语言
马优晨9 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区10 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大11 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai11 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜11 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa12 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio