How do I run the following code
Show older comments
Please ignore the option2 in every menu-driven selection as I need to only include text within an image and then obtain the text back !!!!
The code is :
function [output] = steganography()
%STEGANOGRAPHY: This Function lets a user interactively
% choose to encode a hidden message within a "canvas image" or decode a
% hidden message hidden within a "canvas image".
%
% INPUTS: NONE, the user will select them as the program executes.
%
% OUTPUTS:
% - output: Either an Encoded "Canvas Image" or a Decoded Message.
%%David Pipkorn and Preston Weisbrot
% Project: Steganography - Hidden Messages in Images
%
%%STEP 1: Determine Whether User is Encoding or Decoding a Message
enc_dec = input('Welcome to the Steganography Program \nEnter 1 for Encoding, 2 for Decoding:\n');
if enc_dec == 1
%%STEP A: ENCODING VERSION
%%STEP 2A: Select "Canvas Image" and "Message File".
% First Get "Canvas" Image.
[FileName,PathName] = uigetfile({'*.jpg';'*.png';'*.gif';'*.bmp'},'Select "Canvas Image" to Hide Message.');
img = imread( strcat(PathName,FileName) );
% Next get Message File
msg_type = input('Enter 1 for TEXT Message, 2 for IMAGE Message:\n');
if msg_type == 1
[FileName,PathName] = uigetfile('*.txt','Select TEXT MESSAGE.');
testmsg = fopen( strcat(PathName,FileName) );
[msg] = fscanf(testmsg,'%c');
elseif msg_type == 2
[FileName,PathName] = uigetfile({'*.jpg';'*.png';'*.gif';'*.bmp'},'Select IMAGE MESSAGE.');
msg = imread( strcat(PathName,FileName) );
else
error('Invalid Message Type Selection');
end
%%STEP 3A: Prompt User for Encryption Key
enc_key = input('Please Enter an Encryption Key Between 0 - 255:\n');
if enc_key < 0 || enc_key > 255
error('Invalid Key Selection');
end
enc_key = uint8(enc_key);
%%STEP 4A: Allow User to Select SEQUENTIAL or RANDOM Encoding Method
encode = input('Enter 1 for Sequential Encoding, 2 for Random Encoding:\n');
if encode == 1
% SEQUENTIAL ENCODING: This only needs an Encryption Key Input.
output = stegancoder(img,msg,enc_key);
elseif encode == 2
% RANDOM ENCODING: This needs the Encryption Key AND Random Seed
% Value.
% Random Seed Value
randSeed = input('Please Enter Random Seed Value Between 1 - 100:\n');
if randSeed < 1 || randSeed > 100
error('Invalid Random Seed Value')
end
randSeed = uint8(randSeed);
% Final Output
output = stegancoder_Rand(img,msg,enc_key,randSeed);
else
error('Invalid Encoding Selection');
end
%%STEP 5A: Write Canvas Image to .BMP File
% BMP, or bitmap format, was chosen because it DOES NOT use
% compression. JPEG compression destroys the message.
secfn = input('Enter File Name for Image + Message:\n','s');
nametest = ischar(secfn);
if nametest == 1
imwrite(output,strcat(secfn,'.bmp'));
else
error('Invalid File Name');
end
elseif enc_dec == 2
%%STEP B: DECODING VERSION
%%STEP 2B: Import "Canvas Image" With Hidden Message.
[FileName,PathName] = uigetfile('*.bmp','Select "Canvas Image" With Hidden Message.');
img = imread( strcat(PathName,FileName) );
%%STEP 3B: Prompt User for Encryption Key
enc_key = input('Please Enter an Encryption Key Between 0 - 255:\n');
if enc_key < 0 || enc_key > 255
error('Invalid Key Selection');
end
enc_key = uint8(enc_key);
%%STEP 4B: Allow User to Select SEQUENTIAL or RANDOM Decoding Method
decode = input('Enter 1 for Sequential Decoding, 2 for Random Decoding:\n');
if decode == 1
% SEQUENTIAL DECODING: This only needs an Encryption Key Input.
output = stegandecoder(img,enc_key);
elseif decode == 2
% RANDOM DECODING: This needs the Encryption Key AND Random Seed
% Value.
% Random Seed Value
randSeed = input('Please Enter Random Seed Value Between 1 - 100:\n');
if randSeed < 1 || randSeed > 100
error('Invalid Random Seed Value')
end
randSeed = uint8(randSeed);
% Final Output
output = stegandecoder_Rand(img,enc_key,randSeed);
else
error('Invalid Encoding Selection');
end
%%STEP 5B: Writing Message to .TXT or .JPG File
secfn = input('Enter File Name for Image + Message:\n','s');
nametest = ischar(secfn);
if nametest == 1
msgtest = ischar(output);
if msgtest == 1
% TEXT Message CASE
fid = fopen(strcat(secfn,'.txt'),'w');
fwrite(fid,output,'char');
fclose(fid);
else
% IMAGE Message CASE
imwrite(output,strcat(secfn,'.bmp'));
end
else
error('Invalid File Name');
end
else
error('Invalid Selection');
end
function [J] = stegancoder(img,msg,enc_key)
% STEGANCODER: This function "hides" a message within an image that the
% user provides. The final output is an image file that contains the
% message protected by encryption and encoding.
% This function will eventually be expanded to randomly "hide" the message
% across the "canvas" message using the STEGANCODER_RAND Function.
%
% INPUTS:
% - img: This is the "clean" original image that will be used to hide our
% secret message.
% - msg: This is the information to be hidden within the original image.
% This can be a text file or another image file. Image files will
% be converted to GRAYSCALE IMAGES.
% - enc_key: This is the Encryption Key used for Symmetric XOR Encryption.
% THIS MUST BE THE SAME FOR SUCCESSFUL DECRYPTION!
%
% OUTPUTS:
% - J: Final image contains the encoded and/or encrypted message
%%David Pipkorn and Preston Weisbrot
% Project: Steganography - Hidden Messages in Images
%%Step 1: Determining Message Type and Normalizing
% The MATLAB Function 'double' is extremely useful for converting both
% text files into a useful form. If the message is ASCII formatted text,
% double will return the integer values for each character.
% So, 'Hello World' is: 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100
% For image files we will use 'im2unit8', which forces the pixel values to
% be represented as integers between 0-255 (just like the text values).
msgtype = ischar(msg); % If message is text this will be true;
% false otherwise
if msgtype == 1 % Message = TEXT
msg_temp = double(msg); % Converts from ASCII to Integer Values.
msg_dim = num2str(length(msg_temp));
msg_length = length(msg_dim);
z = 0;
if msg_length < 7
padtext = 7 - msg_length;
for z = 1:padtext
msg_dim = horzcat('0',msg_dim);
end
msg_head = horzcat('t',msg_dim);
% Applying Header To Beginning of Message to be Encoded.
msg_temp_head = horzcat(msg_head,msg_temp);
end
else
% Message = IMAGE
msg = im2uint8(msg); % Convert to Integer Value Representation.
msg_temp = rgb2gray(msg); % Converts Hidden Message to Grayscale.
% Reduces Amount of Data to Hide.
% Determine Message Image's Size for Encoding in Header
[hideM1,hideN1] = size(msg_temp);
hideM = num2str(hideM1);
hideN = num2str(hideN1);
dimM = length(hideM);
dimN = length(hideN);
padM = 0; padN = 0;
z = 0;
if dimM < 4
padM = 4 - dimM;
for z = 1:padM
% Zero Padding Dimension if less than 4 Sig Figs.
hideM = horzcat('0',hideM);
end
end
z = 0;
if dimN < 4
padN = 4 - dimN;
for z = 1:padN
% Zero Padding Dimension if less than 4 Sig Figs.
hideN = horzcat('0',hideN);
end
end
msg_head = horzcat(hideM,hideN);
msg_temp_head = msg_head;
y = 0; k = hideM1;
for y = 1:k
% Applying Header To Beginning of Message to be Encoded.
msg_temp_head = horzcat(msg_temp_head,msg_temp(y,:));
end
end
%%Step 2: Ensuring Sufficient "Hiding Space"
% tot_hiding_pix = max(cumprod(size(img)));
% tot_data = max(cumprod(size(msg_temp_head)));
%
% if tot_hiding_pix <= tot_data
% error('Insufficient Hiding Space in Image')
% end
%%Step 3: Encrypting Using XOR Key
% key = 42; % Used for Test Phase
msg_enc = bitxor(uint8(msg_temp_head),uint8(enc_key));
msg_enc_set = dec2bin(msg_enc, 8);
%%Step 4: Preparing Hiding Canvas
img_prep = im2uint8(img);
%%Step 5: Hiding Data
% I will try to hide the data points using a RGBBGRRG Order. I will be
% hiding this data along the columns moving from left to right through
% the target image.
rm = 1; gm = 1; bm = 1; % Initializing Counters
rn = 1; gn = 1; bn = 1;
[maxM,maxN] = size(img_prep);
z = 0;
% RUN_TIME Variable indicates the number of Message "Words" that need to be
% encoded in the IMG_PREP "Canvas" Image.
run_time = length(msg_enc_set);
for z = 1:run_time;
temp_code = msg_enc_set(z,:);
% Bit 1: Red
if str2double(temp_code(1)) == 0
img_prep(rm,rn,1) = bitand(img_prep(rm,rn,1),uint8(254));
else
img_prep(rm,rn,1) = bitor(img_prep(rm,rn,1),uint8(1));
end
rm = rm + 1;
% This next step is used to determine whether or not we have reached
% the end end of the image. We then need to move to the next column
% and reset our pattern to the top row. Since we have no idea when we
% will reach this point we have to check this EVERY time after we
% increase the rm/gm/bm counter.
if rm > maxM
rn = rn + 1;
rm = 1;
end
% Bit 2: Green
if str2double(temp_code(2)) == 0
img_prep(gm,gn,2) = bitand(img_prep(gm,gn,2),uint8(254));
else
img_prep(gm,gn,2) = bitor(img_prep(gm,gn,2),uint8(1));
end
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
end
% Bit 3: Blue
if str2double(temp_code(3)) == 0
img_prep(bm,bn,3) = bitand(img_prep(bm,bn,3),uint8(254));
else
img_prep(bm,bn,3) = bitor(img_prep(bm,bn,3),uint8(1));
end
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Bit 4: Blue
if str2double(temp_code(4)) == 0
img_prep(bm,bn,3) = bitand(img_prep(bm,bn,3),uint8(254));
else
img_prep(bm,bn,3) = bitor(img_prep(bm,bn,3),uint8(1));
end
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Bit 5: Green
if str2double(temp_code(5)) == 0
img_prep(gm,gn,2) = bitand(img_prep(gm,gn,2),uint8(254));
else
img_prep(gm,gn,2) = bitor(img_prep(gm,gn,2),uint8(1));
end
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
end
% Bit 6: Red
if str2double(temp_code(6)) == 0
img_prep(rm,rn,1) = bitand(img_prep(rm,rn,1),uint8(254));
else
img_prep(rm,rn,1) = bitor(img_prep(rm,rn,1),uint8(1));
end
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
end
% Bit 7: Red
if str2double(temp_code(7)) == 0
img_prep(rm,rn,1) = bitand(img_prep(rm,rn,1),uint8(254));
else
img_prep(rm,rn,1) = bitor(img_prep(rm,rn,1),uint8(1));
end
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
end
% Bit 8: Green
if str2double(temp_code(8)) == 0
img_prep(gm,gn,2) = bitand(img_prep(gm,gn,2),uint8(254));
else
img_prep(gm,gn,2) = bitor(img_prep(gm,gn,2),uint8(1));
end
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
end
end
%%Step 6: Final Output
J = img_prep; % Final Encoding Output
% J = msg_enc_set; % ENCRYPTION STEP TEST OUTPUT
end
function [msg] = stegandecoder(img,enc_key)
% STEGANDECODER: This function "reveals" hidden messages by reversing the
% processing steps completed by the STEGANCODER Function.
%
% INPUTS:
% - img: This is image contains a hidden message that needs to be decoded.
% - enc_key: This is the Encryption Key used for Symmetric XOR Decryption.
% THIS MUST BE THE SAME AS ENCRYPTION STEP FOR SUCCESSFUL
% DECRYPTION!
%
% OUTPUTS:
% - msg: This output file will either be a grayscale image or a hidden text
% message that was encoded into the original image.
%%David Pipkorn and Preston Weisbrot
% Project: Steganography - Hidden Messages in Images
%%Step 1a: Recover Header Set
rm = 1; gm = 1; bm = 1; % Initializing Counters
rn = 1; gn = 1; bn = 1;
header = [];
[maxM, maxN, chan] = size(img);
for z = 1:8;
temp = zeros(1,8);
% Red
temp(1,1) = mod(img(rm,rn,1),2);
rm = rm + 1;
% This next step is used to determine whether or not we have reached
% the end end of the image. We then need to move to the next column
% and reset our pattern to the top row. Since we have no idea when we
% will reach this point we have to check this EVERY time after we
% increase the rm/gm/bm counter.
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Green
temp(1,2) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
% Blue
temp(1,3) = mod(img(bm,bn,3),2);
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Blue
temp(1,4) = mod(img(bm,bn,3),2);
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Green
temp(1,5) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
% Red
temp(1,6) = mod(img(rm,rn,1),2);
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Red
temp(1,7) = mod(img(rm,rn,1),2);
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Green
temp(1,8) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
tempstr = num2str(temp);
header = vertcat(header,tempstr);
end
%%Step 1b: Header Analysis - Decrypt and Determine Message Dimensions
% key = 42; % Used for Test Phase
msg_head_set = bin2dec(header);
temp_head = bitxor(uint8(msg_head_set),uint8(enc_key));
% Case 1: If the Header starts with 't' it is a text file.
% Case 2: If the Header DOESN'T start with 't' then the message is an image
% with the dimensions described in the header.
if temp_head(1) == 116
% CASE 1: Text Set
dim1 = char(temp_head(2:8));
m = str2double(dim1);
n = 1;
else
% CASE 2: Image Set
% Determine Dimensions from Header Values
tempm = char(temp_head(1:4));
tempn = char(temp_head(5:8));
m = str2double(tempm');
n = str2double(tempn');
end
%%Step 2: Isolate Potential Message
% Recall in Step 5 of the STEGANCODER Function we used a RGBBGRRG Cycle to
% encode the message set. In this step we need to reverse this process
% using MODULO arithmatic.
z = 0;
enc_msg = [];
stopmax = (m * n);
for z = 1:stopmax
temp = zeros(1,8);
% Red
temp(1,1) = mod(img(rm,rn,1),2);
rm = rm + 1;
% This next step is used to determine whether or not we have reached
% the end end of the image. We then need to move to the next column
% and reset our pattern to the top row. Since we have no idea when we
% will reach this point we have to check this EVERY time after we
% increase the rm/gm/bm counter.
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Green
temp(1,2) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
% Blue
temp(1,3) = mod(img(bm,bn,3),2);
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Blue
temp(1,4) = mod(img(bm,bn,3),2);
bm = bm + 1;
if bm > maxM
bn = bn + 1;
bm = 1;
end
% Green
temp(1,5) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
% Red
temp(1,6) = mod(img(rm,rn,1),2);
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Red
temp(1,7) = mod(img(rm,rn,1),2);
rm = rm + 1;
if rm > maxM
rn = rn + 1;
rm = 1;
if rn > maxN
break
end
end
% Green
temp(1,8) = mod(img(gm,gn,2),2);
gm = gm + 1;
if gm > maxM
gn = gn + 1;
gm = 1;
if gn > maxN
break
end
end
tempstr = num2str(temp);
enc_msg = vertcat(enc_msg,tempstr);
end
%%Step 3: Decryption Step
msg_dec_set = bin2dec(enc_msg);
msg_dec = bitxor(uint8(msg_dec_set),uint8(enc_key));
% msg_dec_set = dec2bin(msg_dec,8);
%%Step 4: Message Prep
if temp_head(1) == 116
% CASE 1: Text Set
msg_set = msg_dec;
msg_out = char(msg_set');
else
% CASE 2: Image Set
% Determine Dimensions from Header Values
tempm = char(temp_head(1:4));
tempn = char(temp_head(5:8));
m = str2double(tempm');
n = str2double(tempn');
% Reshape Message Set into an Image Output
msg_set = msg_dec;
count = 1;
msg_out = uint8(zeros(m,n));
for y = 1:m
for x = 1:n
msg_out(y,x) = msg_set(count);
count = count + 1;
end
end
msg_out = im2uint8(msg_out);
% THIS CODE Never worked for a larger "real" image so we scrapped it.
% msg_img = reshape(msg_set,m,n)';
% msg_out = im2uint8(msg_img);
end
%%Step 5: Final Output
msg = msg_out;
end
2 Comments
Walter Roberson
on 25 Jan 2014
What difficulty did you have when you followed the prompts ?
Answers (0)
Categories
Find more on High Dynamic Range Images in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!