⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 txthide.m

📁 XTHIDE is a GUI that allows the user to hide a text message in an image file. The user will be ask
💻 M
字号:
function []=txthide(arg)
% TXTHIDE  Hides text message (MSG) within an image, using a key (KEY).
% After typing txthide at the command line, a GUI appears that will guide
% the user through the process of encoding the text.  The maximum length of
% text that can be encoded is 1000 characters.  This could be 
% modified, but represents a good comprimise between speed and
% functionality on the author's computer.
% Text can be hidden in a bitmap (*.bmp), a tif (*.tif) or a jpg (*.jpg ).
% However, the encoded image can only be saved as a bitmap or
% tif; the jpg format uses compression and the decoder will not return the
% correct MSG if the user tries to save the encoded image in this 
% format.
% Any character from a common keyboard can be encoded, including the 
% shifted characters and numbers, such as !@#$%^&*()_+123 etc.
%-----------------------------USER NOTES-------------------------------%
% 1.  User may hit the 'Return' key while typing the MSG, but this is NOT
%     recommended, as the formatting will not be preserved on decoding, 
%     and the string length counter will not display the correct string 
%     length.  Similarly for the 'Tab' key, use spaces instead.
% 2.  User should NOT hit the 'Return' key as part of the decoding KEY.


if nargin==0
   arg = 'initialize';
else 
    % Retrieve/redefine (See definitions below) Mainly for easy reading.
    hands = get(gcf,'userdata');
    pos = get(gcbf,'position');
    checkd = hands(1); % For user to choose to decode a MSG.
    checke = hands(2); % For user to choose to encode a MSG.
    edit1 = hands(3);  % Space for user to enter MSG.
    edit2 = hands(4);  % Space for user to enter key.
    frame1 = hands(5);
    frame2 = hands(6);
    push1 = hands(7);  % Indicates user is done entering MSG.
    push2 = hands(8);  % Indicates user is done entering KEY.
    static1 = hands(9);
    static2 = hands(10);
    static3 = hands(11);
    static4 = hands(12);
    static5 = hands(13);
end
 
switch arg
    case 'initialize'  % Creation of GUI and storage of handles.
    counter=0;  % This is where the length of MSG is stored.
    h_fig = figure('name','Text Hider','position',[460 760 300 80],...
                   'menubar','none','resize','off');                                               
    col = get(h_fig,'color');
    checkd=uicontrol(h_fig,'style','checkbox','position',[140 20 60 20],...
                    'string','Decode','backgroundcolor',col,'callback',...
                    'txthide(''decode'')','fontweight','bold');
    checke=uicontrol(h_fig,'style','checkbox','position',[140 50 60 20],...
                    'string','Encode','fontweight','bold',...
                    'backgroundcolor',col,'callback',...
                    'txthide(''encode'')');
    edit1=uicontrol(h_fig,'style','edit','horizontalalignment','left',...
                    'max',9,'min',1,'visible','off','KeyPressFcn',...
                    'txthide(''count'')','userdata',counter);
    edit2=uicontrol(h_fig,'style','edit','horizontalalignment','left',...
                    'max',9,'min',1,'visible','off');
    frame1=uicontrol(h_fig,'style','frame','visible','off');
    frame2=uicontrol(h_fig,'style','frame','visible','off');
    push1=uicontrol(h_fig,'style','pushbutton','string','done',...
                   'callback','txthide(''done1'')','visible','off');
    push2=uicontrol(h_fig,'style','pushbutton',...
                   'string','done','callback','txthide(''done2'')',...
                   'visible','off');
    static1=uicontrol(h_fig,'style','text','visible','off',...
                     'string','Enter the message you wish to hide.',...
                     'fontweight','bold','backgroundcolor',col);                
    static2=uicontrol(h_fig,'style','text','position',[30 33 75 20],...
                      'strin','Choose one:','fontweight','bold',...
                      'backgroundcolor',col);           
    static3=uicontrol(h_fig,'style','text','visible','off',...
                     'string','Enter the key for decoding.',...
                     'fontweight','bold','backgroundcolor',col);
    static4=uicontrol(h_fig,'style','text','visible','off',...
                     'string','Message Length:',...
                     'fontweight','bold','backgroundcolor',col);
    static5=uicontrol(h_fig,'style','text','visible','off',...
                     'string','0','foregroundcolor','blue',...
                     'fontweight','bold','backgroundcolor',col);
    hands=[checkd checke edit1 edit2 frame1 frame2 push1 push2 static1... 
           static2 static3 static4 static5];
    set(h_fig,'userdata',hands);  % Store handles in figures userdata. 
    
    case 'encode' % The user has chosen to encode a MSG.
        set(gcbf,'position',[pos(1) pos(2)-300 300 380]);
        set(checkd,'enable','off','position',[140 320 60 20]);
        set(checke,'position',[140 350 60 20],'enable','off');
        set(edit1,'visible','on','position',[30 50 245 200],'fontsize',...
            10,'string',['     Maximum Number of Characters  ',...
            '         is 1000. See Counter Below'],'foregroundcolor',...
            'red');  % Issue a reminder about the max MSG length.
        set(frame1,'visible','on','position',[30 295 245 3],...
            'backgroundcolor','black');
        set(push1,'visible','on','position',[230 10 45 28]);
        set(static1,'visible','on','position',[30 260 245 20]);
        set(static2,'position',[30 333 75 20]);
        set(static4,'visible','on','position',[28 4 100 28]);
        set(static5,'visible','on','position',[130 4 50 28]);
        pause(1.75);  % Displays reminder only a short time.
        set(edit1,'foregroundcolor','black','string','','fontsize',9) 
        
    case 'decode'  % The user has decided to decode a MSG.
        set(gcbf,'position',[pos(1) pos(2)-110 300 190]);
        set(checkd,'enable','off','position',[140 130 60 20]);
        set(checke,'enable','off','position',[140 160 60 20]);
        set(edit2,'visible','on','position',[30 40 245 30]);
        set(frame1,'position',[30 110 245 3],'visible','on',...
            'backgroundcolor','black');
        set(push2,'visible','on','position',[130 7 45 28]);
        set(static2,'position',[30 143 75 20]);
        set(static3,'visible','on','position',[30 75 245 20]);
        
    case 'done1'  % The user is done entering the MSG to encode.
         set(gcbf,'position',[pos(1) pos(2)-140 300 520]);
         set(checkd,'position',[140 460 60 20]);
         set(checke,'position',[140 490 60 20]);
         set(edit1,'position',[30 190 245 200],'enable','off');
         set(edit2,'visible','on','position',[30 60 245 30]);
         set(frame1,'position',[30 435 245 3]);
         set(frame2,'position',[30 133 245 3],'visible','on',...
             'backgroundcolor','black');
         set(push1,'position',[230 150 45 28],'enable','off');
         set(push2,'visible','on','position',[130 20 45 28]);
         set(static1,'position',[30 400 245 20]);
         set(static2,'position',[30 473 75 20]);
         set(static3,'visible','on','position',[30 95 245 20]);
         set(static4,'position',[28 144 100 28]);
         set(static5,'position',[130 144 50 28])
         if isempty(get(edit1,'string')) % User tried to encode nothing!
               fprintf('\n\t\t No message entered, try again.\n\n')
               close(gcbf)
               return
         end
         
    case 'done2'  % User has entered the key for use in encoding/decoding.
        en_or_de = get(checke,'value'); % Is user encoding or decoding?
        if en_or_de==1 % Encoding.
           key = get(edit2,'string');
           if isempty(key)  % Check if user tried to encode with no KEY.
              fprintf('\n\t\t No key entered, try again.\n\n');
              close(gcbf);
              return
           end
           msg = get(edit1,'string');
           [i j] = size(msg);  % Useful if user hit 'return' in MSG.
           if i >1
               msg = reshape(msg',1,i*j); % MSG should be 1 by n.
           end
           close(gcbf);
           wrkd = encode(msg,key);  % Pass to encode function.
           if isempty(wrkd)  % User hit cancel when choosing a file.
               close(gcbf);
               fprintf('\n\t\t Operation aborted.\n\n');
               return
            end
           fprintf('\t\t\n Your message was encoded.\n\n');
        else % Decoding.
            key = get(edit2,'string');
            if isempty(key)  % Check if user tried to dencode with no KEY.
               close(gcbf)
               fprintf('\n\t\t No key entered, try again.\n\n')
               return
            end 
            msg=decode(key);  % Pass to decode function.
            if isempty(msg) % User hit cancel when choosing a file.
               close(gcbf)
               fprintf('\n \t\t Operation aborted.\n\n')
               return
            end
            close(gcbf);  % New figure is created next to display MSG.
            h_fig = figure('name','The Message','position',...
                         [460 460 300 380],'menubar','none');
                     col=get(h_fig,'color');
            stat = uicontrol(h_fig,'style','edit','position',...
                     [30 40 245 300],'string',msg,'fontsize',9,...
                     'horizontalalignment','left','max',9,'min',1);%#ok
            stat2 = uicontrol(h_fig,'style','text','position',...
                     [30 355 245 20],'string','Your Message:',...
                     'fontweight','bold','backgroundcolor',col,...
                     'horizontalalignment','left','fontsize',12);%#ok
        end
        
    case 'count' % This is where the length of MSG is counted.
        ch=get(gcbf,'currentcharacter');
        if isempty(ch) || ch==13 
            return
        elseif ch==8
            counter = get(edit1,'userdata')-1;
        else
         counter = get(edit1,'userdata')+1;  % Retrieve current length.
        end
        set(edit1,'userdata',counter);
        set(static5,'string',num2str(counter));
        if counter > 990  % Issue a warning when getting close to limit.
           set(static5,'foregroundcolor','red');
        end
end  % End switch
%----------New Function Starts Below--------------------------------------


function success = encode(msg,key)
% ENCODE(msg,key) Encodes a text message using a key.
% This works by using the ascii number representation of the chars in
% KEY (and certain permutations) to create coordinate pairs that represent
% the places in matrix A (which is a submatrix of the pic matrix) where the
% unit alterations to the pic matrix will be made.  I tried to make the
% code easy to follow, but I will respond to questions about how this
% works.

num2add = 1000-length(msg);  % Number of spaces to add to end of MSG.

if num2add < 0, error('This message is too long to encode.'), end

newmsg = [msg,repmat(' ',1,num2add)]; % 1000 chars always encoded.
msgmat = dec2bin(newmsg)-48; % Each row is a bin. rep. of an ascii char. 
[filen pth]=uigetfile({'*.bmp';'*.tif';'*.jpg'},'Choose Image To Encode.');

if isequal(filen,0) || isequal(pth,0)
    success = [];   return  % User cancelled.
end

pic1 = imread([pth filen]);   
B = pic1(:,:,1);   [piclngth pichght] = size(B);  % Choose the first page.
dim1 = piclngth-2;   dim2 = pichght-3;   keyb = key(end:-1:1);
rows = cumsum(double(key));   
columns = cumsum(double(keyb));  % Coord pairs for KEY (rows,columns)
A = zeros(dim1,dim2); % This matrix will house the hiding points.
A = crtmtrx(A,rows,columns,dim1,dim2,key);
idx = find(A==1);  % This same index will be used for pic matrix.

for vv = 1:1000  % This is the encoder.
    for uu = 1:7
        if msgmat(vv,uu)==1;
           if rem(B(idx(uu+7*(vv-1))),2)==0
              B(idx(uu+7*(vv-1))) = B(idx(uu+7*(vv-1)))+1;
           end
        elseif rem(B(idx(uu+7*(vv-1))),2)==1
              B(idx(uu+7*(vv-1))) = B(idx(uu+7*(vv-1)))-1;
        end
    end
end

newpic = pic1;   newpic(:,:,1) = B;
[filen pth] = uiputfile({'*.bmp';'*.tif'},'Save Encoded File As');

if isequal(filen,0) || isequal(pth,0)
    success = [];   return
end % User cancelled.

imwrite(newpic,[pth filen])
success = 1;
%----------New Function Starts Below--------------------------------------


function msg = decode(key)
% DECODE(key) Decodes the message hidden by encode in pic, using key.

[filen pth] = uigetfile({'*.bmp';'*.tif'},'Choose Image To Decode.');

if isequal(filen,0) || isequal(pth,0)
    msg = [];   return
end % User cancelled.

pic2 = imread([pth filen]);   
B = pic2(:,:,1);   [piclngth pichght] = size(B);  % Choose the top page.
dim1 = piclngth-2;   dim2 = pichght-3;   keyb = key(end:-1:1);
rows = cumsum(double(key));   columns = cumsum(double(keyb));
A = zeros(dim1,dim2);  % This matrix houses the hiding points.
A = crtmtrx(A,rows,columns,dim1,dim2,key);
idx = find(A==1);   msgmat = zeros(1000,7);

for vv = 1:1000  % This is the decoder.
    for uu = 1:7
        if rem(B(idx(uu+7*(vv-1))),2)==1 
           msgmat(vv,uu) = 1;
        end
    end
end

msg = char(bin2dec(num2str(msgmat)))'; 
%----------New Function Starts Below--------------------------------------


function A = crtmtrx(A,rows,columns,dim1,dim2,key)
% Creates the matrix used to find the points to hide the message.

jj = 1;   idx = 1;
while 7000 > length(idx) %  Need 7000 points to hide 1000 characters.     
    for ii = 1:length(rows)
        if rows(ii) < dim1
           rows(ii) = rem(dim1,rows(ii))+1;
        else
           rows(ii) = rem(rows(ii),dim1)+1;
        end
        if columns(ii) < dim2
           columns(ii) = rem(dim2,columns(ii))+1;
        else
           columns(ii) = rem(columns(ii),dim2)+1;
        end
        A(rows(ii),columns(ii)) = 1;
    end
    rows = jj*cumsum(double(columns))+round(dim2/2);  % Each pass is diff.
    columns = jj*cumsum(double(rows))+round(dim1/2);
    if jj > ceil(7000/length(key))+2  % Estimate how many iters. needed.
       idx = find(A==1);
    end
   jj = jj+1;
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -