MATLAB
程序来源:Simulator of nsF5 embedding (Matlab):http://dde.binghamton.edu/download/nsf5simulator/。
.mex文件是由C或Fortran语言编写的代码经过matlab编译器处理而生成的二进制文件。它是可以被matlab解释器自动装载并执行的动态链接程序。
mex封装包名称与操作系统的对应关系如下:
mexa64 : 64-bit Linux
mexglx : 32-bit Linux
mexw32 : 32-bit Windows
mexw64 : 64-bit Windows
JSteg
信息隐藏算法是LSB替换思想在DCT域的实现
。
JSteg信息隐藏算法嵌入过程的关键步骤就是将原始图像的AC系数中最低的一个位平面“替换”为要隐藏的秘密信息
。这里的“替换”遵循如下规则:
(1)跳过-1、0、1;
(2)若AC系数为2i,秘密比特为0,该系数不变;
(3)若AC系数为2i,秘密比特为1,该系数变为2i+1;
(4)若AC系数为2i+1,秘密比特为0,该系数变为2i;
(5)若AC系数为2i+1,秘密比特为1,该系数不变。
由此规则可知:载密图像的AC系数中,-1、0、1不包含任何秘密信息。此外,其他的AC系数中的最低比特位即为秘密比特。只需将除-1、0、1外的其他AC系数的最低比特位取出,即可恢复秘密信息。
Steg信息隐藏算法嵌入流程如下:
(1)提取原始图像的DCT系数,获取AC系数;
(2)将秘密信息转换为二进制序列,并按照JSteg信息隐藏算法替换规则,将原始图像中AC系数的最低比特位替换为二进制序列中的每一比特信息;
(3)在替换过程结束后,将原始图像中AC系数的二进制数据转换回十进制数据,保存为载密图像。
与嵌入算法对应,Steg信息隐藏算法提取流程如下:
(1)提取载密图像的DCT系数,获取AC系数;
(2)将除-1、0、1外的其他AC系数的最低比特位取出,根据嵌入顺序进行组合得到原秘密序列。
根据JSteg信息隐藏算法替换规则,载密图像的DCT直方图会出现“成对现象”
。
function [nzAC] = JSTEG_simulation(COVER, STEGO, message)
try
jobj = jpeg_read(COVER); %读取cover图片
PrimeDCT = jobj.coef_arrays{1}; %读取DCT系数
DCT = PrimeDCT;
catch
error('ERROR (problem with the cover image)');
end
nzAC = numel(DCT) - numel(DCT(1:8:end, 1:8:end)); %计算AC系数个数
messageLen = length(message);
changeable = true(size(DCT)); %生成一个布尔矩阵
changeable(1:8:end, 1:8:end) = false; %DC系数的位置置为false
posAC = find(changeable); %找出布尔矩阵中为true的位置,即AC系数的位置
idD = 1;
idMsg = 1;
while idMsg <= messageLen
while idD <= nzAC && abs(DCT(posAC(idD))) <= 1
idD = idD + 1;
end
%信息过长
if idD > nzAC
error('ERROR (too long message)')
end
DCTInfo = DCT(posAC(idD));
if message(idMsg) ~= mod(DCTInfo, 2) %LSB与隐藏信息不同
if DCTInfo < 0
if mod(DCTInfo, 2)
DCT(posAC(idD)) = DCTInfo + 1;
else
DCT(posAC(idD)) = DCTInfo - 1;
end
else
if mod(DCTInfo, 2)
DCT(posAC(idD)) = DCTInfo - 1;
else
DCT(posAC(idD)) = DCTInfo + 1;
end
end
end
idD = idD + 1;
idMsg = idMsg + 1;
end
histogram(DCT)
%%% save the resulting stego image
try
jobj.coef_arrays{1} = DCT;
jobj.optimize_coding = 1;
jpeg_write(jobj, STEGO);
catch
error('ERROR (problem with saving the stego image)');
end
%显示未嵌入信息的图像
subplot(3, 2, 1);
imshow(COVER);
title('未嵌入信息的图像');
%显示未嵌入信息的图像的DCT系数直方图
subplot(3, 2, [3, 4]);
histogram(PrimeDCT);
axis([-10, 10, 0, 2 * 1e4]);
title('嵌入前的图像DCT系数直方图');
%显示嵌入信息的图像
subplot(3, 2, 2);
imshow(STEGO);
title('嵌入信息的图像');
%显示嵌入信息的图像的DCT系数直方图
subplot(3, 2, [5, 6]);
histogram(DCT);
axis([-10, 10, 0, 2 * 1e4]);
title('嵌入后的图像DCT系数直方图');
COVER = 'cover.jpg';
STEGO = 'stego.jpg';
message = randi([0, 1], 1, 25000); %生成随机数,作为隐藏信息
save('message', 'message', '-ascii'); %保存秘密信息
tic;
[nzAC] = JSTEG_simulation(COVER, STEGO, message);
T = toc;
fprintf('-----------------------------------\n');
fprintf('JSTEG simulation finished\n');
fprintf('cover image: %s\n', COVER);
fprintf('stego image: %s\n', STEGO);
fprintf('number of nzACs in cover: %i\n', nzAC);
fprintf('elapsed time: %.4f seconds\n', T);
fprintf('-----------------------------------\n');
function message = JSTEG_extract(STEGO, messageLen)
try
jobj = jpeg_read(STEGO); %读取stego图片
DCT = jobj.coef_arrays{1}; %读取DCT系数
catch
error('ERROR (problem with the stego image)');
end
changeable = true(size(DCT)); %生成一个布尔矩阵
changeable(1:8:end, 1:8:end) = false; %DC系数的位置置为false
changeable = find(changeable); %找出布尔矩阵中为true的位置,即AC系数的位置
idMsg = 1;
idD = 1;
nzAC = numel(DCT) - numel(DCT(1:8:end, 1:8:end)); %计算AC系数个数
message = linspace(0, 0, messageLen);
while idMsg <= messageLen
while idD <= nzAC && abs(DCT(changeable(idD))) <= 1
idD = idD + 1;
end
if idD > nzAC
error('ERROR (wrong hiden message length)');
end
message(idMsg) = mod(DCT(changeable(idD)), 2);
idMsg = idMsg + 1;
idD = idD + 1;
end
STEGO = 'stego.jpg';
messageLen = 25000;
tic;
messageHiden = JSTEG_extract(STEGO, messageLen);
T = toc;
save('messageHiden', 'messageHiden', '-ascii');
% 保存提取出来的秘密信息
fprintf('-----------------------------------\n');
fprintf('JSTEG extract finished\n');
fprintf('elapsed time: %.4f seconds\n', T);
fprintf('-----------------------------------\n');
运行JSteg信息隐藏算法隐藏过程的实现代码stego.m。观察到嵌入完成,并且原始图像和载密相差甚微,DCT直方图出现“成对现象
”。
运行JSteg信息隐藏算法提取过程的实现代码extract.m。观察到提取完成。
查看提取出来的秘密信息文件messageHiden,与原始秘密信息文件message比对,观察到提取出来的秘密信息是正确的。
[1] 孔祥维等.多媒体信息安全实践教程.科学出版社