I tried to get bignumber from a string, but the value in binary is wrong.
priKeyData = HexByteKit.Hex2Byte("b8dfc598d14c0bb032c1f4eb1fcdb033289002f38cc16b2120dfa697f8982bef");
BigInteger priKeyBN2 = new BigInteger(priKeyData);
String s3 = priKeyBN2.toString(2);
it gives:
-100011100100000001110100110011100101110101100111111010001001111110011010011111000001011000101001110000000110010010011111100110011010111011011111111110100001100011100110011111010010100110111101101111100100000010110010110100000000111011001111101010000010001
But the right one should be:
1011100011011111110001011001100011010001010011000000101110110000001100101100000111110100111010110001111111001101101100000011001100101000100100000000001011110011100011001100000101101011001000010010000011011111101001101001011111111000100110000010101111101111
http://www.mobilefish.com/services/big_number/big_number.php
The right one is 256 bit, so it overflows in Java bignumber class?
Then how can I use this 256 bit number for some steps in Java encryption algorithm?
Thanks.
I don't know what HexByteKit is, but constructing BigInteger from the hex string gives the right result:
BigInteger priKeyBN2 = new BigInteger("b8dfc598d14c0bb032c1f4eb1fcdb033289002f38cc16b2120dfa697f8982bef", 16);
String s3 = priKeyBN2.toString(2);
Related
I try the following code in c# and it give me the result as follow:
long dec1 = Convert.ToInt64("B62FD56EFD5B375D", 16);
result : -531879796222753398
I am trying to do this in java, but I always get NumberFormatException, because there are alphanumeric inside the String. What I code in java is:
Long.parseLong("B62FD56EFD5B375D", 16);
May I know what is the equivalent of this in java?
You can use Long.parseUnsignedLong in Java to get the same result.
long result = Long.parseUnsignedLong("B62FD56EFD5B375D", 16);
Maximum value is 9,223,372,036,854,775,807 (inclusive) for a long value. When the value B62FD56EFD5B375D parsed it is 13,127,946,111,482,018,682 which is unable to hold in a long value.
So instead use BigInteger.
long dec1 = new BigInteger("B62FD56EFD5B375D", 16).longValue();
you can try with BigInteger
BigInteger value = new BigInteger(hex, 16);
I am trying to convert UUID which is coming as string to Big Integer but it's failing every time with Number Format exception as it need String Decimal as parameter. Is there any way we can achieve this.
String x = "6CFAFD0DA976088FE05400144FFB4B37";
I tried with radix also but output is different.
BigInteger big = new BigInteger(x, 0);
System.out.println(big);
Any help is appreciated, TIA.
You are supposed to be using radix 16 as your string has alphanumeric values from 0-9 and A-F, set value 16 in radix as you have hexadecimal string.
String x = "6CFAFD0DA976088FE05400144FFB4B37";
BigInteger big = new BigInteger(x, 16);
System.out.println(big);
OUTPUT
144859830291446118078300087367740640055
You need to set radix value to 16.
For hexadecimal String you need to define the radix value as 16
The question is about the correct way of creating a hash in Java:
Lets assume I have a positive BigInteger value that I would like to create a hash from. Lets assume that below instance of the messageDigest is a valid instance of (SHA-256)
public static final BigInteger B = new BigInteger("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC996C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58", 16);
byte[] byteArrayBBigInt = B.toByteArray();
this.printArray(byteArrayBBigInt);
messageDigest.reset();
messageDigest.update(byteArrayBBigInt);
byte[] outputBBigInt = messageDigest.digest();
Now I only assume that the code below is correct, as according to the test the hashes I produce match with the one produced by:
http://www.fileformat.info/tool/hash.htm?hex=BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC996C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58
However I am not sure why we are doing the step below i.e.
because the returned byte array after the digest() call is signed and in this case it is a negative, I suspect that we do need to convert it to a positive number i.e. we can use a function like that.
public static String byteArrayToHexString(byte[] b) {
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
thus:
String hex = byteArrayToHexString(outputBBigInt)
BigInteger unsignedBigInteger = new BigInteger(hex, 16);
When I construct a BigInteger from the new hex string and convert it back to byte array then I see that the sign bit, that is most significant bit i.e. the leftmost bit, is set to 0 which means that the number is positive, moreover the whole byte is constructed from zeros ( 00000000 ).
My question is: Is there any RFC that describes why do we need to convert the hash always to a "positive" unsigned byte array. I mean even if the number produced after the digest call is negative it is still a valid hash, right? thus why do we need that additional procedure. Basically, I am looking for a paper: standard or rfc describing that we need to do so.
A hash consists of an octet string (called a byte array in Java). How you convert it to or from a large number (a BigInteger in Java) is completely out of the scope for cryptographic hash algorithms. So no, there is no RFC to describe it as there is (usually) no reason to treat a hash as a number. In that sense a cryptographic hash is rather different from Object.hashCode().
That you can only treat hexadecimals as unsigned is a bit of an issue, but if you really want to then you can first convert it back to a byte array, and then perform new BigInteger(result). That constructor does threat the encoding within result as signed. Note that in protocols it is often not needed to convert back and forth to hexadecimals; hexadecimals are mainly for human consumption, a computer is fine with bytes.
I'm looking for a way to convert a BigInteger into a very short String (shortest possible). The conversion needs to be reversible. The security of the conversion is not a big deal in this case. Would anyone have recommendations or samples of how they would go about solving this problem?
You can use a Base64 encoding. Note that this example uses Apache commons-codec:
BigInteger number = new BigInteger("4143222334431546643677890898767548679452");
System.out.println(number);
String encoded = new String(Base64.encodeBase64(number.toByteArray()));
System.out.println(encoded);
BigInteger decoded = new BigInteger(Base64.decodeBase64(encoded));
System.out.println(decoded);
prints:
4143222334431546643677890898767548679452
DC0DmJRYaAn2AVdEZMvmhRw=
4143222334431546643677890898767548679452
One easy way is to use BigInteger.toString(Character.MAX_RADIX). To reverse, use the following constructor: BigInteger(String val, int radix).
I have a file on disk which I'm reading which has been written by c/c++ code. I know I have two 64-bit unsigned integers to read, but Java doesn't support unsigned integers, so the value I get when I do DataInputStream.readLong() is incorrect. (Ignore byte-order for now I'm actually using a derivative of DIS called LEDataInputStream which I downloaded from the web)
A lot of posts on here talk about using BigInteger but the javadoc for reading a bytearray only talks about loading a bytearray respresentation, and the questions seem centered on the fact that some people are going outside the positive bounds of the java long type, which I will be nowhere near with the data I'm reading.
I have a MATLab/Octave script which reads these long long values as two 32-bit integers each, then does some multiplying and adding to get the answer it wants too.
I suppose the question is - how do i read a 64-bit unsigned integer either using BigInteger, or using [LE]DataInputStream.XXX?
Thanks in advance
I would suggest using a ByteBuffer and then using code such as this to get what you want.
You can use a long as a 64-bit value to store unsigned data. Here is a module showing that most Unsigned operations can be performed using the standard long type. It really depends on what you want to do with the value as whether this is problem or not.
EDIT: A common approach to handling unsigned numbers is to widen the data type. This simpler in many cases but not a requirement (and for long using BigInteger doesn't make things any simpler IMHO)
EDIT2: What is wrong with the following code?
long max_unsigned = 0xFFFFFFFFFFFFFFFFl;
long min_unsigned = 0;
System.out.println(Unsigned.asString(max_unsigned) + " > "
+ Unsigned.asString(min_unsigned) + " is "
+ Unsigned.gt(max_unsigned, min_unsigned));
prints
18446744073709551615 > 0 is true
first you check out this question
Also see this
Now use of BigInteger class
// Get a byte array
byte[] bytes = new byte[]{(byte)0x12, (byte)0x0F, (byte)0xF0};
// Create a BigInteger using the byte array
BigInteger bi = new BigInteger(bytes);
// Format to binary
String s = bi.toString(2); // 100100000111111110000
// Format to octal
s = bi.toString(8); // 4407760
// Format to decimal
s = bi.toString(); // 1183728
// Format to hexadecimal
s = bi.toString(16); // 120ff0
if (s.length() % 2 != 0) {
// Pad with 0
s = "0"+s;
}
// Parse binary string
bi = new BigInteger("100100000111111110000", 2);
// Parse octal string
bi = new BigInteger("4407760", 8);
// Parse decimal string
bi = new BigInteger("1183728");
// Parse hexadecimal string
bi = new BigInteger("120ff0", 16);
// Get byte array
bytes = bi.toByteArray();