How to convert int [] to Big Integer? - java

I would like to convert an integer array of values, which was original were bytes.

First, make sure you know in which format your int[] is meant to be interpreted.
Each int can be seen as consisting of four bytes, and these bytes together can be converted to an BigInteger. The details are the byte order - which byte is the most and which one the least significant?
Also, do you have a signed or unsigned number?
A simple way to convert your ints to bytes (for latter use in a BigInteger constructor) would be to use ByteBuffer and wrap an IntBuffer around it.
public BigInteger toBigInteger(int[] data) {
byte[] array = new byte[data.length * 4];
ByteBuffer bbuf = ByteBuffer.wrap(array);
IntBuffer ibuf = bbuf.asIntBuffer();
ibuf.put(data);
return new BigInteger(array);
}
Obvious adaptions would be to set the byte order of bbuf, or use another BigInteger constructor (for unsigned).

Well, what about new BigInteger(byte[] val)?
To quote the API docs I linked to:
Translates a byte array containing the two's-complement binary representation of a BigInteger into a BigInteger. The input array is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element.

Related

Java->C# BigInteger + Math Conversion

I am attempting to convert some BigInteger objects and math from Java to C#.
The Java flow is as follows:
1. Construct 2 BigIntegers from a base-10 string (i.e. 0-9 values).
2. Construct a third BigInteger from an inputted byte array.
3. Create a fourth BigInteger as third.modPow(first, second).
4. Return the byte result of fourth.
The main complications in converting to C# seem to consist of endianness and signed/unsigned values.
I have tried a couple different ways to convert the initial 2 BigIntegers from Java->C#. I believe that using the base-10 string with BigInteger.Parse will work as intended, but I am not completely sure.
Another complication comes from the use of a BinaryReader/BinaryWriter implementation, in C#, that is already big-endian (like Java). I use the BR/BW to supply the byte array to create the third BigInteger and consume the byte array produced from the modPow (the fourth BigInteger).
I have tried reversing the byte arrays for input and output in every way, and still do not get the expected output.
Java:
public static byte[] doMath(byte[] input)
{
BigInteger exponent = new BigInteger("BASE-10-STRING");
BigInteger mod = new BigInteger("BASE-10-STRING");
BigInteger bigInput = new BigInteger(input);
return bigInput.modPow(exponent, mod).toByteArray();
}
C#:
public static byte[] CSharpDoMath(byte[] input)
{
BigInteger exponent = BigInteger.Parse("BASE-10-STRING");
BigInteger mod = BigInteger.Parse("BASE-10-STRING");
// big->little endian
byte[] reversedBytes = input.Reverse().ToArray();
BigInteger bigInput = new BigInteger(reversedBytes);
BigInteger output = BigInteger.ModPow(bigInput, exponent, mod);
// little->big endian
byte[] bigOutput = output.ToByteArray().Reverse().ToArray();
return bigOutput;
}
I need the same output from both.

Inserting unsigned integer value into bytebuffer, maintaining binary representation

I'm trying to put the following binary representation into a bytebuffer for 4 bytes. But since Java doesn't do unsigned, I'm having trouble: 11111111000000001111111100000000
ByteBuffer bb = ByteBuffer.allocate(8);
bb.putInt(Integer.parseInt("11111111000000001111111100000000", 2));
//throws numberformatexception
Negating the most significant bit seems to change the binary string value because of how two's compliment works:
bb.putInt(Integer.parseInt("-1111111000000001111111100000000", 2));
System.out.println(Integer.toBinaryString(bb.getInt(0)));
//prints 10000000111111110000000100000000
It's important that the value is in this binary format exactly because later it will be treated as an unsigned int. How should I be adding the value (and future values that start with 1) to the bytebuffer?
Just parse it as a long first, and cast the result:
int value = (int) Long.parseLong("11111111000000001111111100000000", 2);
That handles the fact that int runs out of space, because there's plenty of room in a long. After casting, the value will end up as a negative int, but that's fine - it'll end up in the byte buffer appropriately.
EDIT: As noted in comments, in Java 8 you can use Integer.parseUnsignedInt("...", 2).
You can also use Guava's UnsignedInts.parseUnsignedInt(String string, int radix) and UnsignedInts.toString(int x,int radix) methods:
int v = UnsignedInts.parseUnsignedInt("11111111000000001111111100000000", 2);
System.out.println(UnsignedInts.toString(v, 2));
try this
bb.putInt((int)Long.parseLong("11111111000000001111111100000000", 2));

Parse C byte array into Java ByteBuffer.

I'm parsing a byte array which contains variables of different types. I'm getting this array from HID connected to my phone. Array was made by C programmer. I'm trying to parse it using ByteBuffer class:
byte[] buffer = new byte[64];
if(connection.bulkTransfer(endpoint, buffer, 64, 1000) >= 0)
{
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
char mId = byteBuffer.getChar();
short rId = byteBuffer.getShort();
// ............................
}
But the values of this variables are not correct. Can anyone please tell me what i'm doing wrong?
There are systems with LitteEndian Byte order and BigEndian.
java uses BigEndian.
If the c programmer wrote the byte array in Little endian, you could use DataInputStream based on an Appache LittleEndianInputStream:
LittleEndianInputStream leis = new LittleEndianInputStream(is);
DataInputStream dis = new DataInputStream(leis);
int i1 = dis.readInt();
short s2 = dis.readShort();
If you and your colleague define a binary interface (file, or byte array) you always should force a speciifc byte order (Either little or big endian).
If byte order (little vs big endian) is the issue, you can set the byte order for the ByteBuffer to native without changing all of the program:
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
byteBuffer.order(ByteOrder.nativeOrder()); // Set native byte order
char mId = byteBuffer.getChar();
short rId = byteBuffer.getShort();
On the other hand, if you find ByteBuffer objects more convenient than byte arrays, tell the C programmer to return you a direct byte buffer instead of an array: easier for all parties and probably more efficient.

Java byte Insert value error string to byte

I have class that have one member myByte as follows.
public class ByteClass {
private Byte myByte;
public Byte getMyByte() {
return myByte;
}
public void setMyByte(Byte myByte) {
this.myByte = myByte;
}
}
I have string value which is FF and I need to assign it to the class member,
how should I do that since when I try it ass follows I got error in the compile time
Type mismatch: cannot convert from byte[] to byte I understand that I cant use Array of byte for the string but I have tried to do that in several of ways without any success .any Idea how can I set the value FF to the class ?
public class ByteHanlder {
public static void main(String[] args) {
String str = "FF";
byte temp = str.getBytes();
Byte write_data = new Byte(temp);
ByteClass byteClass = new ByteClass();
byteClass.setMyByte(temp);
System.out.println(byteClass.getMyByte());
}
}
Assuming you really do just want to store a byte, you can use:
int value = Integer.parseInt("FF", 16);
x.setMyByte((byte) value);
Now that will give you a value of -1 if you look at it in the debugger - but that's just because bytes are signed, as other answerers have noted. If you want to see the unsigned value at any time, you can just use:
// Only keep the bottom 8 bits within a 32-bit integer, which ends up
// treating the original byte as an unsigned value.
int value = x.getMyByte() & 0xff;
You can still just store a byte - and then interpret it in an unsigned way rather than a signed way. If you really just want to store a single byte - 8 bits - I suggest you don't change to using a short.
Having said all this, it's somewhat odd to need a mutable wrapper type just for a byte... perhaps you could give us more context as to why you want this, and we may be able to suggest cleaner alternatives.
Your String "FF" seems to be a hex value, right? So you actually want to convert it to the byte value of 255.
You can use a method like described here to convert a hex string to a byte array: Convert a string representation of a hex dump to a byte array using Java?.
In your case, you could adapt that method to expect a 2-letter string and return a single byte instead of a byte array.
String.getBytes return a bytearray so you can not assign a bytearray to a byte.
If you want to set FF hex value then you could use
setMyByte((byte)0xff);
But there is still a problem 0xff is of 2 byte size but byte type is of 1 byte. In that case you can use short instead of byte

Get single bytes from multi-byte variable in java

How can I split a variable into single bytes in java? I have for example following snippet in C++:
unsigned long someVar;
byte *p = (byte*)(void*) someVar; // byte being typedef unsigned char (from 0 to 255)
byte *bytes = new byte[sizeof(someVar)];
for(byte i = 0;i<sizeof(someVar);i++)
{
bytes[i] = *p++;
}
.... //do something with bytes
I want to accomplish the same under java, but I can't seem to find an obvious workaround.
There are two ways to do it with the ByteBuffer class. One is to create a new byte array dynamically.
long value = 123;
byte[] bytes = ByteBuffer.allocate(8).putLong(value).array();
Another is to write to an existing array.
long value = 123;
byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putLong(value);
// bytes now contains the byte representation of 123.
If you use Guava, there is a convenience Longs.toByteArray. It is simply a wrapper for John's ByteBuffer answer above, but if you already use Guava, it's slightly "nicer" to read.

Categories

Resources