How does this piece of code verify a checksum? - java

Context:
My teacher ported the Darwin-OP Framework from C++ to Java, allowing students like me to use it without having to master C++. Darwin has two controllers: the main controller runs Linux and runs the java code, and has a serial connection with the sub controller (a microcontroller) that controls all the sensors/servo's/transducers etc.
Darwin uses a motion.bin file in which it stores a list of 256 pages. Each page is 512 (8 * 64) bytes, and consists of 7 steps (64 bytes each) plus a page header (also 64 bytes). Each steps contains positions (a value between 0-4095) for the servo to take. So for Darwin to move his arm, he goes through (<7) amount of steps until he finishes the final step.
Inside the page header there is a checksum of 1 byte. The Java code contains two methods in which the checksum is calculated and verified:
private static boolean VerifyChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
if (checksum != (byte)0xFF) {
return false;
}
return true;
}
private static void SetChecksum(PAGE page) {
byte checksum = (byte)0x00;
byte[] pagebytes = page.GetBytes();
page.header.checksum = (byte)0x00;
for (int i = 0; i < pagebytes.length; i++) {
checksum += pagebytes[i];
}
page.header.checksum = (byte)((byte)0xFF - checksum);
}
Main question: Can someone explain how the checksum is verified? I don't understand why it checks checksum != (byte)0xFF. Why not just compare the calculated checksum to page.header.checksum?
Bonus question: Why check the file integrity in the first place? Would it be that common for a page inside a .bin file to become corrupted?

To compute the checksum, you perform an XOR of all the bytes in the file, then return 0xFF minus that value.
The file passed in to the checksum method is the final file with 0x00 in the checksum position.
sum = 0xFF - XOR(file)
For binary, addition is the same as XOR, hence the line checksum += pagebytes[i];
Your professor's verification method, will XOR the entire file. Which is to say, the original argument to the checksum method, and an additional byte which is the output of the checksum method.
So the expected result is then:
XOR(file, sum)
= XOR(file) + sum
= XOR(file) + 0xFF - XOR(file)
= 0xFF

Assuming the header is part of the page. Then you calculate the sum of all bytes x and store 255-x as the checksum. When verifying it, you calculate y + 255 - x which must be equal to 255. If it is, x and y are the same number.
Note that all calculations are performed modulo 256, therefore x and y are always in the range of 0 to 255.

Related

Decode encoded text with ASCII

I'm using below method to encode given text.
static long encodeText(String text) {
long l = 31;
for (int i = 0; i < text.length(); i++) {
l = l * 47 + text.getBytes()[i] % 97;
}
return l;
}
When i call above method as encodeText("stackoverflow"), return the encoded text 3818417496786881978.
Now i want to provide encoded text and get String value. For example, if i give 3818417496786881978 to decodeText(long encoded), i need to get output as stackoverflow.
static String decodeText(long encoded) {
String str = null;
// decode steps here
return str;
}
How can i do this ?
Think this through logically: the clear text "stackoverflow" when represented as 7-bit ASCII represents 13 times 7 bits (=91 bits) of information. Thats more than a long (64 bits) can hold. So your encoding will lose information, making decoding impossible.
That should be also quite apparent from the formula you use:
l = l * 47 + text.getBytes()[i] % 97;
For each charcter you get a number between 0 and 96 (you already loosing information in the modulo, reducing information to 97 possible characters (e.g. you cannot distinguish between the bytes 1 and 98 after the modulo any more). Then you multiply your long by a number less than 97 (47), so two consecutive characters will overlap in terms of information distribution in the cyphertext.
Finally, after adding more an more characters, the long simply overflows and the topmost bits are simply lost.
In conclusion: If you want to decode the cyphertext ever again, fix the loss of information in these three places.

Read value of bits in a 32bit unsigned integer in Java

I am trying to read the value of bits in an Integer in Java. I'm reading the status of a hardware device which says it returns:
Header (4 bytes):
1B + FF + 02 + m
where m is the number of bytes of status data following the m. Byte 3 should define the type of status packet.
Status Summary (4 bytes):
Each of the 32 bits of the status summary is available as a flag for the following purposes, Note that this is a 32-bit unsigned integer. Each Bit (0-31) is mostly 0 or 1.
When I read the status from the USB device, it usually returns "18". So I tried a function like so:
status_printer_error = getBit(status,0);
public int getBit(int n, int k) {
return (n >> k) & 1;
}
This doesn't seem to work though. I also tried just looping through all the bits:
for (int i = 31; i >= 0; i--) {
int s = status_sum & (1 << i);
Log.d(TAG,"bit: " + s);
}
But the results seem wrong, I am getting 0,2,0,0,16,0,0...etc (all 0's).
Here is the PDF document for the device. The printing functions all work for me, it's just the status part I'm struggling with (page 51):
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCkQFjAA&url=http%3A%2F%2Fwww.hengstler.com%2Fgfx%2Ffile%2Fshop%2Fprinter%2FeXtendo_X-80%2FD-684-112_EmulationCommandSetReference_eXtendo-E-V1_07.pdf&ei=8BaeUuLII5H3oASAxoLQDw&usg=AFQjCNF6iwxBwDsotnKUYmeWwis6ZIqX2w&bvm=bv.57155469,d.cGU
I wouldn't be treating it as an int at all. The reason is that your data comes as bytes, you are turning it into an int and then decoding the int back into bytes.
I would just parse each byte as you get it. but in answer to your question, I would print the int value as hex with Integer.toHexString(status) to make sure your int is composed as you expect. Your 18 as an int value appears to be wrong so trying to turn this into bits won't make it any more correct.
The first thing I would check is that you are not doing this.
int i = inputStream.read(); // is 8-bit not 32-bit.
This returns an int value but it is an 8-bit int value, not a 32-bit int value.
So it turns out that the method on the hardware device api only returns the length and parsing one of the arguments returned all the details I needed. So
public int getBit(int n, int k) {
return (n >> k) & 1;
}
worked when given the correct int.

Bit-wise efficient uniform random number generation

I recall reading about a method for efficiently using random bits in an article on a math-oriented website, but I can't seem to get the right keywords in Google to find it anymore, and it's not in my browser history.
The gist of the problem that was being asked was to take a sequence of random numbers in the domain [domainStart, domainEnd) and efficiently use the bits of the random number sequence to project uniformly into the range [rangeStart, rangeEnd). Both the domain and the range are integers (more correctly, longs and not Z). What's an algorithm to do this?
Implementation-wise, I have a function with this signature:
long doRead(InputStream in, long rangeStart, long rangeEnd);
in is based on a CSPRNG (fed by a hardware RNG, conditioned through SecureRandom) that I am required to use; the return value must be between rangeStart and rangeEnd, but the obvious implementation of this is wasteful:
long doRead(InputStream in, long rangeStart, long rangeEnd) {
long retVal = 0;
long range = rangeEnd - rangeStart;
// Fill until we get to range
for (int i = 0; (1 << (8 * i)) < range; i++) {
int in = 0;
do {
in = in.read();
// but be sure we don't exceed range
} while(retVal + (in << (8 * i)) >= range);
retVal += in << (8 * i);
}
return retVal + rangeStart;
}
I believe this is effectively the same idea as (rand() * (max - min)) + min, only we're discarding bits that push us over max. Rather than use a modulo operator which may incorrectly bias the results to the lower values, we discard those bits and try again. Since hitting the CSPRNG may trigger re-seeding (which can block the InputStream), I'd like to avoid wasting random bits. Henry points out that this code biases against 0 and 257; Banthar demonstrates it in an example.
First edit: Henry reminded me that summation invokes the Central Limit Theorem. I've fixed the code above to get around that problem.
Second edit: Mechanical snail suggested that I look at the source for Random.nextInt(). After reading it for a while, I realized that this problem is similar to the base conversion problem. See answer below.
Your algorithm produces biased results. Let's assume rangeStart=0 and rangeEnd=257. If first byte is greater than 0, that will be the result. If it's 0, the result will be either 0 or 256 with 50/50 probability. So 0 and 256 are twice less likely to be chosen than any other number.
I did a simple test to confirm this:
p(0)=0.001945
p(1)=0.003827
p(2)=0.003818
...
p(254)=0.003941
p(255)=0.003817
p(256)=0.001955
I think you need to do the same as java.util.Random.nextInt and discard the whole number, instead just the last byte.
After reading the source to Random.nextInt(), I realized that this problem is similar to the base conversion problem.
Rather than converting a single symbol at a time, it would be more effective to convert blocks of input symbol at a time through an accumulator "buffer" which is large enough to represent at least one symbol in the domain and in the range. The new code looks like this:
public int[] fromStream(InputStream input, int length, int rangeLow, int rangeHigh) throws IOException {
int[] outputBuffer = new int[length];
// buffer is initially 0, so there is only 1 possible state it can be in
int numStates = 1;
long buffer = 0;
int alphaLength = rangeLow - rangeHigh;
// Fill outputBuffer from 0 to length
for (int i = 0; i < length; i++) {
// Until buffer has sufficient data filled in from input to emit one symbol in the output alphabet, fill buffer.
fill:
while(numStates < alphaLength) {
// Shift buffer by 8 (*256) to mix in new data (of 8 bits)
buffer = buffer << 8 | input.read();
// Multiply by 256, as that's the number of states that we have possibly introduced
numStates = numStates << 8;
}
// spits out least significant symbol in alphaLength
outputBuffer[i] = (int) (rangeLow + (buffer % alphaLength));
// We have consumed the least significant portion of the input.
buffer = buffer / alphaLength;
// Track the number of states we've introduced into buffer
numStates = numStates / alphaLength;
}
return outputBuffer;
}
There is a fundamental difference between converting numbers between bases and this problem, however; in order to convert between bases, I think one needs to have enough information about the number to perform the calculation - successive divisions by the target base result in remainders which are used to construct the digits in the target alphabet. In this problem, I don't really need to know all that information, as long as I'm not biasing the data, which means I can do what I did in the loop labeled "fill."

techniques used in digital watermaking

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.

Reading Image from j2me to c++

I am learning c++ in order to create a little application which displays image stream. The images are coming from a j2me device which aren't stored as a file (so I just have the bytes).
I am thinking I need to send the size of the image as an int first so then the client knows how much to read for that particular image in the stream.
My problem is the size is always way too big - not the size of the image when I initially just try to read the size (I send this length in java server in a socket.write(int) and have tried dataoutputstream.writeInt). I will post some code as it's probably pretty simple.
Why is the size different to what I send?
ssize_t
readLine(int fd, char *buffer, size_t n)
{
ssize_t numRead, tt; /* # of bytes fetched by last read() */
size_t totRead; /* Total bytes read so far */
char *buf;
char ch;
if (n <= 0 || buffer == NULL) {
return -1;
}
buf = buffer; /* No pointer arithmetic on "void *" */
totRead = 0;
for (;;) {
numRead = read(fd, &ch, 1);
tt += numRead;
if (numRead == -1) {
return -1; /* Some other error */
} else if (numRead == 0) { /* EOF */
if (totRead == 0) /* No bytes read; return 0 */
return 0;
else /* Some bytes read; add '\0' */
break;
} else { /* 'numRead' must be 1 if we get here */
if (totRead < n - 1) { /* Discard > (n - 1) bytes */
totRead++;
*buf++ = ch;
}
if (ch == '\n')
break;
}
}
printf("read line %s ", buf);
fflush(stdout);
int test = (int)buf;
printf("read line int %i ", tt);
fflush(stdout);
*buf = '\0';
return totRead;
}
WBXML defines a platform independent way to write int values: Multy-byte integers.
A multi-byte integer consists of a series of octets, where the most significant bit is the continuation flag and the remaining seven bits are a scalar value. The continuation flag indicates that an octet is not the end of the multi-byte sequence. A single integer value is encoded into a sequence of N octets. The first N-1 octets have the continuation flag set to a value of one (1). The final octet in the series has a continuation flag value of zero (0).
The remaining seven bits in each octet are encoded in a big-endian order, eg, most significant bit first. The octets are arranged in a big-endian order, eg, the most significant seven bits are transmitted first. In the situation where the initial octet has less than seven bits of value, all unused bits must be set to zero (0).
For example, the integer value 0xA0 would be encoded with the two-byte sequence 0x81 0x20. The integer value 0x60 would be encoded with the one-byte sequence 0x60.
I did it for Java ME and Bada but it is pretty straightforward to implement in any language.
Your reading code handles text files, it works one char after the other, it checks for newlines, etc.
The image ("so i just have the bytes") seem to be binary data. When you interpret binary data as text, you get all sorts of random errors. These binary data may include for example a "\n", when the value of a pixel happen to be 13. It may also include "\0", which will end the string before the real end.
When store the size first, you send it as int, which is represent with 4 bytes. When you read it as 4 separate characters, you get some garbage.
You need also beware of order/endian of bytes. java uses "network order", on x86, C may read it just the other way around.
You are using the old C standard lib. It may be easier to use the C++ iostreams.

Categories

Resources