We have a J2ME application that needs to read hex numbers. The application is already too big for some phones so We try not to include any other codec or write our own function to do this.
All the numbers are 64-bit signed integers in hex, when we use Long.ParseLong(hex, 16), it handles positive numbers correctly but it throws exception on negative numbers,
long l = Long.parseLong("FFFFFFFFFFFFFFFF", 16);
How can we get -1 from that hex string using classes provided in Java itself?
Some people may suggest we should write our hex as -1 as Java expected. Sorry, the format is fixed by the protocol and we can't change it.
Your problem is that parseLong() does not handle two's complement - it expects the sign to be present in the form of a '-'.
If you're developing for the CDC profile, you can simple use
long l = new BigInteger("FFFFFFFFFFFFFFFF", 16).longValue()
But the CLDC profile doesn't have that class. There, the easiest way to do what you need is probably to split up the long, parse it in two halves and recombine them. This works:
long msb = Long.parseLong("FFFFFFFF", 16);
long lsb = Long.parseLong("FFFFFFFF", 16);
long result = msb<<32 | lsb;
UPDATE
As of Java 8, you can use parseUnsignedLong():
long l = Long.parseUnsignedLong("FFFFFFFFFFFFFFFF", 16);
Parse it in chunks.
long l = (Long.parseLong("FFFFFFFFF",16)<<32) | Long.parseLong("FFFFFFFF",16);
Worse case scenario, you could check to see if the string is 16 characters that begins with an 8-F, and if so, change that to the equivalent character w/o the most significant bit set (i.e. subtract 8 from that digit), parse the result, and add the parsed value to the lower bound of a signed long? (Essentially just doing the 2's complement yourself.)
Related
I'm working on Huffman compression.
String binaryString = "01011110";
outFile.write(byte);
I have a String which I want to convert to a byte so that I can write that byte to the file. Does anyone know how I can do this?
You can turn that String into a numerical value using the overloaded parseByte that lets you specify the radix:
String binaryString = "01011110";
byte b = Byte.parseByte(binaryString, 2); //this parses the string as a binary number
outFile.write(b);
The second argument to parseByte() lets you specify the Number system in which the String should be parsed. By default, a radix of 10 is used because us humans usually use the decimal system. The 2 says that the number should be treated as a binary value (which is base 2).
You can use Byte.parseByte() with a radix of 2:
byte b = Byte.parseByte(str, 2);
example:
System.out.println(Byte.parseByte("01100110", 2));
Could write (a String[256] with each manually written 1 and 0 set of 8 bits) it out , its only 256 of them. gives you the ability to check with String.indexOf(binnum[arrayIndex])
and make a corresponding array of new byte[256] and set each in matching order with new Integer(increment).byteValue(), it should reproduce for checking printable over the byte[] array using new Byte(bytarray[incr]).intValue()+"\n"
I read SHA-256 from a book, but the book doesn't explain what it is for? The book explained how to create it in Java. However, I failed to understand what Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)) is for. Can someone explain it to me in detail?
Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1))
is one way of converting a byte value to a string that's exacly two character wide, showing the byte's hexadecimal value. Having a look at String's Javadoc page will help.
The combination of 0x100 and substring(1) ensures that byte values < than 16 decimal (that is, 0 to F in hex) are also represented as two characters.
By the way:
String.format("%02x",byteData[i])
does exactly the same, and might be considered more readable, especially by people who are used to C printf style format strings.
Lastly, why (byteData[i] & 0xff) ? See here for a detailed explanation:
It works because Java will perform a widening conversion to int, using
sign extension, so instead of a negative byte you will have a negative
int. Masking with 0xff will leave only the lower 8 bits, thus making
the number positive again (and what you initially intended).
SHA-256 is called a hash algorithm, and its purpose is simple: it takes any data and generates a unique series of bytes to represent it. There is no way to reverse this process, and there are no known instances of a SHA-256 hash being not unique.
The purpose of the line of code in question is to generate one character of the final SHA-256 output. Java gives you the has in raw data (a byte array) and we typically convert it to hexadecimal to represent it as a string. That line of code is pretty complex, so I'll go over what each part of it does separately.
sb.append(); is taking the imput and adding it to the result stored in a StringBuilder.
Integer.toString(); Takes a number and represents it as a literal string
byteData[i] & 0xff Selects the current byte of hash data and uses the bitwise and operation using 0xff (so for each bit in the byte, if the corresponding bit in 0xff is the same, the output is a 1, if not the output is a 0.
string.substring(1); Outputs the string starting after the first character.
I have one long value and Set Particular bit by converting hexadecimal value.
long l = 4;
long output; //output is 84 if i want set 7th bit (1000 0100)
same way is long is 7 then output is 87 so how to set particular bit inside long value.
Requirement:
I have to send one byte to server by proper formatting.
Client gives following thing.
1. Whether 7th bit set or not set.
2. One integer value (like 4,5,6,7 etc.)
Now I have generate string or decimal (2H) that format as client parameter.
You need to do a bitwise or with the value of the bit.
The value of the bit you can find by shifting 1L the correct number of bits to the left. (Don't forget the L, without that you're shifting the int 1.)
Bitwise or can be done with the | operator in Java.
So the code becomes:
long output = l | (1L << 7);
I need to convert a value declared as a byte data type into a string of 8 bits. Is there any Java library method that can do this? For example, it should take in -128 and output "10000000". Also, input -3 should give "11111101". (I converted these by hand.)
Before you assume this has been answered many times, please let me explain why I am confused.
The name "byte" is a little ambiguous. So, it's been difficult following other answers. For my question, byte is referring to the java data type that takes up 8 bits and whose value ranges from -128 to 127. I also don't mean an "array of bytes". My question is about converting a single value into its 8-bit representation only. Nothing more.
I've tried these:
byte b = -128; //i want 10000000
Integer.toBinaryString(b); //prints 11111111111111111111111110000000
Integer.toString(b, 2); //prints -10000000
If there's no built-in method, can you suggest any approach (maybe bit shifting)?
Try
Integer.toBinaryString(b & 0xFF);
this gives a floating length format e.g. 4 -> 100. There seems to be no standard solution to get a fixed length format, that is 4 -> 00000100. Here is a one line custom solution (prepended with 0b)
String s ="0b" + ("0000000" + Integer.toBinaryString(0xFF & b)).replaceAll(".*(.{8})$", "$1");
I am coming across a strange thing. I have a number in binary in the form of string particularly "01001100". But I am getting the exception mentioned above by executing the following code.
String s = "01001100";
byte b = Byte.parseByte(s);
But why is it happening? Whereas in a byte we can store max no. upto 127 and min. upto -128.
And the decimal equivalent of the above number is 76 which is perfectly in the range.
The particular exception I am getting is as:
java.lang.NumberFormatException:Value out of range. value:01001100 radix:10
Is there any way to get rid of it. Yes and it is compulsory for me to use byte only as I am extracting the data stored in the image byte by byte only.
Thank you.
The key is at the end of the exception string: radix:10. You are converting the decimal value 1,001,100 to a byte, and it does not fit. Try this:
String s = "01001100";
byte b = Byte.parseByte(s, 2);
01001100 is a fairly large number in decimal (over a million; see the docs for parseByte(String)). You probably want the version that accepts a radix:
byte b = Byte.parseByte(s, 2);