java - Steganography program giving weird results -
i developing steganography program computer programming class. appears gives random ascii symbols. output supposed binary. encode message method given teacher. have program decode part.
import java.awt.*; class hidemessage { public void encodemessage(picture stegoobject, int[] binaryarray) { pixel pixeltarget = new pixel(stegoobject, 0, 0); pixel[] pixelarray = stegoobject.getpixels(); color pixelcolor = null; int redvalue = 0; (int x = 0; x < binaryarray.length; x++) { redvalue = binaryarray[x]; pixeltarget = pixelarray[x]; pixeltarget.setred(redvalue); } pixeltarget = pixelarray[binaryarray.length]; pixeltarget.setred(255); system.out.println("finishedpic"); stegoobject.write("secretmessage.bmp"); stegoobject.explore(); } public void decodemessage(picture decodepic) { int redvalue = 0; pixel targetpixel = null; color pixelcolor = null; int sum = 0; (int x = 0; redvalue < 2; x++) { //inside nested loop traverse image left right (int count = 1; count < 9; count++) { targetpixel = decodepic.getpixel(count + (8 * x), 0); //gets x,y coordinate of target pixel pixelcolor = targetpixel.getcolor(); //gets color of target pixel redvalue = pixelcolor.getred(); if (redvalue == 1) { if (count == 1) { sum = sum + 128; } if (count == 2) { sum = sum + 64; } if (count == 3) { sum = sum + 32; } if (count == 4) { sum = sum + 16; } if (count == 5) { sum = sum + 8; } if (count == 6) { sum = sum + 4; } if (count == 7) { sum = sum + 2; } if (count == 8) { sum = sum + 1; } } system.out.println(sum); } system.out.println((char)sum); sum = 0; } //end of inner loop } } public class hidemessagetester { public static void main(string[] args) { int[] bitarray = { 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1 }; //int[] bitarray = { 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; picture stegoobject = new picture("earth.bmp"); hidemessage stego = new hidemessage(); stego.encodemessage(stegoobject, bitarray); picture decodeobject = new picture("secretmessage.bmp"); system.out.println("now decoding"); stego.decodemessage(decodeobject); } }
first, general pieces of advice: think program overly complicated because functions commingling responsibilities:
picture stegoobject = new picture("earth.bmp"); hidemessage stego = new hidemessage(); stego.encodemessage(stegoobject, bitarray); picture decodeobject = new picture("secretmessage.bmp"); system.out.println("now decoding"); stego.decodemessage(decodeobject);
i very surprised see secretmessage.bmp
; wasn't @ obvious trying decode object had created. sure, upon reading encodemessage()
method easy enough determine came from, think flow have been easier:
/* encode */ picture pic_to_steg = new picture("foo.bmp"); hidemessage stego = new hidemessage(); picture secret = stego.encodemessage(pic_to_steg, bitarray); secret.write("secretmessage.bmp"); /* decode */ picture pic_with_message = new picture("secretmessage.bmp"); int[] hidden = stego.decodemessage(pic_with_message); /* output `hidden` , compare against `bitarray` */
in other words: leave file io entirely main flow of program. perhaps routines called network server in future, , pictures never saved disk. modification far easier if routines operate on picture
s , return amended picture
s , int[]
.
can test encodemessage()
method in isolation? perhaps @ differences in between input file , output file. section looks troublesome:
public void encodemessage(picture stegoobject, int[] binaryarray) { pixel pixeltarget = new pixel(stegoobject, 0, 0); pixel[] pixelarray = stegoobject.getpixels(); color pixelcolor = null; int redvalue = 0; (int x = 0; x < binaryarray.length; x++) { redvalue = binaryarray[x]; pixeltarget = pixelarray[x]; pixeltarget.setred(redvalue); } pixeltarget = pixelarray[binaryarray.length]; pixeltarget.setred(255);
is pixelarray
reference image can updated through simple assignment? i'd expect design more pseudo-code:
pixel p = image.getpixel(x, y); p.setred(binaryarray[i]); image.setpixel(x, y, p);
the decoding has strange loops:
(int x = 0; redvalue < 2; x++) { //inside nested loop traverse image left right (int count = 1; count < 9; count++) {
this loop might work designed it, upon first reading, feels wrong: start x=0
, increment x
each time through loop, use redvalue < 2
loop termination rule.
i rather see loop written this:
int x = 0; while (redvalue < 2) { /* stuff */ x++; }
(it isn't identical; x
still valid outside loop, can dangerous. however, think more clear.)
there cases termination clause of for
loop isn't related setup or increment clauses -- in experience, very rare.
in case though, feels mistake; condition redvalue < 2
loop invariant, inner loop assumes happen on pixels multiples of 8, assumption not enforced in encodemessage()
method.
trying compute integer value redvalue
s read them needlessly complicating decode routine. suggest removing inner loop , return array array passed encodemessage()
routine. (a) easier (b) easier debug (c) easier test (d) thousand times easier handle writing bit arrays aren't evenly divisible 8.
then write second method turns bit array output sum, or ascii characters, or ebcdic characters, or rsa key parameters, or whatever that's being encoded. don't try @ once. writing separate method decode array of bits (a) easier (b) easier debug (c) easier test (d) thousand time easier handle arbitrary output modifications.
i hope these hints help.
Comments
Post a Comment