• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

DataOutputStream / WAVE steganography

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
didnt know where else to put this (as i am using the DataOutputStream to write a text file)

first off let me say i am aware of javas non unsigned types issue.
im trying to make a stego tool to hide simple .text files inside WAVE files.

the Attachment shows what i decode from the .wav file and the origonal text next to it

i'l post code if need be, i was just wondering if anyone knew offhand why it starts to work then trails off.

as it stands, i am reading one byte at a time and converting them to a BitSet(8), do i need to be reading in 2 bytes at a time or prhaps a bigger BitSet?
im also using System.arraycopy() to copy the changed byte into a new byte array (for writing).

Audio info:

Format: WAVE / PCM
Size: 55.78449630737305MBChannel Type: Sterio
Sample Rate: 44100Hz
BPS: 16
Byte Rate: 176400

i should also probably mention im using lsb technique, and at this moment the hidden bits are placed in the first x bytes of the Data Chunk of the WAVE file (x being the number of bits the .txt file is made up of)

Cheeres.
Java Greenhorn Stig.
decoded.jpg
[Thumbnail for decoded.jpg]
 
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Stephen, welcome to JavaRanch!

It sounds like a fun project, but you're not really giving us enough information to go on. How are you adding the text to the wav without corrupting it? In any case, I think you would need to get the text in a byte array, which is fairly easy because it looks like simple ASCII. Then I'd guess you'd read some data from the wav file, manipulate some bits, and then write it back to your "stego" wav file. I'm not clear why you're using a DataOutputStream though, since I think all you need to do is write bytes to a file, which you can do with a simple FileOutputStream. I'm also not clear how Java's integer types being signed affects you in any way. I assume it trails off the way it does because you're doing something wrong, but I can't guess what that would be without some more detail.
 
Stephen Longville
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi greg thanks for the warm welcome.

im not currently sure what the difference between file / data or even audio input stream (i origonaly started out using the audio input stream to read the bytes of the wav file but this didnt go too well)

this is how im encoding the wav file:



and my decoder;



theres also an issue with endians (big/small) the WAVE file is apparently little but i read somewhere most things use big (like .txt files) but i think iv encoded little endian LSB (farthest left).
its all alot to get my head arround and mabey not the best of choices for my project but yes it is fun none the less.

Cheeres.
Stig.
 
Stephen Longville
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok im now using a File input / output stream directly, tried a number of things such as changing my byte to bit and vice versa methods making sure they work.

doesnt matter what txt file i use the first 31 characters display fine and the rest is along the lines of "ol}lyèýÿïî¯ëï.ÿïï¾çï"

this is realy wierd, any ideas anyone?
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Stephen,

Sorry, I've been traveling for the past week, so I haven't had a chance to get back to you.

I looked up WAV format and found this:

Offset Contents
(hex)
0000 'R', 'I', 'F', 'F'
0004 Length of the entire file - 8 (32-bit unsigned integer)
0008 form type (4 characters)

000C first chunk type (4 character)
0010 first chunk length (32-bit unsigned integer)
0014 first chunk's data
... ...


So, I assume you want to take a character from your text file and store it in lowest order bit of each of eight (or sixteen if you allow Unicode) bytes of the WAV's data chunks. If you store it in the metadata areas (chunk type or chunk length), you will probably corrupt the WAV file. The big-endian / little-endian comes into play for you because you have to know how to interpret the length. So your algorithm is going to be something like:

ENCODE:
< Skip past RIFF header
> Write RIFF header into new file
< Read length of entire file (and maybe confirm it's long enough for your text)
> Write length into new file
while you still have chunks left
< Read chunk type
> Write chunk type into new file
< Read chunk length
> Write chunk length into new file
< Read chunk into byte array
while you have eight bytes left in chunk
get a character from your text
set low order bit of next eight bytes to the eight bits of the character
> write byte array to new file

Done! Note that when you run out of characters, you're going to want to change gears a bit and just copy the rest of the input file directly to the output file.


DECODE:
Skip past RIFF header
Skip past length of entire file
while you still have chunks left
Skip chunk type
Get chunk length
Read chunk into byte array
while there are still eight bytes left in chunk
build up a character from low order bits of the next eight bytes
add the character to a string

Done!

Actually, you will still get gibberish at the end since there's no way to check how long the original text was. Maybe you want to encode the text length into WAV file first. That's just some extra polish though.


 
Stephen Longville
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanks for the reply greg:

if slightly changed the code since my last post, i now write as soon as each byte is ready, as for your advice, unless im mistaken i belive i'v already done this

within my gui i type the size of the file to be extracted (and how many(for now just one)) just to make sure its working but i still get gibberish when i extract anything past 32 characters (or bytes).

e.g. encoding the text file with: "This is my secret message" (25 bytes) works as its short, but iv been trying it with a script of hamlet i found somwhere in .txt format (201789 bytes)

to avoid any confution heres my encoding / decoding up to date:



encoder writes new WAVE header info, then begins to loop through the file data taking each byte converting it to bits and changes it aquordingly




also heres how i convert to and from bits to bytes:





could it be a memory problem? something which makes me think so is that it gives memory errors when i try and run it in university (on holiday at the moment) so i can only run it at home.

Phew...

cheres.
 
Stephen Longville
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
P.s. if i convert the byte to a char and add it to a string (or even print it out) it still comes out the same (first 31 characters are ok and the rest is nonsence)

cheers.
 
Stephen Longville
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
i dont wanna jump to conclutions but...WOOOOOHOOOOOO i think i did it, if ya intrested i re wrote the encoder seeming doing everything the same and it didnt work then i added the else statement in this little chunck of code...

...and hey presto it workes, now i gotta tidy it up a bit...looks like a bomb hit my IDE

thanks for trying to help greg.
i'll be sure to post if it turns sour >.< (fingers crossed)

still odd though how the first 30 or so characters came out fine without this little fix
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Congratulations! Yep, little things like that can really trip you up. Incidentally, I'd guess the first 31 characters worked because the chunk of audio data started with a bunch of zeroes (or less likely a bunch of even values), so it didn't matter you weren't clearing the lsb. Once you got to audio data that had some of those bits set, you were seeing problems.
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephen Longville wrote:


As an aside, this can be shortened to

bit.set(0, bit1.get(j));
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry to post in old thread. Where is the v object declared in your code and how is it defined?

My guess is it is a Vector, but where does it get its data from in your code? Could you explain or show?

Thanks.



Also, where does this little bit of info go? I don't see it at all in your encode.

-
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephen Longville wrote:...



where is the getSubchunk() and getDataChunk located?
I cannot find one.
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Possibly from http://code.google.com/p/esn-android/source/browse/trunk/?r=138#trunk%2Fsrc%2Fesn%2Fclasses or http://www.javadocexamples.com/java_source/apo/io/fields/WaveStructure.java.html. (I know nothing about these, I found them via a quick Google search.)
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's working! but the variable v is of what type?
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
totalFileData = new byte[(int)v.elementAt(0).getFile().length()];

I'm getting an error here.
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Impossible to say, as we don't know the code where that snippet is taken from.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It;s actually taken from [ the above code ].

cheers.

[ UD: removed duplicated code - see the code posted above ]
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
V isn't declared anywhere in that code, which is either a mistake or it's declared as a member variable of the class. Given its name and the elementOf() method, I guess it is meant to be a Vector, which is a class we don't use much anymore.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So with what code do I substitute then?
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
From the context I would guess that it's a list of WAV files to be processed.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you help me with the code?I'm not quite sure how to go about it.
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ArrayList is the normal substitution for Vector. It also is basically a growable array, but it's not synchonized like Vector, so it performs better in single-threaded contexts.

What help do you need with the code exactly? Don't just say it doesn't work, but what doesn't work, where in the code the problem happens, and what the error message is. Something like that we can help with.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
totalFileData = new byte[(int)v.elementAt(0).getFile().length()];

This is where the error actually happens.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm actually tryin' to read the dataChunk into the audio data array but I don't exactly know how to go about it.
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Kordor Pyrbot wrote:totalFileData = new byte[(int)v.elementAt(0).getFile().length()];

This is where the error actually happens.



Again, please tell us what the error is. Is it a compile error or a runtime error? Do you get an error message? If not, how do you know it's an error?
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephen Longville wrote:thanks for the reply greg:

if slightly changed the code since my last post, i now write as soon as each byte is ready, as for your advice, unless im mistaken i belive i'v already done this

within my gui i type the size of the file to be extracted (and how many(for now just one)) just to make sure its working but i still get gibberish when i extract anything past 32 characters (or bytes).

e.g. encoding the text file with: "This is my secret message" (25 bytes) works as its short, but iv been trying it with a script of hamlet i found somwhere in .txt format (201789 bytes)

to avoid any confution heres my encoding / decoding up to date:



encoder writes new WAVE header info, then begins to loop through the file data taking each byte converting it to bits and changes it aquordingly




also heres how i convert to and from bits to bytes:





I'm not quite sure what's happening in line number 39 & 40.please help & what packages is the coder using?

 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey there helper.Down below is how my encoding code is.now how do I exactly append the encrypted message into the audioBytes array?kindly help.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Ulf can you help me with the insertion of text into a wave file datachunk?
 
Bartender
Posts: 3323
86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please don't keep asking for help, PatienceIsAVirtue (← click). We are all volunteers here and will help as soon as we can.
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Kordor Pyrbot wrote:Hey Ulf can you help me with the insertion of text into a wave file datachunk?



Is that related to the chunk of code you posted earlier? If so you're going to have to explain how the code is relevant. I couldn't figure out how the original question was relevant to that code -- for example I didn't see anything which looked like an encrypted message there. And now you're asking about inserting text, presumably into the byte array which that code fills? That requires explanation too.
 
Kordor Pyrbot
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Is that related to the chunk of code you posted earlier? If so you're going to have to explain how the code is relevant. I couldn't figure out how the original question was relevant to that code -- for example I didn't see anything which looked like an encrypted message there. And now you're asking about inserting text, presumably into the byte array which that code fills? That requires explanation too.



Thank you for the response.I've posted the code earlier.That was just to insert the wav file to a byte array.Let's analyze the code again.

this code is executed when my 'Encode' button on my GUI is clicked.I've extracted the audio data and it's stored in the audioBytes array.The text will be extracted from a text file chosen by the user or from a TextArea where the user may enter the text manually.Then the text will be encrypted using DES algorithm.The variable that holds this text is named 'enctext'.
Now,how do I append this text to the wave file bits contained in the audioBytes array?Do I have to convert the encrypted text 'enctext' to bits or to bytes?Kindly help me with the code to accomplished this.
reply
    Bookmark Topic Watch Topic
  • New Topic