String of 0's and 1's to File as bits - 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();

Related

Java decryption from byte to text

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.

JAVA - Write binary number to a file and read it

How can i write to a file a binary number without it to cut the zeros .
I'm writing like this :
byte[] b = new BigInteger("1011010101010110", 2).toByteArray();
FileOutputStream fos = new FileOutputStream("file",true);
fos.write(b);
But then for example : When i write 0000001, it writes in the file just 1 and ignores the zeros, the same happens if i write 001001001000 , it ignores the zeros on the left reading 8bits at the time from the right to the left.
What is the correct way to write binary digits to a file ? If this is the correct way, i'm might be trying to read the file in the wrong way ( I'm using the read() of InputStream )
Ps-(8 digits must be 1 byte so writing as a string is not an option, cause each digit is 1 byte.)
You can try something like this
String s = "0000001";
byte[] a = new byte[s.length()];
for (int i = 0; i < s.length(); i++) {
a[i] = (byte) (s.charAt(i) & 1);
}
You don't want to write it as a binary, you want to write it as a String representing the binary. The problem is that Java has no way to know you want it padded. I would suggest converting your binary numbers to a String, then left-padding with 0 (Apache StringUtils will help with this)

Converting String type binary number to bit in java

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());

How to put a string into a position in a byte array in Java?

I've pretty much reached a brick wall and could use some advice on how to proceed with a project for one of my courses. Here's code I'm trying to get to work:
for(i = 0; i < sendData.length; i++){
String hex = Integer.toHexString(C[i]);
}
System.out.println("Encrypted Message: ");
for(i = 0; i < sendData.length; i++){
System.out.print(sendData[i]);
}
As a bit of a background this is for code for RC4 encryption. I've trying to put the value of hex in a position in sendData[] which is a fixed byte array. Because hex is a string I haven't really found a way to put that value in a position in the sendData array. I know I can't use the getBytes() function as it completely gets rid of the hex values. If anyone has any idea on how to take a string value and put it into a position in a fixed byte array it'd be greatly appreciated.
You need to understand Integer is of 4 bytes not a single byte so you will need array 4 bytes rather than storing in loop with single bytes. You can convert an Integer to byte[] like below.
public static byte[] toByteArray(int value)
{
ByteBuffer bb = ByteBuffer.allocate(4);
return bb.putInt(value).array();
}
public long toInteger(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.put(bytes);
return buffer.getInt();
}

Taking a string representation of a large integer and converting it to a byte array in Java

Basically, my problem is two-fold, and refers pretty specifically to the Bitcoin RPC. I am writing a miner in Java for Litecoin (a spinoff of BTC) and need to take a string that looks like:
000000000000000000000000000000000000000000000000000000ffff0f0000
Convert it to look like
00000fffff000000000000000000000000000000000000000000000000000000
(Which I believe is switching from little endian to big endian)
I then need to turn that string into a byte array --
I've looked at the Hex class from org.apache, String.toByte(), and a piece of code that looks like:
public static byte[] toByta(char[] data) {
if (data == null) return null;
// ----------
byte[] byts = new byte[data.length * 2];
for (int i = 0; i < data.length; i++)
System.arraycopy(toByta(data[i]), 0, byts, i * 2, 2);
return byts;
}
So essentially: What is the best way, in Java to change endianness? And what is the best way to take a string representation of a number and convert it to a byte array to be hashed?
EDIT: I had the wrong result after changing the endian.
Integer and BigInteger both have toString methods taking a radix, so
you can get the hex String.
You can make a StringBuffer from that
String and call reverse().
You then convert back to a String using
toString(), then get the bytes via getBytes();
Don't know if this is "best" but it requires little work on your part.
If you need better speed, call getBytes() on the original wrong direction hex string (from step 1) and reverse it in place using a for loop. e.g.
for (int i=0; i<bytes.length/2; i++) {
byte temp = bytes[i];
bytes[i] = bytes[bytes.length - i];
bytes[bytes.length - i] = temp;
}

Categories