Integer str = 300;
RandomAccessFile file = new RandomAccessFile(filePath, "rw");
file.seek(seek);
file.write(Integer.parseInt(String.format("%02x", Integer.reverseBytes(str)), 10));
file.close();
java.lang.NumberFormatException: For input string: "2c010000"
How can save this value in the file?
When you give String.format("%02x",...), you are telling the compiler to give you a Hexadecimal number.
But then you are trying to parse it as a decimal number. Hence the issue.
You should do either of these,
file.write(Integer.parseInt(String.format("%02d", Integer.reverseBytes(str)), 10));
or,
file.write(Integer.parseInt(String.format("%02x", Integer.reverseBytes(str)), 16));
You can skip formatting and parsing, and go straight for this implementation:
file.write(Integer.reverseBytes(str));
The problem is that you are printing the number as hex, but you parse it back as a decimal. To parse the number back as hex, pass 16 for the last parameter of parseInt:
file.write(Integer.parseInt(String.format("%02x", Integer.reverseBytes(str)), 16));
// ^^
Demo.
Note: This is probably not what you want anyway: if you with to write all four bytes, not the MSB, do this:
byte[] bytes = ByteBuffer
.allocate(4)
.putInt(Integer.reverseBytes(str))
.array();
file.write(bytes);
Related
I am currently reading in a UDP byte array that I know is a string and I know the MAXIMUM possible length of said string. So I print out a string (which is usually shorter than the max length). I am able to print it out but it prints out the text then junk characters. Is there a way to trim the junk binary data without knowing the actual length of the valid text?
String result = new String(input, Charset.forName("US-ASCII"));
Ill try for those asking for more data. Here is how the UDP message is read:
sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
The UDP message itself will contain a header of fixed size and then a set of data (Max size of 1024 bytes). This data may be int, string, byte etc. This is determined by header data. So depending on the type, i chop the data out based on the appropriate size chunks. The problem I am focusing on is the String type of data. I know that the max size of a string will be 128 bytes per string, so I read that amount in chunks via where dataArray is the byte array.:
for (int i = 0; i < msg.length; i = i + readSize)
{
dataArray = Arrays.copyOfRange(msg, i, i + readSize);
}
Then I use the original code in the first code set in this post to place the data into a string object. Thing is, the text that is usually sent is less than the 128 bytes allocated for max size. So when I print the string, I get the valid text and then whitespace and non-normal ascii characters (junk data). Hope this addition helps.
An example of the output is here. Everything up to the .mof is valid:
https://1drv.ms/i/s!Ai0t7Oj1PUFBpRP9K_2RlocAK4B7
Is there a way to trim the junk binary data without knowing the actual
length of the valid text?
Yes you can simply call trim(), it will remove the trailing null characters. Indeed trim() removes every leading and trailing characters less or equal to \u0020 (aka whitespace) which includes \u0000 (aka null character).
byte[] bytes = "foo bar".getBytes();
// Simulate message with a size bigger than the actual encoded String
byte[] msg = new byte[32];
System.arraycopy(bytes, 0, msg, 0, bytes.length);
// Decode the message
String result = new String(msg, Charset.forName("US-ASCII"));
// Trim the result
System.out.printf("Result: '%s'%n", result.trim());
Output:
Result: 'foo bar'
Ok here is how I was able to get it to work. It's a rather manual method but before using
String result = new String(input, Charset.forName("US-ASCII"));
to combine the byte array into a string, I looked at each byte and made sure it was within the printable range of 0x20 - 0x7e. If not, I replaced the value with a space (0x20). Then finished off with a .trim on the string.
I'm trying to convert a string of bits into Unicode characters in java. Problem is that I only get chines signs etc.
String bits = "01010011011011100110000101110010"
Anyone know how to do this?
Values <= 32bits
Use Integer.parseInt to parse the binary string, then convert it to byte array (using ByteBuffer) and finally convert byte array to String:
String bits = "01010011011011100110000101110010"
new String(
ByteBuffer.allocate(4).putInt(
Integer.parseInt(bits, 2)
).array(),
StandardCharsets.UTF_8
);
Values > 32bits
For arbitrary large bits String you can use also BigInteger:
new String(
new BigInteger(bits, 2).toByteArray(),
StandardCharsets.UTF_8
);
Result
Snar
I am following the below method
new Biginteger(str,16).toString(2);
It works really well, but it removes leading zeros. I need output in 64 bits if input string is "3031323334353637"
But it returns 62 characters. I can use a for loop to do that. Is there any other way to do that without loop?
Goal: Converting hex to binary with leading zeros
You can pad with spaces using String.format("%64s") and then replace spaces with zeros. This has the advantage of working for any size of input, not just something in the int range. I'm guessing you're working with arbitrary inputs from your use of BigInteger...
String value = new BigInteger("3031323334353637", 16).toString(2);
System.out.println(String.format("%64s", value).replace(" ", "0"));
Output
0011000000110001001100100011001100110100001101010011011000110111
Explanation... The String.format("%64s, value) outputs the earlier String padded to fill 64 characters.
" 11000000110001001100100011001100110100001101010011011000110111"
The leading spaces are then replaced with '0' characters using String.replace(oldString, newString)
"0011000000110001001100100011001100110100001101010011011000110111"
The following may be the easiest:
new BigInteger("1" + str,16).toString(2).substring(1)
Check out this question.
You can do it using String.format():
String unpaddedBinary = new BigInteger("a12", 16).toString(2);
String paddedBinary = String.format("%064s", Integer.parseInt(unpaddedBinary, 2));
int hex=Integer.parseInt(str.trim(),16);
String binary=Integer.toBinaryString(hex);
i have a array of hexadecimal numbers as strings and i want to convert those numbers to binary string, above is the code i used and in there, i get a error as shown below
Exception in thread "main" java.lang.NumberFormatException: For input string: "e24dd004"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at sew1.javascript.main(javascript.java:20)
Maximum Integer in Java is 0x7fffffff, because it is signed.
Use
Long.parseLong(str.trim(),16);
or
BigInteger(str.trim(),16);
instead.
The problem is that e24dd004 is larger than int can handle in Java. If you use long, it will be fine:
String str = "e24dd004";
long hex = Long.parseLong(str.trim(),16);
String binary=Long.toBinaryString(hex);
System.out.println(binary);
That will be valid for hex up to 7fffffffffffffff.
An alternative, however, would be to do a direct conversion of each hex digit to 4 binary digits, without ever converting to a numeric value. One simple way of doing that would be to have a Map<Character, String> where each string is 4 digits. That will potentially leave you with leading 0s of course.
Use BigInteger as below:
BigInteger bigInteger = new BigInteger("e24dd004", 16);
String binary = bigInteger.toString(2);
Or using Long.toBinaryString() as below:
long longs = Long.parseLong("e24dd004",16);
String binary = Long.toBinaryString(longs);
Since java-8, you can treat integers as unsigned, so you could do:
String str = "e24dd004";
int i = Integer.parseUnsignedInt(str, 16);
String binary = Integer.toBinaryString(i); //11100010010011011101000000000100
String backToHex = Integer.toUnsignedString(i, 16); //e24dd004
You would be able to handle values that are not larger than 2^32-1 (instead of 2^31-1 if you use signed values).
If you can't use it, you'll have to parse it as a long like other answers showed.
If I have some binary data D And I convert it to string S. I expect than on converting it back to binary I will get D. But It's wrong.
public class A {
public static void main(String[] args) throws IOException {
final byte[] bytes = new byte[]{-114, 104, -35};// In hex: 8E 68 DD
System.out.println(bytes.length); //prints 3
System.out.println(new String(bytes, "UTF-8").getBytes("UTF-8").length); //prints 7
}
}
Why does this happens?
Converting between a byte array to a String and back again is not a one-to-one mapping operation. Reading the docs, the String implmentation uses the CharsetDecoder to convert the incoming byte array into unicode. The first and last bytes in your input byte array must not map to a valid unicode character, thus it replaces it with some replacement string.
It's likely that the bytes you're converting to a string don't actually form a valid string. If java can't figure out what you mean by each byte, it will attempt to fix them. This means that when you convert back to the byte array, it won't be the same as when you started. If you try with a valid set of bytes, then you should be more successful.
Your data can't be decoded into valid Unicode characters using UTF-8 encoding. Look at decoded string. It consists of 3 characters: 0xFFFD, 0x0068 and 0xFFFD. First and last are "�" - Unicode replacement characters. I think you need to choose other encoding. I.e. "CP866" produces valid string and converts back into same array.