Java - need help handling binary / code strings

For a project, I need to convert a binary string to an (array) of bytes and write it to a file in binary format.

Say I have a sentence converted to a line of code using huffman encoding. For example, if the sentence was: "hello" h = 00 e = 01, l = 10, o = 11

Then the string representation will be 0001101011.

How do I convert this to bytes? <- If this question does not make sense, because I know little about bit / byte bitwise shifts and everything related to manipulating 1 and 0.

+3
source share
4 answers

( ) , 8 ( , 8).

Integer   , "0" "1" radix = 2.

static int parseInt(String s, int radix) 

, .

-

EDIT: Byte.parseByte - .

0

, , , :

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class BitOutputStream extends FilterOutputStream {

  private int bits = 0;
  private int n = 0;
  private long totalBits = 0;

  public BitOutputStream(OutputStream out) {
    super(out);
  }

  private void writeSingleBit(int bit) throws IOException {
    bits = (bits << 1) | (bit & 1);
    n++;
    totalBits++;
    if (n == 8) {
      super.write(bits);
      bits = 0;
      n = 0;
    }
  }

  /**
   * Writes the <i>numberOfBits</i> lower bits of <i>bitsToWrite</i> to the
   * output stream, starting with the most significant bit.
   */
  public void writeBits(int bitsToWrite, int numberOfBits) throws IOException {
    for (int i = numberOfBits - 1; i >= 0; i--) {
      int bit = bitsToWrite >> i;
      writeSingleBit(bit);
    }
  }

  @Override
  public void write(byte[] b, int off, int len) throws IOException {
    for (int i = 0; i < len; i++)
      writeBits(b[off + i], 8);
  }

  @Override
  public final void write(int b) throws IOException {
    writeBits(b, 8);
  }

  @Override
  public final void flush() throws IOException {
    writeBits(0, (8 - n) & 0x07);
  }

  /**
   * Returns the number of bits that have been written to this bitstream.
   */
  public long getTotalBits() {
    return totalBits;
  }
}

unit test:

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.junit.Test;

public class BitOutputStreamTest {

  @Test
  public void hello() throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BitOutputStream bos = new BitOutputStream(baos);
    bos.writeBits(0x00, 2);
    bos.writeBits(0x01, 2);
    bos.writeBits(0x02, 2);
    bos.writeBits(0x02, 2);
    bos.writeBits(0x03, 2);
    assertEquals(10, bos.getTotalBits());
    bos.close();
    assertEquals(16, bos.getTotalBits());
    assertArrayEquals(new byte[] { 0x1A, (byte) 0xC0 }, baos.toByteArray());
  }
}

, , , .

(2010-09-25): ​​ write(byte[], int, int). off .

+1

? .

, , byte, byte. . 1 , - :

b = (b << 1) | 1;

, , byte[], . ByteArrayOutputStream , byte, byte[] .

, , , , int . .

0

String bot , , .

Preon. Preon BitChannel, . BitChannel. "-" .

BitChannel channel = new OutputStreamBitChannel(...);
channel.write(1, 0); // 0 = 'h'
channel.write(2, 1); // 01 = 'e'
channel.write(3, 2); // 10 = 'l'
channel.write(4, 2); // 11 = '0'

However, ideally, you could use Preon's higher-level pre-abstractions (preon-binding), which would prevent you from even dealing with this yourself. This will just require annotation to your string.

@BoundHuffmanCoded String toBeEncoded = "hello";

... and Preon will take care of the rest. Now, remember, this is an ideal case, and Preon does not yet have this annotation. But for this you can register Codec. Keep an eye out for this, though, this is what will definitely be included in a future version of Preon.

0
source

Source: https://habr.com/ru/post/1749785/


All Articles