繁体   English   中英

在字节数组中存储二进制序列?

[英]Store binary sequence in byte array?

我需要将一对长度为16位的二进制序列存储到一个字节数组(长度为2)中。 一个或两个二进制数不会更改,因此执行转换的函数可能过度。 例如,16位二进制序列是1111000011110001.如何将其存储在长度为2的字节数组中?

    String val = "1111000011110001";
    byte[] bval = new BigInteger(val, 2).toByteArray();

还有其他选择,但我发现最好使用BigInteger类,它有转换为字节数组,以解决这类问题。 我更喜欢if,因为我可以从String实例化类,它可以代表各种基础,如8,16等,也可以输出它。

编辑:星期一......:P

public static byte[] getRoger(String val) throws NumberFormatException,
        NullPointerException {
    byte[] result = new byte[2];
    byte[] holder = new BigInteger(val, 2).toByteArray();

    if (holder.length == 1) result[0] = holder[0];
    else if (holder.length > 1) {
        result[1] = holder[holder.length - 2];
        result[0] = holder[holder.length - 1];
    }
    return result;
}

例:

int bitarray = 12321;
String val = Integer.toString(bitarray, 2);
System.out.println(new StringBuilder().append(bitarray).append(':').append(val)
  .append(':').append(Arrays.toString(getRoger(val))).append('\n'));

我对将字符串转换为字节数组的所有解决方案感到失望,反之亦然 - 所有这些都是错误的(即使是上面的BigInteger解决方案),并且很少有效率应该如此高。

我意识到OP只涉及到两个字节数组的位串,BitInteger方法似乎可以正常工作。 但是,由于这篇文章是目前搜索Google中“bit string to byte array java”的第一个搜索结果,我将在这里发布我的通用解决方案,用于处理大字符串和/或大字节数组的人。

请注意,我的解决方案是我运行的唯一通过所有测试用例的解决方案 - 许多在线解决方案对这个相对简单的问题根本不起作用。

/**
 * Zips (compresses) bit strings to byte arrays and unzips (decompresses)
 * byte arrays to bit strings.
 *
 * @author ryan
 *
 */
public class BitZip {

  private static final byte[] BIT_MASKS = new byte[] {1, 2, 4, 8, 16, 32, 64, -128};
  private static final int BITS_PER_BYTE = 8;
  private static final int MAX_BIT_INDEX_IN_BYTE = BITS_PER_BYTE - 1;

  /**
   * Decompress the specified byte array to a string.
   * <p>
   * This function does not pad with zeros for any bit-string result
   * with a length indivisible by 8.
   *
   * @param bytes The bytes to convert into a string of bits, with byte[0]
   *              consisting of the least significant bits in the byte array.
   * @return The string of bits representing the byte array.
   */
  public static final String unzip(final byte[] bytes) {
    int byteCount = bytes.length;
    int bitCount = byteCount * BITS_PER_BYTE;

    char[] bits = new char[bitCount];
    {
      int bytesIndex = 0;
      int iLeft = Math.max(bitCount - BITS_PER_BYTE, 0);
      while (bytesIndex < byteCount) {
        byte value = bytes[bytesIndex];
        for (int b = MAX_BIT_INDEX_IN_BYTE; b >= 0; --b) {
          bits[iLeft + b] = ((value % 2) == 0 ? '0' : '1');
          value >>= 1;
        }
        iLeft = Math.max(iLeft - BITS_PER_BYTE, 0);
        ++bytesIndex;
      }
    }
    return new String(bits).replaceFirst("^0+(?!$)", "");
  }

  /**
   * Compresses the specified bit string to a byte array, ignoring trailing
   * zeros past the most significant set bit.
   *
   * @param bits The string of bits (composed strictly of '0' and '1' characters)
   *             to convert into an array of bytes.
   * @return The bits, as a byte array with byte[0] containing the least
   *         significant bits.
   */
  public static final byte[] zip(final String bits) {
    if ((bits == null) || bits.isEmpty()) {
      // No observations -- return nothing.
      return new byte[0];
    }
    char[] bitChars = bits.toCharArray();

    int bitCount = bitChars.length;
    int left;

    for (left = 0; left < bitCount; ++left) {
      // Ignore leading zeros.
      if (bitChars[left] == '1') {
        break;
      }
    }
    if (bitCount == left) {
      // Only '0's in the string.
      return new byte[] {0};
    }
    int cBits = bitCount - left;
    byte[] bytes = new byte[((cBits) / BITS_PER_BYTE) + (((cBits % BITS_PER_BYTE) > 0) ? 1 : 0)];
    {
      int iRight = bitCount - 1;
      int iLeft = Math.max(bitCount - BITS_PER_BYTE, left);
      int bytesIndex = 0;
      byte _byte = 0;

      while (bytesIndex < bytes.length) {
        while (iLeft <= iRight) {
          if (bitChars[iLeft] == '1') {
            _byte |= BIT_MASKS[iRight - iLeft];
          }
          ++iLeft;
        }
        bytes[bytesIndex++] = _byte;
        iRight = Math.max(iRight - BITS_PER_BYTE, left);
        iLeft = Math.max((1 + iRight) - BITS_PER_BYTE, left);
        _byte = 0;
      }
    }
    return bytes;
  }
}

性能

我在工作中感到无聊,所以我做了一些性能测试,比较了当N很大时接受的答案。 (假装忽略上面发布的BigInteger方法甚至不能作为一般方法正常工作的事实。)

这是使用大小为5M的随机位字符串和大小为1M的随机字节数组运行的:

String -> byte[] -- BigInteger result: 39098ms
String -> byte[] -- BitZip result:     29ms
byte[] -> String -- Integer result:    138ms
byte[] -> String -- BitZip result:     71ms

和代码:

  public static void main(String[] argv) {

    int testByteLength = 1000000;
    int testStringLength = 5000000;

    // Independently random.
    final byte[] randomBytes = new byte[testByteLength];
    final String randomBitString;
    {
      StringBuilder sb = new StringBuilder();
      Random rand = new Random();

      for (int i = 0; i < testStringLength; ++i) {
        int value = rand.nextInt(1 + i);
        sb.append((value % 2) == 0 ? '0' : '1');
        randomBytes[i % testByteLength] = (byte) value;
      }
      randomBitString = sb.toString();
    }

    byte[] resultCompress;
    String resultDecompress;
    {
      Stopwatch s = new Stopwatch();
      TimeUnit ms = TimeUnit.MILLISECONDS;
      {
        s.start();
        {
          resultCompress = compressFromBigIntegerToByteArray(randomBitString);
        }
        s.stop();
        {
          System.out.println("String -> byte[] -- BigInteger result: " + s.elapsed(ms) + "ms");
        }
        s.reset();
      }
      {
        s.start();
        {
          resultCompress = zip(randomBitString);
        }
        s.stop();
        {
          System.out.println("String -> byte[] -- BitZip result:     " + s.elapsed(ms) + "ms");
        }
        s.reset();
      }
      {
        s.start();
        {
          resultDecompress = decompressFromIntegerParseInt(randomBytes);
        }
        s.stop();
        {
          System.out.println("byte[] -> String -- Integer result:    " + s.elapsed(ms) + "ms");
        }
        s.reset();
      }
      {
        s.start();
        {
          resultDecompress = unzip(randomBytes);
        }
        s.stop();
        {
          System.out.println("byte[] -> String -- BitZip result:     " + s.elapsed(ms) + "ms");
        }
        s.reset();
      }
    }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM