How to add padding on to a byte array? - java

I have this 40 bit key in a byteArray of size 8, and I want to add 0 padding to it until it becomes 56 bit.
byte[] aKey = new byte [8]; // How I instantiated my byte array
Any ideas how?

An 8 byte array is of 64 bits. If you initialize the array as
byte[] aKey = new byte [8]
all bytes are initialized with 0's. If you set the first 40 bits, that is 5 bytes, then your other 3 bytes, i.e, from 41 to 64 bits are still set to 0. So, you have by default from 41st bit to 56th bit set to 0 and you don't have to reset them.
However, if your array is already initialized with some values and you want to clear the bits from 41 to 56, there are a few ways to do that.
First:
you can just set aKey[5] = 0 and aKey[6] = 0 This will set the 6th bye and the 7th byte, which make up from 41st to 56th bit, to 0
Second: If you are dealing with bits, you can also use BitSet. However, in your case, I see first approach much easier, especially, if you are pre Java 7, some of the below methods do not exist and you have to write your own methods to convert from byte array to bit set and vice-versa.
byte[] b = new byte[8];
BitSet bitSet = BitSet.valueOf(b);
bitSet.clear(41, 56); //This will clear 41st to 56th Bit
b = bitSet.toByteArray();
Note: BitSet.valueOf(byte[]) and BitSet.toByteArray() exists only from Java 7.

Use System.arraycopy() to insert two bytes (56-40 = 16 bit) at the start of your array.
static final int PADDING_SIZE = 2;
public static void main(String[] args) {
byte[] aKey = {1, 2, 3, 4, 5, 6, 7, 8}; // your array of size 8
System.out.println(Arrays.toString(aKey));
byte[] newKey = new byte[8];
System.arraycopy(aKey, 0, newKey, PADDING_SIZE, aKey.length - PADDING_SIZE); // right shift
System.out.println(Arrays.toString(newKey));
}

Guava's com.google.common.primitives.Bytes.ensureCapacity:
aKey = Bytes.ensureCapacity(aKey , 56/8, 0);
or since JDK6 using Java native tools:
aKey = java.util.Arrays.copyOf(aKey , 56/8);

Related

How do i convert multi-byte integer values to 4bytes array using the two's compliment notation in the big-endian order

I need to convert integers that I send over 4bytes per socket in java. The problem is that when the integer exceeds 9, ie [10, +inf] my crash code.
I read in the instructions this line:
All multi-byte integer values are encoded using the two's compliment notation in the big-endian order.
The problem is that I don't know how to write the appropriate conversion function. Here is the one I had implemented and which seems to work for integers from 0 to 9. Can someone help me.
byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i++) {
size_buffer[i] = (byte)(msg_size >>> (i * 8));
}
ByteBuffer has nice functionality for this:
byte[] bytes = new byte[4];
ByteBuffer.wrap(bytes)
.order(ByteOrder.BIG_ENDIAN) // make explicit
.putInt(intValue);
// bytes is now updated
ByteBuffer Doc in java SE 8
I need to convert integers that I send over 4bytes per socket in java.
Probably no actual conversion is required.
The problem is that when the integer exceeds 9, ie [10, +inf] my crash code.
Nothing in what you have presented suggests why that would be, though in fact the conversion presented is wrong.
All multi-byte integer values are encoded using the two's compliment notation in the big-endian order.
This is Java's native representation for type int. You can write ints to the socket's output stream by wrapping it in a DataOutputStream and using DataOutputStream.writeInt(). Or if you are using NIO then you can put an int into a ByteBuffer via the buffer's putInt() method. Either of these approaches sidesteps any need to manually encode integers into byte arrays.
But if you insist on doing your own conversion, completely manually, then this ...
byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i++) {
size_buffer[i] = (byte)(msg_size >>> (i * 8));
}
... reads out the bytes in little-endian order instead of big-endian (most-significant to least). This would be a correct alternative:
byte[] size_buffer = new byte[4];
for (int i = 0; i < 4; i++) {
size_buffer[i] = (byte)(msg_size >>> ((3 - i) * 8));
}
You state you tried +Inf, but that is not an int value. The only number type you can stick +Inf into is double or float, but it's a compiler error to attempt to do >>> to a double or float.
Also, the code snippet you wrote doesn't work for anything - it turns things into little endian order. It treats 9 the exact same way it treats 10: 9 turns into [9, 0, 0, 0] (which is 9 in 2's complement int, but, little endian), and 10 becomes [10, 0, 0, 0].
In other words, you've either thoroughly misanalysed your own code, or you aren't running that snippet.
This will work fine:
int n = -2;
byte[] sizeBuffer = new byte[4];
for (int i = 0; i < 4; i++) {
sizeBuffer[i] = (byte)(n >>> (24 - (i * 8)));
}
Turns -1 into [255, 255, 255, 254] (in java bytes are rendered signed, so if you try to print that, it'll probably show as -1, -1, -1, -2. It's the same thing) - and that is indeed -2 in 2's complement big endian.
You can make a ByteBuffer and write that way as well.

Problem with storing 9 bits codes in buffer for lzw compression

For my LZW compression code. I chose to store the codes in 9-bit codes, dictionary size will be 512, so there will be room for only 256 new
symbols. Now I feel like I didn't choose the right buffer for the job:
byte[] buffer = new byte[3];
This buffer is more suited to store for 12 bits, what is the equivalent for 9 bits and how can I store the 9 bits in the buffer correctly?
I used this to store 8 bits in buffer[0] and 4 bits in buffer[1]. What is the equivalent for 9 bits?
buffer[0] = (byte) (code & 255);
buffer[1] = (byte) ((code >> 8) << 4);
Nine is a hard bit count to work with. First question would be: Can you work in 8 bits?
Assuming not, I'd look at allocating at the dictionary level and packing your 9-bit words in without paying attention to byte boundaries. A 512 byte dictionary = 4096 bits = 455 9-bit symbols. You just need some math to access those symbols from your bitstream:
byte[] buffer = new byte[512];
function getWord(int wordOfs) {
// Gets wordOfs'th 9-bit symbol from buffer, For buffer of 512 bytes, wordOfs = 0 -> 454
if (wordOfs<0 || wordOfs>454) throw InvalidArgumentException;
int bitsOfs = wordOfs * 9; // Offset (in bits) of the desired 9 bit word
int idx = bitsOfs / 8; // buffer[idx] contains bit 0 of the desired word
int ofs = bitsOfs % 8; // ... shifted this many places to the right
// Grab at least 8 bits beyond the calculated starting point
unsigned word val = buffer[idx] | (buffer[idx+1]>>8);
// Shift and mask it down to the desired 9 bits for return
return (val << ofs) & 0x01FF;
}
Caveat: I don't have access to a Java compiler right now, syntax may need work.

Does BitSet in java stores bits or integers?

I came across many coding sites about bitset. But i cant understand whether it stores bits or integers.
BitSet creates an array of bits represented by boolean values.
import java.util.*;
public class GFG
{
public static void main(String[] args)
{
BitSet bs1 = new BitSet();
BitSet bs2 = new BitSet(6);
bs1.set(0);
bs1.set(1);
bs1.set(2);
bs1.set(4);
bs2.set(4);
bs2.set(6);
bs2.set(5);
bs2.set(1);
bs2.set(2);
bs2.set(3);
System.out.println("bs1 : " + bs1);
System.out.println("bs2 : " + bs2);
}
}
Output:
bs1 : {0, 1, 2, 4}
bs2 : {1, 2, 3, 4, 5, 6}
BitSet stores bits or integers?
How does it stores that in memory?
How the values change when any manipulation is done?
Typically BitSet would be implemented using a long[]. Each long stores 64 consecutive possible bit positions. The array needs a size equal to the highest set bit index minus one (to allow for index 0), divided by 64 (rounded down). Set bits are represented as a binary 1 and bits present in the array but not set as a binary 0.
So the internal representation of your examples would be something like:
bs1 = new long[] { 0b00010111L }; // 23
bs2 = new long[] { 0b01111110L }; // 126
// bit indexes: 76543210
(Bits 8-63 elided from constants - add all the zeros if your want.)
The BitSet stores bits using an array of longs:
private long[] bits;
Manipulating this means you manipulate bits of those longs using bitwise operations
and shifts
public void set(int pos)
{
int offset = pos >> 6; // divide by 2^6 = 64
ensure(offset); // if needed extend array
// ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException,
// so we'll just let that be our exception.
bits[offset] |= 1L << pos; // set bit using OR and a shift
}
Some illustration of whats going on for 6 bits (index 0-5):
init 000000
set 3:
000000
OR 001000 = 1 << 3
= 001000
set 5:
001000
OR 100000 = 1 << 5
= 101000
This means you take all bits of the current bitmask and the newly set bit of the desired offset to calculate the new bitmask.
Source Code

Putting my 32 bits into a 4 bytearray

I am putting different binary numbers into a byte array. One of the numbers are: 10001101010010010000000000001000 this number is giving me a NumberFormatException on the line where I try to parse it, obviously because it's too big. See code below where string is the binary number.
int number = Integer.parseInt(string, 2);
ByteBuffer bytes = ByteBuffer.allocate(4).putInt(number);
byte[] byteInstruction = bytes.array();
What I want is to put the numbers in my byte array but as they are 32-bit numbers I don't want to take up more than 4 bytes in my array. When I use long to parse it works but then I take up 8 spaces in my byte array.
long number = Long.parseLong(string, 2);
ByteBuffer bytes = ByteBuffer.allocate(8).putLong(number);
byte[] byteInstruction = bytes.array();
If I print out the array later I get this:
[0, 0, 0, 0, -115, 73, 0, 8]
where we can see that there are 4 spots free. How can I solve this? How did I mess up?
All help is appreciated.
Your input string "10001101010010010000000000001000" represents value that is too big for signed Integer. Integer.MAX_VALUE = 2147483647 and the input string you've passed has a value of 2370371592.
The Integer.parseInt does not interpret the leading 1 at position 32 from right as sign. If you would like parse a negative value it would have to be preceded with - sign.
See this answer for more through explanation.
If you expect the input "10001101010010010000000000001000" to in fact mean "-0001101010010010000000000001000" just replace the first character with +/- depending on the value of 32 bit from right.
Alternatively if you would like to treat the binary string in Two's complement compatible way you can use approach from this answer:
int msb = Integer.parseInt("1000110101001001", 2);
int lsb = Integer.parseInt("0000000000001000", 2);
int result = msb<<16 | lsb;

Please verify: this converter reads the byte array as Big-Endian?

I am porting some stuff from C# to Java and I need a class that can convert bytes to primitives, just like BitConverter in .NET can.
As I just posted here, I noted that my computer uses Little-Endian (Intel) and BitConverter works as expected:
// C# code
byte[] b2 = new byte[] { 0, 1 };
short b2short = BitConverter.ToInt16(b2, 0);
the b2short == 256 as expected.
Well, I needed a "BitConverter" in JAVA and found this piece of code. However, when I try it in JAVA it seems to me that the methods interpret the byte arrays as Big-Endian. JAVA-code:
// JAVA code
byte[] b2 = new byte[] { 0, 1 };
short b2short = MyFoundConverter.BitConverter.toShort(b2, 0);
In this case, b2short == 1 and that seems to me like Big-Endian.
Is the code found on this webpage interpreting the byte array as Big-Endian?
If so, is there an easy way to make it Little-Endian?
The code you linked to is taking the first byte, and making it the high-order byte of the short. The second byte goes into the low-order byte of the short. So this is a big-endian operation. The way it is coded, there would be no easy way to fix this, other than going method by method and swapping the array indexes, so that the highest index becomes the lowest.
I found another code bit that will take the data type and swap its endian-ness. Maybe you can combine the two.
The code you need is:
byte[] b2 = new byte[] { 0, 1 };
short b2short = b2[0] | (b2[1] << 8);
and for int values:
byte[] b4 = new byte[] { 0, 1, 2, 3 };
int b4int = b4[0] | (b4[1] << 8) | (b4[2] << 16) | (b4[3] << 24);
you get the idea :-)

Categories

Resources