Necesito almacenar un par de secuencias binarias que son de 16 bits de longitud en una matriz de bytes (de longitud 2). Los uno o dos números binarios no cambian, por lo que una función que realiza la conversión podría ser una exageración. Digamos, por ejemplo, los 16 bits de secuencia binaria es 1111000011110001. ¿Cómo se almacena que en una matriz de bytes de longitud dos?

¿Cómo tener los bits ahora? Están en un entero? Una Cadena?
Se refieren a mi post para un enfoque general para estas conversiones.

OriginalEl autor Roger | 2011-03-23

2 Comentarios

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

    Hay otras opciones, pero me pareció mejor utilizar BigInteger clase, que ha de conversión de matriz de bytes, para este tipo de problemas. Prefiero si, porque puedo crear una instancia de la clase de String, que pueden representar varias de las bases como de 8, 16, etc. y también la producción como tal.

    Edit: Lunes … 😛

    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;
    }

    Ejemplo:

    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'));
    Esto funcionó al principio, pero ahora es el almacenamiento de una determinada secuencia de 16 bits en una matriz de longitud de uno (1). La matriz de bytes debe ser exactamente de dos (2) bytes de longitud.
    J. J. no estaba seguro de que, si has entendido mi respuesta inicial, así que he hecho un ejemplo. En este ejemplo tengo un número entero, que almacena los bits de la matriz. Puedo convertir a cadena que representa es la forma binaria. Luego me llama a una función, que devuelve las matrices de bytes primeros 2 bytes. Yo no estaba seguro de si iba a ser difícil para usted para verificar la salida, así que he añadido una línea de salida. Se debe imprimir 12321:11000000100001:[33, 48].

    OriginalEl autor Margus

  2. 6

    Me ha decepcionado con todas las soluciones que he encontrado para convertir cadenas de bits para matrices de bytes y viceversa — todos han sido buggy (incluso el BigInteger solución más arriba), y muy pocos son tan eficientes como deberían ser.

    Me doy cuenta de que el OP se preocupa sólo de una cadena de bits a una matriz de dos bytes, que la BitInteger enfoque parece funcionar bien. Sin embargo, dado que este post es actualmente el primer resultado de la búsqueda al buscar «cadena de bits a la matriz de bytes de java» en Google, voy a publicar mi solución general aquí para la gente que trabaja con grandes cadenas y/o grandes matrices de bytes.

    Nota que mi solución a continuación es la única solución que he encontré que pasa todos mis casos de prueba — muchas soluciones en línea para esta relativamente simple problema simplemente no funcionan.

    Código

    /**
    * 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;
    }
    }

    Rendimiento

    Yo estaba aburrido en el trabajo, así que hice algunas pruebas de rendimiento comparando contra el aceptado respuesta aquí para cuando N es grande. (Fingiendo ignorar el hecho de que el BigInteger enfoque publicado anteriormente ni siquiera funciona correctamente como un enfoque general.)

    Este se está ejecutando con una muestra aleatoria de cadena de bits de tamaño 5M y una al azar matriz de bytes de tamaño 1M:

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

    Y el código:

      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();
    }
    }
    }
    Mi primera pulgar downer en TAN… cuidado de explicar?

    OriginalEl autor Ryan

Dejar respuesta

Please enter your comment!
Please enter your name here