adler32 java bitwise and of input - java

I found the code for adler32 here http://developer.classpath.org/doc/java/util/zip/Adler32-source.html
however my update code looks like following
private int a = 1, b = 0;
public void update(byte[] buf, int offset, int len)
{
for (int i = offset; i < len; i++) {
a = (a + buf[i]) % MOD_ADLER;
b = (b + a) % MOD_ADLER;
}
}
as oppose code on the link
public void update(byte[] buf, int offset, int len)
{
for (int i = offset; i < len; i++) {
a = (a + (buf[i] & 0xff)) % MOD_ADLER; // <<=== Why & 0xff ?
b = (b + a) % MOD_ADLER;
}
}
I do not understand need to AND with 0xff as buf[i] is already 8 bytes, I understand it will be promoted to int as a is int, still the type promotion shouldn't change value in byte. May be I'm missing some more details as it doesnt work without & 0xff, I tested it with the values computed by java.util.zip.Adler32
Thanks for the answer, however it will only matter for values that result in negative numbers, for example in my test
byte a = -4;
int n1 = a & 0xff;
int n2 = a;
out.printf(" a %4d %s\n", a,Integer.toBinaryString(a));
out.printf("n1 %4d %s\n",n1,Integer.toBinaryString(n1));
out.printf("n2 %4d %s\n",n2,Integer.toBinaryString(n2));
prints
a -4 11111111111111111111111111111100
n1 252 11111100
n2 -4 11111111111111111111111111111100

The problem is that byte is signed in Java. Hence, the automatic type promotion byte -> int would always give a integer in the range (-128,127) instead of (0,255), as we want. The & 0xff operation fixes that.

Related

The Inverse of a bit-shift to the left in the format 1 << n

Let's say I have the following bit masks:
1 << 1, // 2
1 << 2, // 4
1 << 3, // 8
1 << 4, // 16
1 << 5, // 32
1 << 6 // 64
I would like to get the 'inverse'.
This does the job:
void foo(int n) {
int c = 1;
while (n/2 >= 2) {
n /= 2;
c++;;
}
println(c);
}
For example, 1 << 4 resulted in 16. If I run foo(16) it prints 4.
However, I feel like it could be done a lot simpler, but I can't figure out how.
Is it possible?
BigInteger has many useful methods - including getLowestSetBit(). It probably does it as fast as it can possibly be done.
public void test() {
System.out.println(BigInteger.valueOf(16).getLowestSetBit());
}
void foo(int n)
{
println( (Math.log(n) / Math.log(2)));
//cast to int with (int) to take off decimal place
}
Returns the "inverse" bitshift as you are calling it, the base 2 logarithm.
Slightly faster and not depend on value itself.
UPDATED version
private static int foo2(int value) {
int result = 0;
int mask = 0xFFFF;
int shift = 1<<4;
for (int j = 0; j < 5; j++) {
result <<= 1;
if ((value & mask) == 0) {
result |= 1;
value >>>= shift;
}
shift >>>= 1;
mask >>= shift;
}
return result;
}

Bit shift operations on a byte array in Java

How do I shift a byte array n positions to the right? For instance shifting a 16 byte array right 29 positions? I read somewhere it can be done using a long? Would using a long work like this:
Long k1 = byte array from 0 to 7
Long k2 = byte array from 8 to 15
Then right rotating these two longs using Long.rotateRight(Long x, number of rotations).How would the two longs be joined back into a byte array?
I believe you can do this using java.math.BigInteger which supports shifts on arbitrarily large numbers. This has advantage of simplicity, but disadvantage of not padding into original byte array size, i.e. input could be 16 bytes but output might only be 10 etc, requiring additional logic.
BigInteger approach
byte [] array = new byte[]{0x7F,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
// create from array
BigInteger bigInt = new BigInteger(array);
// shift
BigInteger shiftInt = bigInt.shiftRight(4);
// back to array
byte [] shifted = shiftInt.toByteArray();
// print it as hex
for (byte b : shifted) {
System.out.print(String.format("%x", b));
}
Output
7f1122334455667 <== shifted 4 to the right. Looks OK
Long manipulation
I don't know why you'd want to do this as rotateRight() as this makes life more difficult, you have to blank at the bits that appear at the left hand side in K1 etc. You'd be better with using shift IMO as describe below. I've used a shift of 20 as divisible by 4 so easier to see the nibbles move in the output.
1) Use ByteBuffer to form two longs from 16 byte array
byte[] array = { 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77 };
ByteBuffer buffer = ByteBuffer.wrap(array);
long k1 = buffer.getLong();
long k2 = buffer.getLong();
2) Shift each long n bits to the right
int n = 20;
long k1Shift = k1 >> n;
long k2Shift = k2 >> n;
System.out.println(String.format("%016x => %016x", k1, k1Shift));
System.out.println(String.format("%016x => %016x", k2, k2Shift));
0000111122223333 => 0000000001111222
4444555566667777 => 0000044445555666
Determine bits from k1 that "got pushed off the edge"
long k1CarryBits = (k1 << (64 - n));
System.out.println(String.format("%016x => %016x", k1, k1CarryBits));
0000111122223333 => 2333300000000000
Join the K1 carry bits onto K2 on right hand side
long k2WithCarray = k2Shift | k1CarryBits;
System.out.println(String.format("%016x => %016x", k2Shift, k2WithCarray));
0000044445555666 => 2333344445555666
Write the two longs back into a ByteBuffer and extract as a byte array
buffer.position(0);
buffer.putLong(k1Shift);
buffer.putLong(k2WithCarray);
for (byte each : buffer.array()) {
System.out.print(Long.toHexString(each));
}
000011112222333344445555666
Here is what I came up with to shift a byte array by some arbitrary number of bits left:
/**
* Shifts input byte array len bits left.This method will alter the input byte array.
*/
public static byte[] shiftLeft(byte[] data, int len) {
int word_size = (len / 8) + 1;
int shift = len % 8;
byte carry_mask = (byte) ((1 << shift) - 1);
int offset = word_size - 1;
for (int i = 0; i < data.length; i++) {
int src_index = i+offset;
if (src_index >= data.length) {
data[i] = 0;
} else {
byte src = data[src_index];
byte dst = (byte) (src << shift);
if (src_index+1 < data.length) {
dst |= data[src_index+1] >>> (8-shift) & carry_mask;
}
data[i] = dst;
}
}
return data;
}
1. Manually implemented
Here are left and right shift implementation without using BigInteger (ie. without creating a copy of the input array) and with unsigned right shift (BigInteger only supports arithmetic shifts of course)
Left Shift <<
/**
* Left shift of whole byte array by shiftBitCount bits.
* This method will alter the input byte array.
*/
static byte[] shiftLeft(byte[] byteArray, int shiftBitCount) {
final int shiftMod = shiftBitCount % 8;
final byte carryMask = (byte) ((1 << shiftMod) - 1);
final int offsetBytes = (shiftBitCount / 8);
int sourceIndex;
for (int i = 0; i < byteArray.length; i++) {
sourceIndex = i + offsetBytes;
if (sourceIndex >= byteArray.length) {
byteArray[i] = 0;
} else {
byte src = byteArray[sourceIndex];
byte dst = (byte) (src << shiftMod);
if (sourceIndex + 1 < byteArray.length) {
dst |= byteArray[sourceIndex + 1] >>> (8 - shiftMod) & carryMask;
}
byteArray[i] = dst;
}
}
return byteArray;
}
Unsigned Right Shift >>>
/**
* Unsigned/logical right shift of whole byte array by shiftBitCount bits.
* This method will alter the input byte array.
*/
static byte[] shiftRight(byte[] byteArray, int shiftBitCount) {
final int shiftMod = shiftBitCount % 8;
final byte carryMask = (byte) (0xFF << (8 - shiftMod));
final int offsetBytes = (shiftBitCount / 8);
int sourceIndex;
for (int i = byteArray.length - 1; i >= 0; i--) {
sourceIndex = i - offsetBytes;
if (sourceIndex < 0) {
byteArray[i] = 0;
} else {
byte src = byteArray[sourceIndex];
byte dst = (byte) ((0xff & src) >>> shiftMod);
if (sourceIndex - 1 >= 0) {
dst |= byteArray[sourceIndex - 1] << (8 - shiftMod) & carryMask;
}
byteArray[i] = dst;
}
}
return byteArray;
}
Used in this class by this Project.
2. Using BigInteger
Be aware that BigInteger internally converts the byte array into an int[] array so this may not be the most optimized solution:
Arithmetic Left Shift <<:
byte[] result = new BigInteger(byteArray).shiftLeft(3).toByteArray();
Arithmetic Right Shift >>:
byte[] result = new BigInteger(byteArray).shiftRight(2).toByteArray();
3. External Library
Using the Bytes java library*:
Add to pom.xml:
<dependency>
<groupId>at.favre.lib</groupId>
<artifactId>bytes</artifactId>
<version>{latest-version}</version>
</dependency>
Code example:
Bytes b = Bytes.wrap(someByteArray);
b.leftShift(3);
b.rightShift(3);
byte[] result = b.array();
*Full Disclaimer: I am the developer.
The is an old post, but I want to update Adam's answer.
The long solution works with a few tweak.
In order to rotate, use >>> instead of >>, because >> will pad with significant bit, changing the original value.
second, the printbyte function seems to miss leading 00 when it prints.
use this instead.
private String getHexString(byte[] b) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < b.length; i++)
result.append(Integer.toString((b[i] & 0xff) + 0x100, 16)
.substring(1));
return result.toString();
}

Sending Java int to C over TCP

I'm trying to send Java's signed integers over TCP to a C client.
At the Java side, I write the integers to the outputstream like so:
static ByteBuffer wrapped = ByteBuffer.allocateDirect(4); // big-endian by default
public static void putInt(OutputStream out, int nr) throws IOException {
wrapped.rewind();
wrapped.putInt(nr);
wrapped.rewind();
for (int i = 0; i < 4; i++)
out.write(wrapped.get());
}
At the C side, I read the integers like so:
int cnt = 0;
char buf[1];
char sizebuf[4];
while(cnt < 4) {
iResult = recv(ConnectSocket, buf, 1, 0);
if (iResult <= 0) continue;
sizebuf[cnt] = buf[0];
cnt++;
}
However, how do I convert the char array to an integer in C?
Edit
I have tried the following (and the reverse):
int charsToInt(char* array) {
return (array[3] << 24) | (array[2] << 16) | (array[1] << 8) | array[0];
}
Edited again, because I forgot the tags.
Data
For example of what happens currently:
I receive:
char 0
char 0
char 12
char -64
the int becomes 2448
and use the function for creating the int from the char array:
int charsToInt(char* array) {
return ntohl(*((int*) array));
}
I expect the signed integer: 3264
Update
I will investigate more after some sleep..
Update
I have a Java client which interprets the integers correctly and receives the exact same bytes:
0
0
12
-64
That depends on endianness, but you want either:
int x = sizebuf[0] +
(sizebuf[1] << 8) +
(sizebuf[2] << 16) +
(sizebuf[3] << 24);
or:
int x = sizebuf[3] +
(sizebuf[2] << 8) +
(sizebuf[1] << 16) +
(sizebuf[0] << 24);
Note that sizebuf needs to have an unsigned type for this to work correctly. Otherwise you need to mask off any sign-extended values you don't want:
int x = (sizebuf[3] & 0x000000ff) +
((sizebuf[2] << 8) & 0x0000ff00) +
((sizebuf[1] << 16) & 0x00ff0000) +
((sizebuf[0] << 24) & 0xff000000);
The classical C library has the method you want already, and it is independent from the machine endianness: ntohl!
// buf is a char */uint8_t *
uint32_t from_network = *((uint32_t *) buf);
uint32_t ret = ntohl(from_network);
This, and htonl for the reverse etc expect that the "network order" is big endian.
(the code above presupposes that buf has at least 4 bytes; the return type, and argument type, of ntohl and htonl are uint32_t; the JLS defines an int as 4 bytes so you are guaranteed the result)
To convert you char array, one possibility is to cast it to int* and to store the result :
int result = *((int*) sizebuf)
This is valid and one line. Other possibility is to compute integer from chars.
for (i = 0 ; i < 4; i++)
result = result << sizeof(char) + buf[0]
Choose the one that you prefer.
Alexis.
Edit :
sizeof(char) is 1 because sizeof return a Byte result. So the right line is :
result = result << (sizeof(char) * 8) + buf[0]

Java: reading a variable number of bits and converting to an integer

I need to write a method which reads a variable number of bits from a ByteBuffer and converts those bytes into a primitive int or long (if more than 32 bits). I am not very proficient at working with bits, but I did look at some code examples and answers to similar(ish) questions and here is the best that I could come up with (bb refers to an internal ByteBuffer):
public int readBits(int number) {
int initialPosition = bb.position();
int value = 0;
int remaining = number;
int position = bb.position();
while (remaining > 0) {
int index = (position >> 3);
int bit = (position & 7);
int bitsLeft = Math.min(8 - bit, remaining);
int nibble = (bb.get(index) >> (bit & BIT_MASKS[bitsLeft]));
value |= nibble << (number - remaining);
position += bitsLeft;
remaining -= bitsLeft;
}
bb.position(initialPosition + ((position - initialPosition) >> 3));
return value;
}
The BIT_MASKS array is defined as following:
private static final int[] BIT_MASKS = new int[] { 0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
I tested this method using this test code:
public static void main(String[] args) {
int nm = 4;
BitSet bs = new BitSet(nm);
bs.set(2);
bs.set(3);
BitBuffer bb = new BitBuffer(ByteBuffer.wrap(bs.toByteArray()));
System.out.println(bb.readBits(nm));
}
I expected a value of 6, but it prints 12 and I'm not sure why.
I would appreciate some help with this. Thanks.

Reverse all bits in an int and return the int

What integer should be returned when we reverse all bits of integer 1? How do we do that with Java code?
No java built in functions should be used. Shouldn't use String reverse, converting to string etc. Only bitwise operations allowed.
import java.util.*;
import java.lang.*;
import java.io.*;
class BitReverseInt
{
public static void main (String[] args) throws java.lang.Exception{
System.out.println(reverser(1));
}
public static int reverser(int given){
int input = given;
int temp = 0;
int output = 0;
while(input > 0){
output = output << 1;
temp = input & 1;
input = input >> 1;
output = output | temp;
}
return output;
}
}
Bit reversal can be done by interchanging adjacent single bits, then interchanging adjacent 2-bit fields, then 4-bits, and so on as shown below. These five assignment statements can be executed in any order.
/********************************************************
* These are the bit masks used in the bit reversal process
0x55555555 = 01010101010101010101010101010101
0xAAAAAAAA = 10101010101010101010101010101010
0x33333333 = 00110011001100110011001100110011
0xCCCCCCCC = 11001100110011001100110011001100
0x0F0F0F0F = 00001111000011110000111100001111
0xF0F0F0F0 = 11110000111100001111000011110000
0x00FF00FF = 00000000111111110000000011111111
0xFF00FF00 = 11111111000000001111111100000000
0x0000FFFF = 00000000000000001111111111111111
0xFFFF0000 = 11111111111111110000000000000000
*/
uint x = 23885963; // 00000001011011000111100010001011
x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
// result x == 3508418176 11010001000111100011011010000000
By looking at each intermediary result you can see what is happening.
Hopefully this will give you what you need to sort it out in your head. John Doe's answer consolidates steps 4 and 5 in to a single expression. This will work on most machines.
Here is the actual implementation of Integer.reverse(int).
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
You can use a do while loop like this:
public static int reverse(int number){
int reverse = 0;
int remainder = 0;
do{
remainder = number%10;
reverse = reverse*10 + remainder;
number = number/10;
}while(number > 0);
return reverse;
}
And for bitwise operation: here it goes:
// value=your integer, numBitsInt=how much bit you will use to reverse
public static int reverseIntBitwise(int value, int numBitsInt) {
int i = 0, rev = 0, bit;
while (i++ < numBitsInt) {
bit = value & 1;
value = value >> 1;
rev = rev ^ bit;
if (i < numBitsInt)
rev = rev << 1;
}
return rev;
}
Well there are multiple ways to reverse the bits of the given number in Java.
First, Java language has inbuild bitwise complement operator(~). So (~number) reverses the bits of number.
Second, one can use the Integer.reverse(number)
Third, if this is a part of test or you just want to play with bits, you can refer the code below.
/*
The logic uses moving bitmask from right to left:
1. Get the bit of given number, by binary and(&) with bitmask
2. XOR(^) with the bitmask, so here we reverse the bit.
3. OR(|) this reversed bit with the result(result has all Zero initially)
This logic is repeated for each 32 bits by moving the mask from right to left,
one bit at a time using (<<) left shift operator on bitmask.
*/
public class ReverseBits {
public static int reverseBits(int input) {
print("Input", input);
int bitmask = 1;
int result = 0;
do {
//print("Bitmask", bitmask);
result = result | (bitmask ^ (input & bitmask)) ;
//print("Result", result);
bitmask = bitmask << 1;
} while (bitmask != 0);
print("Reverse", result);
return result;
}
public static void print(String label, int input) {
System.out.println(label +"\t:"+Integer.toBinaryString(input));
}
public static void main(String[] args) {
reverseBits(Integer.MIN_VALUE);
reverseBits(Integer.MAX_VALUE);
reverseBits(reverseBits(170));
}
}
Output:
Input :10000000000000000000000000000000
Reverse :1111111111111111111111111111111
Input :1111111111111111111111111111111
Reverse :10000000000000000000000000000000
Input :10101010
Reverse :11111111111111111111111101010101
Input :11111111111111111111111101010101
Reverse :10101010
return Integer.reverse(given);
Integer.reverse Reference

Categories