Compare hexadecimal and decimal values - java

i have byte array stored by both hexadecimal and decimal value,i want to search for hexadecimal 1 i'e SOH in the how can i do this in java,plz give a sample code.
int SOH=0X01;
if(SOH==1)
Is showing true. Is this correct?

Your byte arrays will just store byte values. The hexadecimal (or decimal, or octal) is just the representation of that value in the source code. Once stored, they're all the same value e.g.
0x01 == 1 == 01
(the last being octal)
So checking for a particular value is the same code. A value won't know if it's been represented as hex/dec/oct.

How is the data in the byte array stored as hexadecimal and decimal?
A byte array contains bytes.
byte[] decimal = new byte[] {1,10 };
byte[] hexa = new byte[] {0x1,0xa };
These contain the same values, you can compare them directly, you don't need any specific code.

Related

Why do C# and Java BigInteger convert byte[] differently?

This is Java code:
new BigInteger("abc".getBytes()).toString();
and the result is 6382179.
I want the same result in C# but when I use the following code:
(new System.Numerics.BigInteger(System.Text.Encoding.ASCII.GetBytes("abc"))).ToString();
I get 6513249.
How do I convert the string in C# the same way as Java?
C#'s BigInteger treats the byte array as little-endian:
Parameters
value Byte[]
An array of byte values in little-endian order.
Whereas Java's BigInteger treats the byte array as big-endian:
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.
So you need to reverse the byte array to get the same result as you do in the other language.
Also note that Java's String.getBytes uses the default encoding, which might not be ASCII. You should use
StandardCharsets.US_ASCII.encode("abc").array()
// or
"abc".getBytes(StandardCharsets.US_ASCII)
to get the same set of bytes as the C# code.

How to convert byte[] values to decimal?

I'm using wireshark and I need to take two bytes (attached image) and have it's decimal value:
My goal is to take this byte[] which is in hex value and parse it to decimal.
Sure, I know how to make one value to decimal which is easy, but I don't know how to make these two, should I make a sum between them or is there any other way to make it?
I didn't find any value which is different then this which the left value is not 00.
If it is always big endian (network byte order), try this.
byte[] bytes = {0x00, 0x16};
System.out.println(ByteBuffer.wrap(bytes).getShort()); // => 22
If byte array length is 4, use getInt() instead of getShort()

Why does writeBytes discard each character's high eight bits?

I wanted to use DataOutputStream#writeBytes, but was running into errors. Description of writeBytes(String) from the Java Documentation:
Writes out the string to the underlying output stream as a sequence of bytes. Each character in the string is written out, in sequence, by discarding its high eight bits.
I think the problem I'm running into is due to the part about "discarding its high eight bits". What does that mean, and why does it work that way?
Most Western programmers tend to think in terms of ASCII, where one character equals one byte, but Java Strings are 16-bit Unicode. writeBytes just writes out the lower byte, which for ASCII/ISO-8859-1 is the "character" in the C sense.
The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive). But The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). That is why this function is writing the low-order byte of each char in the string from first to last. Any information in the high-order byte is lost. In other words, it assumes the string contains only characters whose value is between 0and 255.
You may look into the writeUTF(String s) method, which, retains the information in the high-order byte as well as the length of the string. First it writes the number of characters in the string onto the underlying output stream as a 2-byte unsigned int between 0 and 65,535. Next it encodes the string in UTF-8 and writes the bytes of the encoded string to the underlying output stream. This allows a data input stream reading those bytes to completely reconstruct the string.

Extracting RSA public key modulus and exponent stored in unsigned char arrays

So, I'm using a proprietary library that has its own implementation for the creation of RSA key pairs. The public key struct looks like this:
typedef struct
{
unsigned int bits; //Length of modulus in bits
unsigned char modulus[MAX_RSA_MOD_LEN]; //Modulus
unsigned char exponent[MAX_RSA_MOD_LEN]; //Exponent
} RSA_PUB_KEY
I need to figure out a way to extract both the exponent and the module so I can send them to a server as part of a validation scheme. I guess that this is a pretty standard procedure (or so I hope). I've already read these two similar questions:
How to convert an Unsigned Character array into a hexadecimal string in C
Printing the hexadecimal representation of a char array[]
But so far I've had no luck. I'm also not sure of how to use if at all necessary the "bits" field to extract the modulus. In short what I have to do is be able to recreate this public key in Java:
BigInteger m = new BigInteger(MODULUS);
BigInteger e = new BigInteger(EXPONENT);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
Edit:
This is what I'm doing right now: (RSAPublic is a RSA_PUB_KEY struct as described above).
//RSAPublic.bits = length of modulus in bits
log("Modulus length: "+std::to_string(RSAPublic.bits));
log("Key length: "+std::to_string(keyLengthInBits));
//Calculating buffer size for converted hexadec. representations
int modulusLengthInBytes = (RSAPublic.bits+7)/8 ;
int exponentLengthInBytes = (keyLengthInBits+7)/8;
char convertedMod[modulusLengthInBytes*2+1];
char convertedExp[exponentLengthInBytes*2+1];
//Conversion
int i;
for(i=0; i<modulusLengthInBytes ; i++){
sprintf(&convertedMod[i*2], "%02X", RSAPublic.modulus[i]);
}
for(i=0; i<exponentLengthInBytes ; i++){
sprintf(&convertedExp[i*2], "%02X", RSAPublic.exponent[i]);
}
//Print results
printf("Modulus: %s\n", convertedMod);
printf("Exponent: %s\n", convertedExp);
And this is the output:
Modulus length: 16
Key length: 512
Modulus: 0000
Exponent: 0A000200FFFFFFFFFFFF0000600007004DDA0100B01D0000AEC642017A4513000000000000000000000000000000000000000000000000000000000000000000
I'm assuming that you can't just send binary data since you mention the hexadecimal conversion. The most compact way you can send the data as text would be with base 64 but this is more complex than hexadecimal.
Client side
Convert the unsigned char array to a hexadecimal string using a method from the links you have. The bits field will determine how many bytes from the array to use given by (bits+7)/8.
Depending on implementation you might have to explicitly select the overflow bits or the rest might be zeroed, this also depends on the endianness so since you are unsure on implementation details you might have to fiddle around with it a bit.
Once you have the encoded strings, send them to the server.
Server side
Read the encoded strings from the connection and then pass them to the BigInteger(String val, int radix) constructor using the radix of hexadecimal (16).
You will then have A BigInteger with the value you require.
If the first bytes of the public exponent are all zero's then you are dealing with a big endian array. This is most common. In principle the public exponent can be as large as the modulus, but this is commonly not the case. Most common values are 65537, 17 and 3, maybe even 2 but the 3 and 2 are not such good values. Other 2-4 byte primes are also common.
Now if you know the endianness, you can have a look at the modulus. If the highest byte value is 00 then you are dealing with a signed representation of the modulus. Otherwise it is likely unsigned. The highest order byte of the modulus that contains bits should always be 80 or higher. The reason is that otherwise the key size would be smaller than the given key size. This is assuming that the key size is a multiple of 8 of course.
Java only works with big endian for BigInteger (and any other number representation). So if you have little endian encoding in C then you need to reverse the values in Java. It is probably the best to reverse the hexadecimal values in the string to accomplish that. Make sure you handle 2 hexadecimal characters at a time.
Then, as DrYap suggested, use the hexadecimal constructor of BigInteger. Note that if you end up using a byte array then you may want to use new BigInteger(1, MODULUS) as this makes sure you get a positive number regardless of the highest order bit value in the encoding.

Storing Hexa-decimal Values

I have an sequence of 30 or so hexa decimal values 0x01, 0x02...
My question is how can i store these values in Java. I do not know if it matters to convert it into String and store it. But thats what i am not looking for. I just want to store the hexa decimal as constant data. Please also consider the contents representing the Hex-Decimal form and if/what happens to it ?
Hexadecimal is just a format to display numbers, just like decimal, binary or octal. Numbers are just numbers - hexadecimal is not a property of the numbers themselves, it's only a way to display numbers.
Writing the numbers as 0x01, 0x02, etc. in your source code is exactly the same as writing them in decimal 1, 2 etc.
So, you can store the numbers like you would store any other numbers - for example as an array of ints.
You should store them as Integers using the Integer.valueOf(String s, int radix) method.
In your case, the radix is 16.
Just store them in an integer (if it fits within the value range) ... when displaying them, convert it as hex.

Categories

Resources