techniques used in digital watermaking - java

i am trying to implement a new digital watermarking system,this is the embedding procedure
the reference paper is available in the following link
http://www.4shared.com/folder/UNjahlTS/_online.html
i cannot understand the embedding procedure so plz can anyone help,thanks
private byte[] encode_text(byte[] image, byte[] addition, int offset)
{
//check that the data + offset will fit in the image
if (addition.length + offset > image.length) {
throw new IllegalArgumentException("File not long enough!");
}
//loop through each addition byte
for (int i = 0; i < addition.length; ++i) {
//loop through the 8 bits of each byte
int add = addition[i];
for (int bit = 7; bit >= 0; --bit, ++offset) //ensure the new offset value carries on through both loops
{
//assign an integer to b, shifted by bit spaces AND 1
//a single bit of the current byte
int b = (add >>> bit) & 1;
//assign the bit by taking: [(previous byte value) AND 0xfe] OR bit to add
//changes the last bit of the byte in the image to be the bit of addition
image[offset] = (byte) ((image[offset] & 0xFE) | b);
}
}
return image;
}
this is the embedding procedure

This algorithm just replace the last bit from the image pixel and replace it with the bit from the addition byte which you want to hidden it in the image
The inputs for the Method :
byte[] image: your image in which you will hidden your data,
byte[] addition: the data which you want to hidden it,
int offset: a variable will determine the start index which you will hidden from it (it is just a trick, you don't need to start the hidden from the 0 index , it's up to you).
Then you will loop on the addition array , let's say the first byte in the array is 10
the byte for it is (00001010) this data you will embedded it in b pixel.
Lets see how?
Assuming that the image[offset] = 20 ---> let's say offset=0;
int b = (add >>> bit) & 1;---->in the start loop will be (00001010)
^
Then I will replace the last significant bit in the image[offset] by this addition bit 0
image[offset] = 20------------->00010100 , when I replace the LSB1 by 0
It will be 00010100---------> 20
So , I will set the new image[offset] value in the array by 20 which contain 0 bit information
Lets say the b = 1 , image[offset] = 20
So, when I replace the LSB2 in
(20)---->00010100 by the 1 it will be 00010101
^ ^
which is equal to (21) , so 21 is the new value after you embed 1
1, 2:LSB Means: lest significant bit.

Related

What is the purpose of low and high nibble when converting a string to a HexString

Recently I have been going through some examples of MD5 to start getting an understanding of security and MD5 has been fairly simple to understand for the most part and a good starting point even though it is no longer secure. Despite this I have a question regarding high and lo nibbles when it comes to converting a string to a hex string.
So I know high and low nibbles are equal to half a byte or also can be hex digits that represent a single hexadecimal digit. What I am not understanding though is exactly how they work and the purpose that they serve. I have been searching on google and I can't find much of an answer that will help explain what they do in the context that they are in. Here is the context of the conversion:
private static String toHexString( byte[] byteArray )
{
final String HEX_CHARS = "0123456789ABCDEF";
byte[] result = new byte[byteArray.length << 1];
int len = byteArray.length;
for( int i = 0 ; i < len ; i++ )
{
byte b = byteArray[i]
int lo4 = b & 0x0F;
int hi4 = ( b & 0xF0 ) >> 4;
result[i * 2] = (byte)HEX_CHARS.charAt( hi4 );
result[i * 2 + 1] = (byte)HEX_CHARS.charAt( lo4 );
}
return new String( result );
}
I don't exactly understand what is going on in the for statement. I would appreciate any help understanding this and if there is some link to some places that I can learn more about this please also leave it.
I understand the base definition of nibble but not the operations and what the assignment to the number 4 is doing either.
If I need to post the full example code I will just ask as I am unsure if it is needed.
This code simply converts a byte array to hexadecimal representation. Within the for-loop, each byte is converted into two characters. I think it's easier to understand it on an example.
Assume one of the bytes in your array is, say, 218 (unsigned). That's 1101 1010 in binary.
lo4 gets the lowest 4 bits by AND-ing the byte with the bitmask 00001111:
int lo4 = b & 0x0F;
This results in 1010, 10 in decimal.
hi4 gets the highest 4 bits by AND-ing with the bitmask 1111 0000 and shifting 4 bits to the right:
int hi4 = ( b & 0xF0 ) >> 4;
This results in 1101, 13 in decimal.
Now to get the hexadecimal representation of this byte you only need to convert 10 and 13 to their hexadecimal representations and concatenate. For this you simply look up the character in the prepared HEX_CHARS string at the specific index. 10 -> A, 13 -> D, resulting in 218 -> DA.
It's just bit operations. The & character takes the literal bit value of each and does a logical and on them.
int lo4 = b & 0x0F;
for instance if b = 24 then it will evaluate to this
00011000
+00001111
=00001000
The second such line does the same on the first four bits.
00011000
+11110000
=00010000
the '>>' shifts all of the bits a certain number in that direction so
00010000 >> 4 = 00000001.
This is done so that you can derive the hex value from the number. Since each character in hex can represent 4 bits by splitting the number into pieces of 4 bits we can convert it.
in the case of b = 24 we no have lo4 = 1000 or 8 and hi4 = 0001 or 1. The last part of the loop assigns the character value for each.
Hex_chars[hi4] = '1' and Hex_chars[lo4] = '8' which gives you "18" for that part of the string which is 24 in hex.

How to extract and display each of the four bytes of an integer individually as 8-bit values

edit: This question is not a duplicate. The whole point is to solve the question using masks and bit shifts.
I have a terrible programming teacher that introduces concepts without explaining them or providing material to understand them, and he's to arrogant and confrontational too seek help from.
So naturally, I'm stuck on yet another question without any guidance.
Given an integer variable x, write Java code to extract and display each of the four bytes of that integer individually as 8-bit values.
I'm supposed to use masking and bit shift operations to answer this question. I understand that masking means turning bits "on or off" and I understand that an integer has 32 bits or 4 bytes. But that information doesn't help me answer the question. I'm not necessarily asking for the entire solution, but any help would be appreciated.
Using masks and shifting to extract bytes from an integer variable i,
The bytes from most significant (highest) to least are:
byte b3 = (byte)((i>>24));
byte b2 = (byte)((i>>16)&255);
byte b1 = (byte)((i>>8)&255);
byte b0 = (byte)((i)&255);
out.println("The bytes are " + b3 + ", " + b2 + ", " + b1 + ", " + b0);
You could use a ByteBuffer
int myInt = 123;
byte[] bytes = ByteBuffer.allocate(4).putInt(myInt).array();
Then you can do whatever you want with it. If you want all bits you could do something like this:
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
if(bytes[i] & (1 << j))
{
System.out.print("1");
}
else
{
System.out.print("0");
}
}
System.out.print(" ");
}
I have not tested this code because I do not have Java on this PC, but if it does not work let me know. However this sould give you a ruff idea of what has to be done.
Firstly you have to understand bitwise operators and operations. ( https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html )
Boolean logic states that x & 1 = x and x & 0 = 0.
Knowing this we can create a mask for, lets say the least significant 4 bits of an 8 bit number: 11001101 & 00001111 = 1101 (205 & 0x0f = 13).
(we ignore the first 4 zeros and we got our 4 bits)
What if we need the most significant bits?
we apply the same idea, but now the mask will change, according to the bits we need: 11001101 & 11110000 = 11000000 (205 & 0xf0 = 192)
whoops... we got 4 zeros.
How can you get rid of that? Shifting to the right with 4 positions.
so 11000000 >> 4 = 1100 (most significant 4 bits)
I hope this example will help you to get a better understanding of bitwise operations.
One simple solution could be
bit0 = (x & 0xff000000) >> 24;
bit1 = (x & 0x00ff0000) >> 16;
bit2 = (x & 0x0000ff00) >> 8;
bit3 = (x & 0x000000ff);
(bit0 is MSB).
Masking isn't quite turning bits "on" or "off". It is a way to extract only the bits you want from the variable you are using. Lets say that you have the binary number 10011011 and you want the value of the rightmost 4 bits. To do this, you construct another binary number of the same length where there are 0's in the places that you don't want and 1's in the places that you do. Therefore, our binary number is 00001111. You then bitwise AND them together:
1 & 0 = 0
0 & 0 = 0
0 & 0 = 0
1 & 0 = 0
1 & 1 = 1
0 & 1 = 0
1 & 1 = 1
1 & 1 = 1
In java, using hex instead of binary since java doesn't have binary literals, this looks like
int result = 0x9B & 0x0F;
//result is 0xB (or 11 in decimal)
Bit shifting is just what it sounds like. If you have 10011111 and shift it right 2 bits you get 00100111. In java a bit shift of 2 looks like
int result = 0x9B >> 2;
For your program the idea is this:
Mask the rightmost byte of your integer
Shift integer right 8 bits
Repeat three more times

How can I extract a particular bit in Java?

I need a specific bit in a byte value stored as int value. My code is as shown below.
private int getBitValue(int byteVal, int bitShift){
byteVal = byteVal << bitShift;
int bit = (int) (byteVal >>>7);
return bit;
}
It is working when I give the bitshift as 1 but when I give the bitshift as 2 and the byteVal as 67(01000011 in binary), I get the value of 'byteVal' as 268 while 'byteVal' should be 3(000011 in binary) after the first line in the method(the left shift). What am I doing wrong here?
For some reason when I try your code I don't get what you get. For your example, if you say byteVal = 0b01000011 and bitShift = 2, then this is what I get:
byteVal = 0b01000011 << 2 = 0b0100001100
bit = (int) (0b0100001100 >>> 7) = (int) (0b010) // redundant cast
returned value: 0b010 == 2
I believe what you intended to do was shift the bit you wanted to the leftmost position, and then shift it all the way to the right to get the bit. However, your code won't do that for a few reasons:
You need to shift left by (variable length - bitShift) to get the desired bit to the place you want. So in this case, what you really want is to shift byteVal left by 6 places, not 2.
int variables are 32 bits wide, not 8. (so you actually want to shift byteVal left by 30 places)
In addition, your question appears to be somewhat contradictory. You state you want a specific bit, yet your example implies you want the bitShift-th least significant bits.
An easier way of getting a specific bit might be to simply shift right as far as you need and then mask with 1: (also, you can't use return with void, but I'm assuming that was a typo)
private int getBitValue(int byteVal, int bitShift) {
byteVal = byteVal >> bitShift; // makes the bitShift-th bit the rightmost bit
// Assumes bit numbers are 0-based (i.e. original rightmost bit is the 0th bit)
return (int) (byteVal & 1) // AND the result with 1, which keeps only the rightmost bit
}
If you want the bitShift-th least significant bits, I believe something like this would work:
private int getNthLSBits(int byteVal, int numBits) {
return byteVal & ((1 << numBits) - 1);
// ((1 << numBits) - 1) gives you numBits ones
// i.e. if numBits = 3, (1 << numBits) - 1 == 0b111
// AND that with byteVal to get the numBits-th least significant bits
}
I'm curious why the answer should be 3 and I think we need more information on what the function should do.
Assuming you want the value of the byteVal's lowest bitShift bits, I'd do the following.
private int getBitValue(int byteVal, int bitShift){
int mask = 1 << bitShift; // mask = 1000.... (number of 0's = bitShift)
mask--; // mask = 000011111 (number of 1's = bitShift)
return (byteVal & mask);
}
At the very least, this function will return 1 for getBitValue(67, 1) and 3 for getBitValue(67,2).

Splitting a byte into bits

I have a byte array i.e from byte[0] to byte[2]. I want to first split byte[0] into 8 bits. Then bytes[1] and finally bytes[2]. By splitting I mean that if byte[0]=12345678 then i want to split as variable A=8,Variable B=7, variable C=6,Variable D=5,........ Variable H=0. How to split the byte and store the bits into variables? I want to do this in JAVA
well the bitwise operations seem to be almost what you're talking about.
a byte is composed of 8 bits, and so it goes in the rage of 0 to 255.
written in binary that's 00000000 to 11111111.
Bitwise operations are those that basically use masks to get out as much info as possible out of a byte.
Say for instance you have your 1101 0011 byte (space added for visibility only) = 211 (decimal). You can split that into 2 "variables" b1 and b2 of half a byte each. they'll thus cover the range of 0 to 15.
How you do this is by defining some masks. A mask to get your first half-a-byte-value would be 0000 1111.
You take your value of 11010011 apply the bitwise and (& ) operator to it.
So saying byte b = 211; byte mask1=15; OR byte b=0x11010011; byte mask1=0x00001111;
you then have your variable byte b1=b & mask1;
Thus applying that operation would result in b1=00000011 = 3;
With a mask byte mask2=0x11110000; applying the same operation on b, you'd get byte b2=mask2 & b = 0x11010000;
Now of course that leaves the number b2 possibly too large for you. All you have to do if you want to grab the value 0x1101 is to right shift it. Thus b2>>=4;
You can have your masks in any form, but it's usual to have them in decimal as the powers of 2 (so that you can take any bit out of your byte) or decide what range you want on your variables and make the mask "larger" like 0x00000011, or ox00001100. Those 2 masks would respectively get you 2 values from a byte, each value ranging from 0 to 3, values that you can fit 4 inside a byte.
for more info, chek out the relevant wiki.
Sorry, the values were a little off (since byte seems to go from -128 to 127, but the idea is the same.
Second edit (never used bitwise operations myself lol)... the "0x" notation is for hexadecimals. So you'll actually have to calculate for yourself what 01001111 actually means... pretty sucky :| but it's gonna do the trick.
boolean a = (theByte & 0x1) != 0;
boolean b = (theByte & 0x2) != 0;
boolean c = (theByte & 0x4) != 0;
boolean d = (theByte & 0x8) != 0;
boolean e = (theByte & 0x10) != 0;
boolean f = (theByte & 0x20) != 0;
boolean g = (theByte & 0x40) != 0;
boolean h = (theByte & 0x80) != 0;

Convert Bytes to bits

I'm working with java.
I have a byte array (8 bits in each position of the array) and what I need to do is to put together 2 of the values of the array and get a value.
I'll try to explain myself better; I'm extracting audio data from a audio file. This data is stored in a byte array. Each audio sample has a size of 16 bits. If the array is:
byte[] audioData;
What I need is to get 1 value from samples audioData[0] and audioData[1] in order to get 1 audio sample.
Can anyone explain me how to do this?
Thanks in advance.
I'm not a Java developer so this could be completely off-base, but have you considered using a ByteBuffer?
Assume the LSB is at data[0]
int val;
val = (((int)data[0]) & 0x00FF) | ((int)data[1]<<8);
As suggested before, Java has classes to help you with this. You can wrap your array with a ByteBuffer and then get an IntBuffer view of it.
ByteBuffer bb = ByteBuffer.wrap(audioData);
// optional: bb.order(ByteOrder.BIG_ENDIAN) or bb.order(ByteOrder.LITTLE_ENDIAN)
IntBuffer ib = bb.asIntBuffer();
int firstInt = ib.get(0);
ByteInputStream b = new ByteInputStream(audioData);
DataInputStream data = new DataInputStream(b);
short value = data.readShort();
The advantage of the above code is that you can keep reading the rest of 'data' in the same way.
A simpler solution for just two values might be:
short value = (short) ((audioData[0]<<8) | (audioData[1] & 0xff));
This simple solution extracts two bytes, and pieces them together with the first byte being the higher order bits and the second byte the lower order bits (this is known as Big-Endian; if your byte array contained Little-Endian data, you would shift the second byte over instead for 16-bit numbers; for Little-Endian 32-bit numbers, you would have to reverse the order of all 4 bytes, because Java's integers follow Big-Endian ordering).
easier way in Java to parse an array of bytes to bits is JBBP usage
class Parsed { #Bin(type = BinType.BIT_ARRAY) byte [] bits;}
final Parsed parsed = JBBPParser.prepare("bit:1 [_] bits;").parse(theByteArray).mapTo(Parsed.class);
the code will place parsed bits of each byte as 8 bytes in the bits array of the Parsed class instance
You can convert to a short (2 bytes) by logical or-ing the two bytes together:
short value = ((short) audioData[0]) | ((short) audioData[1] << 8);
I suggest you take a look at Preon. In Preon, you would be able to say something like this:
class Sample {
#BoundNumber(size="16") // Size of the sample in bits
int value;
}
class AudioFile {
#BoundList(size="...") // Number of samples
Sample[] samples;
}
byte[] buffer = ...;
Codec<AudioFile> codec = Codecs.create(AudioFile.class);
AudioFile audioFile = codec.decode(buffer);
You can do it like this, no libraries or external classes.
byte myByte = (byte) -128;
for(int i = 0 ; i < 8 ; i++) {
boolean val = (myByte & 256) > 0;
myByte = (byte) (myByte << 1);
System.out.print(val ? 1 : 0);
}
System.out.println();
byte myByte = 0x5B;
boolean bits = new boolean[8];
for(int i = 0 ; i < 8 ; i++)
bit[i] = (myByte%2 == 1);
The results is an array of zeros and ones where 1=TRUE and 0=FALSE :)

Categories

Resources