hide&seek算法
通过减少调色板矩阵的颜色数,再复制增加一倍,再通过某种方法嵌入消息,这里是实现了将读入的图片的颜色减至128色,然后复制成为256色,这样数据索引矩阵中的值可以选择两个索引,一个小索引、一个大索引,使其分别代表不同的信息即可,例如0、1。关于调色板矩阵和索引矩阵可以看我上一篇文章。
代码实现
matlab不是我擅长的语言,hh,想想我也没什么擅长的语言!
隐藏函数
function [ newdata, newmap ] = MyHideSeek( data, map, msg )
%自我实现的最简单的Hide&Seek算法
%data:原始索引矩阵
%map:原始调色板矩阵
%msg:需要隐藏的消息
newdata = data;
newmap = [map;map];
size_data = prod(size(data));
len_msg = length(msg);%消息的长度
lenstr = de2bi(len_msg, 7, 2);
msgasc = double(msg);
msgstr = de2bi(msgasc, 7, 2);
msgstr = msgstr';
len_map = length(map); %原始调色板的颜色个数
if size_data < 7*(len_msg+1)
error('The message is too long to embed!\n');
end
%改变索引矩阵的值来隐藏信息
%存入长度
for i = 1:7
if lenstr(i) == 1 %规定消息为1时使用大的索引
newdata(i) = newdata(i) + len_map;
end
end
%存入msg
for j = 8:7*(len_msg + 1)
if msgstr(j-7) == 1
newdata(j) = newdata(j) +len_map;
end
end
end
提取函数
function msg = MyHideSeekExtract( newdata, newmap )
%MyHideSeek提取函数
%newdata:隐含信息的数据索引矩阵
%newmap:复制后的调色板矩阵
len_map = length(newmap)/2;%原始map的长度
len = zeros(1,7);%用来存放提取出来的消息长度
for i = 1:7
if newdata(i) > len_map
len(i) = 1;
end
end
len = bi2de(len);
msg = zeros(7,len);
%提取消息
for j = 8:7*(len + 1)
if newdata(j) >len_map
msg(j-7) = 1;
end
end
%将消息转为字符串
msgasc = bi2de(msg');
msg = char(msgasc);
msg = msg';
end
测试脚本
clear;
im = imread('comic.png');
[data, map] = rgb2ind(im, 128); %将图片的颜色减少至128色,由于数据索引矩阵的数据时uint8所以这里的最大为128色,超过就无法还原了
msg = 'flag{This_1s_for_my_Hide_&_Seek.}';
[newdata, newmap] = MyHideSeek(data, map, msg);
imshow(data, map);title('Origin');
figure;imshow(newdata, newmap); title('Steg');
flag = MyHideSeekExtract(newdata, newmap);
fprintf('flag:%s\n', flag);
测试结果
比较前后两张图片,肉眼分别不出差异:
查看输出的文本信息:
注:之前一直不清楚hide&seek算法是什么,虽然拍了几张上课的照片,但是不懂,同学的提示让我突然想到了我拍的照片的含义,果然上课不好好听课是不行的,在此向她致谢~
hide&seek算法还有其他的编码方式,这只是其中一种最简单的。关键在改变调色板矩阵之后的嵌入方式的选择,这是多样的。