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

我需要将一个长度为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. * 

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