MATLAB-LSB 信息隐藏

100 阅读10分钟

MATLAB - LSB 信息隐藏工具


2018-8-24 20:29:45 【原创】

1. 运行环境

最近用到 LSB 的信息隐藏技术将数据隐藏到图片文件中,遂写了一个隐藏工具,使用 MATLAB 实现起来也很容易。

另外说一下,如果 MATLAB-2010a 版本在安装破解之后还是不能用时候,修改一下电脑的时间就好了,原理是序列号有过期时间,和本地电脑做校验。


2. 实现的功能

  1. 支持读取用户要隐藏的数据
  2. 支持将数据写入图像文件
  3. 支持将图像文件进行保存
  4. 支持提取图片中隐藏的数据,并且写入一个txt文档在当前目下

3.代码

为了方便查看,我将代码中的注释删掉了,只留了一些汉语的文字注释。

另外,还贴了一个完整版的。

在 MATLAB 如果不会用图形化开发框架的话,可以搜索一下。其实就是在 matlab 的命令行写入命令“guide”,即可调用打开图形化框架

1. 删除注释后的

function varargout = chenyun(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @chenyun_OpeningFcn, ...
                   'gui_OutputFcn',  @chenyun_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end


function chenyun_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;

guidata(hObject, handles);

function varargout = chenyun_OutputFcn(hObject, eventdata, handles) 

set(handles.edit1,'enable','off'); 
varargout{1} = handles.output;


function pushbutton1_Callback(hObject, eventdata, handles)

[filename, pathname] = uigetfile(...
    {'*.bmp;*.png','Image Files(*.bmp,*.png)';...
    '*.*', 'All Files (*.*)'},...
    '选择一个载体图像:');

%读入图像矩阵
global C;
global fpath;
axes(handles.axes1);
fpath=[pathname filename];
C=imread(fpath);%读取图像并存放到C中
imshow(C);


function pushbutton2_Callback(hObject, eventdata, handles)

global C;
global L;
C_M=C;

[filename, pathname] = uigetfile({'*.txt','*.mat'},'请选择待隐藏的信息文件名...');
msgpath=[pathname filename];
fileID=fopen(msgpath,'r');%打开文件
[M,L]=fread(fileID,'ubit1');

%将二进制的秘密消息M嵌入到载密图像的LSB面
[m,n]=size(C);

p=1;%嵌入计数器
for i=1:m
    for j=1:n
        C_M(i,j)=C(i,j)-mod(C(i,j),2)+M(p,1);%嵌入方法是先将LSB置零,然后加上秘密消息中的对应的0或1
        if L==p   %嵌入终止条件:当嵌入的个数为秘密消息的长度时,跳出循环,不再嵌入
         break;
        end
       p=p+1;
 end
 if L==p    %嵌入终止条件:当嵌入的个数为秘密消息的长度时,跳出循环,不再嵌入
    break;
 end
end


[filename1, pathname1] = uiputfile({'*.bmp','*.bmp'},'将隐藏图像另存为...');
imagepath=[pathname1 filename1];
fileID=fopen(imagepath,'w');%打开文件
imwrite(C_M,imagepath','bmp');


% imwrite(C_M,'pic70.bmp','bmp');

 %查看嵌入信息情况:将载密图像减去载体图像
for i=1:m
    for j=1:n
        C_C(i,j)=C_M(i,j)-C(i,j);
   end
 end

%输出第二个图像

%imshow(cover);
axes(handles.axes2);
%fpath=[pathname filename];
%cover=imread(fpath);
%ste_cover=double(cover);
%imshow(cover);
imshow(C_M);

function pushbutton3_Callback(hObject, eventdata, handles)
global L;
global fpath;


[filename, pathname] = uigetfile(...
    {'*.bmp;*.png','Image Files(*.bmp,*.png)';...
    '*.*', 'All Files (*.*)'},...
    '请选择待提取信息的隐藏图像:');

%读入图像矩阵

fpath=[pathname filename];

axes(handles.axes1);
C=imread(fpath);%读取图像并存放到C中
imshow(C);

axes(handles.axes2);
C=imread(fpath);%读取图像并存放到C中
imshow(C);

lsbsget(fpath,L);

fid = fopen('secret.txt','r');
i = 1;
while feof(fid) ==0
   b(i,:) = fgetl(fid);
   i = i+1;
end

set( handles.edit1,'string',b);
fclose(fid);

ra=fix(mean(double(get(handles.edit4,'string'))));
code_disp=get(handles.edit1,'String');
code=str2num(b);
text=char((code-ra)/ra);
set( handles.edit2,'string',text);


function edit1_Callback(hObject, eventdata, handles)

function edit1_CreateFcn(hObject, eventdata, handles)

function edit2_Callback(hObject, eventdata, handles)

function edit2_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function axes1_CreateFcn(hObject, eventdata, handles)

function axes2_CreateFcn(hObject, eventdata, handles)

function pushbutton_readmsg_Callback(hObject, eventdata, handles)


global code_disp;%密文

ra=fix(mean(double(get(handles.edit4,'string'))));%取整避免舍入误差
% ra为加密算子,是由用户输入且仅有用户本人知道的字符串转换而来,这里的转换算法是将字符串中的字符求
%其ASCII码的平均值,作为加密算子ra的值。
text=get(handles.edit2,'String'); %得到要转换的文本内容  
code=double(text); %取得文本内容的ASCII码数组
encode=code*ra+ra;%转换成要显示的编码
code_disp=num2str(encode); %将编码转换成字符串,便于显示  
set(handles.edit1,'String',code_disp)%显示转换后的结果

function pushbutton_savesecret_Callback(hObject, eventdata, handles)

global code_disp;%密文

[filename, pathname] = uiputfile(...
    {'*.txt','txt files(*.txt)';...
    '*.*', 'All Files (*.*)'},...
    '将密文另存为...');
msgpath=[pathname filename];
fileID=fopen(msgpath,'w');
fwrite(fileID,code_disp,'char');

function edit4_Callback(hObject, eventdata, handles)

function edit4_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function S=lsbsget(C_M,L)
%读取载密图像矩阵
C_M1=imread(C_M);
[m,n]=size(C_M1);
S=zeros(1,L);
%读出LSB平面中0、1存入S中
for i=1:m
    for j=1:n
        if (i-1)*m+j>L%判断嵌入长度是否大于L,若大于L,则终止循环
            break;
        end
        S(1,(i-1)*m+j)=mod(C_M1(i,j),2);
    end
    if (i-1)*m+j>L%判断嵌入长度是否大于L,若大于L,则终止循环
         break;
    end
end

%将二进制向量S转化为ASCII码并存放到文本文件secret中
fileID=fopen('secret.txt','w');
a=L/8;%计算字符个数
SC=zeros(1,a);
for i=1:a
    b=0;
    for j=1:8
        b=b+S(1,(i-1)*8+j)*power(2,j-1);
    end
    SC(1,i)=b;
    fwrite(fileID,SC(1,i),'char');  
end
fclose(fileID);

2. 删除注释前的

function varargout = chenyun(varargin)
% CHENYUN M-file for chenyun.fig
%      CHENYUN, by itself, creates a new CHENYUN or raises the existing
%      singleton*.
%
%      H = CHENYUN returns the handle to a new CHENYUN or the handle to
%      the existing singleton*.
%
%      CHENYUN('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in CHENYUN.M with the given input arguments.
%
%      CHENYUN('Property','Value',...) creates a new CHENYUN or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before chenyun_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to chenyun_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help chenyun

% Last Modified by GUIDE v2.5 09-May-2015 09:22:36

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @chenyun_OpeningFcn, ...
                   'gui_OutputFcn',  @chenyun_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before chenyun is made visible.
function chenyun_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to chenyun (see VARARGIN)

% Choose default command line output for chenyun
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes chenyun wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = chenyun_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.edit1,'enable','off'); 
% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[filename, pathname] = uigetfile(...
    {'*.bmp;*.png','Image Files(*.bmp,*.png)';...
    '*.*', 'All Files (*.*)'},...
    '选择一个载体图像:');

%读入图像矩阵
global C;
global fpath;
axes(handles.axes1);
fpath=[pathname filename];
C=imread(fpath);%读取图像并存放到C中
imshow(C);


% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global C;
global L;
C_M=C;
%imwrite(ste_cover,output);

[filename, pathname] = uigetfile({'*.txt','*.mat'},'请选择待隐藏的信息文件名...');
msgpath=[pathname filename];
fileID=fopen(msgpath,'r');%打开文件
[M,L]=fread(fileID,'ubit1');

%将二进制的秘密消息M嵌入到载密图像的LSB面
[m,n]=size(C);

p=1;%嵌入计数器
for i=1:m
    for j=1:n
        C_M(i,j)=C(i,j)-mod(C(i,j),2)+M(p,1);%嵌入方法是先将LSB置零,然后加上秘密消息中的对应的0或1
        if L==p   %嵌入终止条件:当嵌入的个数为秘密消息的长度时,跳出循环,不再嵌入
         break;
        end
       p=p+1;
 end
 if L==p    %嵌入终止条件:当嵌入的个数为秘密消息的长度时,跳出循环,不再嵌入
    break;
 end
end


[filename1, pathname1] = uiputfile({'*.bmp','*.bmp'},'将隐藏图像另存为...');
imagepath=[pathname1 filename1];
fileID=fopen(imagepath,'w');%打开文件
imwrite(C_M,imagepath','bmp');


% imwrite(C_M,'pic70.bmp','bmp');

 %查看嵌入信息情况:将载密图像减去载体图像
for i=1:m
    for j=1:n
        C_C(i,j)=C_M(i,j)-C(i,j);
   end
 end

%输出第二个图像

%imshow(cover);
axes(handles.axes2);
%fpath=[pathname filename];
%cover=imread(fpath);
%ste_cover=double(cover);
%imshow(cover);
imshow(C_M);

% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global L;
global fpath;


[filename, pathname] = uigetfile(...
    {'*.bmp;*.png','Image Files(*.bmp,*.png)';...
    '*.*', 'All Files (*.*)'},...
    '请选择待提取信息的隐藏图像:');

%读入图像矩阵

fpath=[pathname filename];

axes(handles.axes1);
C=imread(fpath);%读取图像并存放到C中
imshow(C);

axes(handles.axes2);
C=imread(fpath);%读取图像并存放到C中
imshow(C);

lsbsget(fpath,L);

fid = fopen('secret.txt','r');
i = 1;
while feof(fid) ==0
   b(i,:) = fgetl(fid);
   i = i+1;
end

set( handles.edit1,'string',b);
fclose(fid);

ra=fix(mean(double(get(handles.edit4,'string'))));
code_disp=get(handles.edit1,'String');
code=str2num(b);
text=char((code-ra)/ra);
set( handles.edit2,'string',text);


function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double


%a1 = str2double(get(handles.edit1,'String'));

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
%if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
%    set(hObject,'BackgroundColor','white');
%end



function edit2_Callback(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit2 as text
%        str2double(get(hObject,'String')) returns contents of edit2 as a double


% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function axes1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axes1


% --- Executes during object creation, after setting all properties.
function axes2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axes2


% --- Executes on button press in pushbutton_readmsg.
function pushbutton_readmsg_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_readmsg (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global code_disp;%密文

ra=fix(mean(double(get(handles.edit4,'string'))));%取整避免舍入误差
% ra为加密算子,是由用户输入且仅有用户本人知道的字符串转换而来,这里的转换算法是将字符串中的字符求
%其ASCII码的平均值,作为加密算子ra的值。
text=get(handles.edit2,'String'); %得到要转换的文本内容  
code=double(text); %取得文本内容的ASCII码数组
encode=code*ra+ra;%转换成要显示的编码
code_disp=num2str(encode); %将编码转换成字符串,便于显示  
set(handles.edit1,'String',code_disp)%显示转换后的结果


% --- Executes on button press in pushbutton_savesecret.
function pushbutton_savesecret_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_savesecret (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global code_disp;%密文

[filename, pathname] = uiputfile(...
    {'*.txt','txt files(*.txt)';...
    '*.*', 'All Files (*.*)'},...
    '将密文另存为...');
msgpath=[pathname filename];
fileID=fopen(msgpath,'w');
fwrite(fileID,code_disp,'char');

function edit4_Callback(hObject, eventdata, handles)
% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit4 as text
%        str2double(get(hObject,'String')) returns contents of edit4 as a double


% --- Executes during object creation, after setting all properties.
function edit4_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function S=lsbsget(C_M,L)
%读取载密图像矩阵
C_M1=imread(C_M);
[m,n]=size(C_M1);
S=zeros(1,L);
%读出LSB平面中0、1存入S中
for i=1:m
    for j=1:n
        if (i-1)*m+j>L%判断嵌入长度是否大于L,若大于L,则终止循环
            break;
        end
        S(1,(i-1)*m+j)=mod(C_M1(i,j),2);
    end
    if (i-1)*m+j>L%判断嵌入长度是否大于L,若大于L,则终止循环
         break;
    end
end

%将二进制向量S转化为ASCII码并存放到文本文件secret中
fileID=fopen('secret.txt','w');
a=L/8;%计算字符个数
SC=zeros(1,a);
for i=1:a
    b=0;
    for j=1:8
        b=b+S(1,(i-1)*8+j)*power(2,j-1);
    end
    SC(1,i)=b;
    fwrite(fileID,SC(1,i),'char');  
end
fclose(fileID);