I want to write a java program which takes a text field with byte data. Output of my program should be string. How can I achieve that. Any inputs are appreciated.
Input is
85f960f0 82868260 f4f78486 60f8f6f
Output is string format like customer, hero, english..
I am planning to write a simple java program.
Thanks in advance.
Sorry for missing out details first time. I am in learning stages now.
Your question doesn't provide enough detail for a full answer. Assuming the fragment "85f960f0 82868260 f4f78486 60f8f6f" is the output you want...
convert a byte array to hexadecimal string using String.format() using the %x pattern within a loop.
Use %02x to pad each octet to 2 digits if necessary
if you need spaces every 8 characters you could do this by checking to see if the counter is divisible by 4 using the % operator.
For example.
byte[] valueFromTextField = "hello world foo bar".getBytes();
StringBuilder builder = new StringBuilder();
int i = 0;
for (byte element : valueFromTextField) {
if (i % 4 == 0 && builder.length() > 0) {
builder.append(" ");
}
builder.append(String.format("%02x", element));
i++;
}
System.out.println(builder.toString());
Output
68656c6c 6f20776f 726c6420 666f6f20 626172
Assuming you are having byte[] bytes and you can convert it using bytes.toString() OR you can change byte by byte
byte[] bites = new byte[]{24,4,72,56};
for(int i = 0; i < bites.length; i++)
System.out.println(new String(bites, i,1));
String hexadecimals = textField.getText();
hexadecimals = hexadecimals.replaceAll("[^0-9A-Fa-f]", ""); // Remove garbage
int nn = hexadecimals.length();
if (nn % 2 != 0) {
JOptionPane.showMessageDialog(null, "... must be even", JOptionPane.ERROR_MESSAGE);
return "";
}
byte[] bytes = new byte[nn / 2];
for (int i = 0; i < nn - 1; i += 2) {
int b = Integer.parseInt(hexadecimals.substring(i, i + 2), 16);
bytes[i] = (byte) b;
}
return new String(bytes, StandardCharsets.UTF_8);
This uses Integer.parseInt with base 16 (0-9A-F) in integer range to ignore negative byte values.
To convert those bytes to text (which in Java is Unicode to hold any combination of chars), one needs to know which text encoding those bytes are in. Here I use UTF-8, which however requires adherance to the UTF-8 multibyte format.
Related
I have a key for a cipher in the form "XY XY+1 XY+2 XY+3 XY+4 XY+5 FF FF" where XY is an unknown byte, for example, XY could be 00000000 so XY+1 is 00000001.
Also, FF is a constant so always 11111111.
l have an addBinary() method which simply adds 1 to any binary string I give it, however, I'm finding it hard to generate all binary strings composing of "xxxx... 11111111 11111111".
I also found this printB() method on StackOverflow which generates the strings but just not sure how to hard code the FF's into it.
static void printB()
{
for(int i = 0; i < Math.pow(2,8); i++)
{
String format="%0"+8+"d";
System.out.printf(format,Integer.valueOf(Integer.toBinaryString(i)));
System.out.println();
}
}
Any help on how to generate this strings would be appreciated
If you want to have the binary number to be prefixed with 0-s you have to do a bit of work. Here I used a StringBuilder filled with 0s, replacing from the end the binary representation without 0 padding.
for (int i = 0; i <= 0xFF; i++) {
StringBuilder builder = new StringBuilder("00000000");
String binary = Integer.toBinaryString(i);
builder.replace(8 - binary.length(), 8, binary);
System.out.println(builder);
}
I recommend not working with strings of "1" and "0" except for formatting output. Internally you should store your "key" as a byte[8], so:
byte[] key = new byte[8];
for(int i=0; i<6; i++) {
key[i] = (byte) x + i;
}
key[6] = (byte) 0xff;
key[7] = (byte) 0xff;
As a first shot at converting this to a printable string, you just need:
String result = IntStream.range(0,8)
.map(i -> key[i])
.mapToObj(n -> intToBinaryString(n))
.collect(Collectors.joining(" "));
... and then you need an intToBinaryString() method. There are plenty of SO answers describing how to do this - for example: Print an integer in binary format in Java
I am working on a Huffman java application and i'm almost done. I have one problem though. I need to save a String of something like: "101011101010" to a file. When I save it with my current code it saves it as characters which take up 1 byte every 0 or 1. I'm pretty sure it's possible to save every 0/1 as a bit.
I already tried some things with BitSet and Integer.valueOf but I can't get them to work. This is my current code:
FileOutputStream fos = new FileOutputStream("encoded.bin");
fos.write(encoded.getBytes());
fos.close();
Where 'encoded' is a String which can be like: "0101011101".
If I try to save it as integer the leading 0 will be removed.
Thanks in advance!
EDIT: Huffman is a compression method so the outputted file should be as small as possible.
I think I found my answer. I put the 1's and 0's in a BitSet using the following code:
BitSet bitSet = new BitSet(encoded.length());
int bitcounter = 0;
for(Character c : encoded.toCharArray()) {
if(c.equals('1')) {
bitSet.set(bitcounter);
}
bitcounter++;
}
After that I save it to the file using bitSet.toByteArray()
When I want to read it again I convert it back to a bitset using BitSet.valueOf(bitSet.toByteArray()). Then I loop through the bitset like this:
String binaryString = "";
for(int i = 0; i <= set.length(); i++) {
if(set.get(i)) {
binaryString += "1";
} else {
binaryString += "0";
}
}
Thanks to everyone who helped me.
Binary files are limited to storing bits in multiples of eight. You can solve this problem by chopping the string into eight-bit chunks, converting them to bytes using Byte.parseByte(eightCharString, 2) and adding them to a byte array:
Compute the length of the byte array by dividing the length of your bit string by eight
Allocate an array of bytes of the desired length
Run a loop that takes substrings from the string at positions representing multiples of eight
Parse each chunk, and put the result into the corresponding byte
Call fos.write() on the byte array
Try this.
String encoded = "0101011101";
FileOutputStream fos = new FileOutputStream("encoded.bin");
String s = encoded + "00000000".substring(encoded.length() % 8);
for (int i = 0, len = s.length(); i < len; i += 8)
fos.write((byte)Integer.parseInt(s.substring(i, i + 8), 2));
fos.close();
In order to send a chunk of bits from a 4 words String, I'm doing getting the byte array from the String and calculating the bit string.
StringBuilder binaryStr = new StringBuilder();
byte[] bytesFromStr = str.getBytes("UTF-8");
for (int i = 0, l = bytesFromStr.length; i < l; i++) {
binaryStr.append(Integer.toBinaryString(bytesFromStr[i]));
}
String result = binaryStr.toString();
The problem appears when I want to do the reverse operation: converting a bit string to a Java String encoded using UTF-8.
Please, Is there someone that can explain me the best way to do that?
Thanks in advance!
TL;DR Don't use toBinaryString(). See solution at the end.
Your problem is that Integer.toBinaryString() doesn't return leading zeroes, e.g.
System.out.println(Integer.toBinaryString(1)); // prints: 1
System.out.println(Integer.toBinaryString(10)); // prints: 1010
System.out.println(Integer.toBinaryString(100)); // prints: 1100100
For your purpose, you want to always get 8 bits for each byte.
You also need to prevent negative values from causing errors, e.g.
System.out.println(Integer.toBinaryString((byte)129)); // prints: 11111111111111111111111110000001
Easiest way to accomplish that is like this:
Integer.toBinaryString((b & 0xFF) | 0x100).substring(1)
First, it coerces the byte b to int, then retains only lower 8 bits, and finally sets the 9th bit, e.g. 129 (decimal) becomes 1 1000 0001 (binary, spaces added for clarity). It then excludes that 9th bit, in effect ensuring that leading zeroes are in place.
It's better to have that as a helper method:
private static String toBinary(byte b) {
return Integer.toBinaryString((b & 0xFF) | 0x100).substring(1);
}
In which case your code becomes:
StringBuilder binaryStr = new StringBuilder();
for (byte b : str.getBytes("UTF-8"))
binaryStr.append(toBinary(b));
String result = binaryStr.toString();
E.g. if str = "Hello World", you get:
0100100001100101011011000110110001101111001000000101011101101111011100100110110001100100
You could of course just do it yourself, without resorting to toBinaryString():
StringBuilder binaryStr = new StringBuilder();
for (byte b : str.getBytes("UTF-8"))
for (int i = 7; i >= 0; i--)
binaryStr.append((b >> i) & 1);
String result = binaryStr.toString();
That will probably run faster too.
Thanks #Andreas for your code. I test using your function and "decoding" again to UTF-8 using this:
StringBuilder revealStr = new StringBuilder();
for (int i = 0; i < result.length(); i += 8) {
revealStr.append((char) Integer.parseUnsignedInt(result.substring(i, i + 8), 2));
}
Thanks for all folks to help me.
I have a byte array read over a network connection that I need to transform into a String without any encoding, that is, simply by treating each byte as the low end of a character and leaving the high end zero. I also need to do the converse where I know that the high end of the character will always be zero.
Searching the web yields several similar questions that have all got responses indicating that the original data source must be changed. This is not an option so please don't suggest it.
This is trivial in C but Java appears to require me to write a conversion routine of my own that is likely to be very inefficient. Is there an easy way that I have missed?
No, you aren't missing anything. There is no easy way to do that because String and char are for text. You apparently don't want to handle your data as text—which would make complete sense if it isn't text. You could do it the hard way that you propose.
An alternative is to assume a character encoding that allows arbitrary sequences of arbitrary byte values (0-255). ISO-8859-1 or IBM437 both qualify. (Windows-1252 only has 251 codepoints. UTF-8 doesn't allow arbitrary sequences.) If you use ISO-8859-1, the resulting string will be the same as your hard way.
As for efficiency, the most efficient way to handle an array of bytes is to keep it as an array of bytes.
This will convert a byte array to a String while only filling the upper 8 bits.
public static String stringFromBytes(byte byteData[]) {
char charData[] = new char[byteData.length];
for(int i = 0; i < charData.length; i++) {
charData[i] = (char) (((int) byteData[i]) & 0xFF);
}
return new String(charData);
}
The efficiency should be quite good. Like Ben Thurley said, if performance is really such an issue don't convert to a String in the first place but work with the byte array instead.
Here is a sample code which will convert String to byte array and back to String without encoding.
public class Test
{
public static void main(String[] args)
{
Test t = new Test();
t.Test();
}
public void Test()
{
String input = "Hèllo world";
byte[] inputBytes = GetBytes(input);
String output = GetString(inputBytes);
System.out.println(output);
}
public byte[] GetBytes(String str)
{
char[] chars = str.toCharArray();
byte[] bytes = new byte[chars.length * 2];
for (int i = 0; i < chars.length; i++)
{
bytes[i * 2] = (byte) (chars[i] >> 8);
bytes[i * 2 + 1] = (byte) chars[i];
}
return bytes;
}
public String GetString(byte[] bytes)
{
char[] chars = new char[bytes.length / 2];
char[] chars2 = new char[bytes.length / 2];
for (int i = 0; i < chars2.length; i++)
chars2[i] = (char) ((bytes[i * 2] << 8) + (bytes[i * 2 + 1] & 0xFF));
return new String(chars2);
}
}
Using deprecated constructor String(byte[] ascii, int hibyte)
String string = new String(byteArray, 0);
String is already encoded as Unicode/UTF-16. UTF-16 means that it can take up to 2 string "characters"(char) to make one displayable character. What you really want is to use is:
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(myString);
to convert a String to an array of bytes. This does exactly what you did above except it is 10 times faster in performance. If you would like to cut the transmission data nearly in half, I would recommend converting it to UTF8 (ASCII is a subset of UTF8) - the format the internet uses 90% of the time, by calling:
byte[] bytes = Encoding.UTF8.GetBytes(myString);
To convert back to a string use:
String myString = Encoding.Unicode.GetString(bytes);
or
String myString = Encoding.UTF8.GetString(bytes);
I have a question about converting String type binary number to bit and write in the txt file.
For example we have String like "0101011" and want to convert to bit type "0101011"
then write in to the file on the disk.
I would like to know is there anyway to covert to string to bit..
i was searching on the web they suggest to use bitarray but i am not sure
thanks
Try this:
int value = Integer.parseInt("0101011", 2); // parse base 2
Then the bit pattern in value will correspond to the binary interpretation of the string "0101011". You can then write value out to a file as a byte (assuming the string is no more than 8 binary digits).
EDIT You could also use Byte.parseByte("0101011", 2);. However, byte values in Java are always signed. If you tried to parse an 8-bit value with the 8th bit set (like "10010110", which is 150 decimal), you would get a NumberFormatException because values above +127 do not fit in a byte. If you don't need to handle bit patterns greater than "01111111", then Byte.parseByte works just as well as Integer.parseInt.
Recall, though, that to write a byte to a file, you use OutputStream.write(int), which takes an int (not byte) value—even though it only writes one byte. Might as well go with an int value to start with.
You can try the below code to avoid overflows of the numbers.
long avoidOverflows = Long.parseLong("11000000000000000000000000000000", 2);
int thisShouldBeANegativeNumber = (int) avoidOverflows;
System.out.println("Currect value : " + avoidOverflows + " -> " + "Int value : " + thisShouldBeANegativeNumber);
you can see the output
Currect value : 3221225472 -> Int value : -1073741824
//Converting String to Bytes
bytes[] cipherText= new String("0101011").getBytes()
//Converting bytes to Bits and Convert to String
StringBuilder sb = new StringBuilder(cipherText.length * Byte.SIZE);
for( int i = 0; i < Byte.SIZE * cipherText .length; i++ )
sb.append((cipherText [i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
//Byte code of input in Stirn form
System.out.println("Bytecode="+sb.toString()); // some binary data
//Convert Byte To characters
String bin = sb.toString();
StringBuilder b = new StringBuilder();
int len = bin.length();
int i = 0;
while (i + 8 <= len) {
char c = convert(bin.substring(i, i+8));
i+=8;
b.append(c);
}
//String format of Binary data
System.out.println(b.toString());