Cómo voltear aleatoriamente un bit binario de char en C/C++

Si tengo una matriz de caracteres A, lo uso para almacenar hexadecimal

A = "0A F5 6D 02"   size=11

La representación binaria de esta matriz de caracteres es:

00001010 11110101 01101101 00000010  

Quiero preguntar si hay alguna función que pueda voltear el bit al azar.

Esto es:
si el parámetro es 5

00001010 11110101 01101101 00000010   
-->

10001110 11110001 01101001 00100010  

elegirá aleatoriamente 5 bits para voltear.

Estoy tratando de convertir estos datos hexadecimales en datos binarios y usar el método de máscara de bits para lograr mi requisito. Luego gírelo de nuevo a hexadecimal. Tengo curiosidad, ¿hay algún método para hacer este trabajo más rápido?

Lo siento, la descripción de mi pregunta no es lo suficientemente clara. Simplemente, tengo algunos datos hexadecimales y quiero simular un error de bit en estos datos. Por ejemplo, si tengo datos hexadecimales de 5 bytes:

"FF00FF00FF" 

representación binaria es

"1111111100000000111111110000000011111111" 

Si la tasa de error de bit es del 10%. Entonces quiero hacer que estos 40 bits tengan un error de 4 bits. Un resultado aleatorio extremo: ocurrió un error en los primeros 4 bits:

"0000111100000000111111110000000011111111" 

preguntado el 12 de junio de 14 a las 11:06

¿Podría explicar qué significa "elegir al azar 5 bits"? -

muéstrenos algún código que declare/defina la matriz de caracteres A -

¿Se puede voltear el mismo bit más de una vez? Por favor, elabore su pregunta. -

Por ejemplo, si tengo datos hexadecimales de 100 bytes. Habrá 100*8 bits en representación binaria. Quiero hacer que el 10% de estos bits sean aleatorios 0->1 o 1->0. 10% es mi parámetro. Y matriz A --> char A[]="0A F5 6D 02"; -

No, un bit solo cambia como máximo una vez. -

6 Respuestas

En primer lugar, averigüe qué carácter representa el bit:

param es tu bit para voltear...

char *byteToWrite = &A[sizeof(A) - (param / 8) - 1];

Eso le dará un puntero al carácter en ese desplazamiento de matriz (-1 para 0 desplazamiento de matriz frente al tamaño)

Luego obtenga el módulo (o más cambios de bit si se siente aventurero) para averiguar qué bit cambiar aquí:

*byteToWrite ^= (1u << param % 8);

Entonces eso debería dar como resultado un parámetro de 5 para el byte en A[10] para tener su 5to bit alternado.

Respondido 25 Feb 21, 17:02

Leí la pregunta como comenzando desde la derecha, y usted la leyó como desde la izquierda ... lo cual es comprensible, ya que el bit 5 desde cualquier extremo en el ejemplo binario trabajado está configurado: 00001010 11110101 01101101 00000010 vs 10001110 11110001 01101001 00100010 De cualquier manera, espero que sea suficiente para ayudar a este tipo. - fquinner

Sizeof(A) siempre le devolverá '4'. Cualquiera que sea la cantidad de elementos de la matriz, eso es lo que estoy tratando de señalar. - Vago

La pregunta indicada A es una matriz, no un char* - sizeof (char[11]) devolverá 11. - fquinner

Pruébelo: sizeof (char*) devolverá el tamaño del puntero local (generalmente 4 en una máquina de 32 bits u 8 en una máquina de 64 bits). sizeof(A) donde char[11] A = {0x01, .... etc.}; regresará 11.- fquinner

Sí, me di cuenta de eso, lo siento. - Vago

  1. almacenar los valores de 2^n en una matriz
  2. generar una semilla de número aleatorio
  3. recorre x veces (en este caso 5) y ve data ^= valores_almacenados[número_aleatorio]

Alternativamente a almacenar los valores 2^n en una matriz, podría cambiar un poco a una potencia aleatoria de 2 como:

data ^= (1<<random%7)

Reflejando el primer comentario, realmente podría escribir esa línea 5 veces en su función y evitar por completo la sobrecarga de un bucle for.

Respondido 06 Jul 14, 07:07

no necesita hacer un bucle si lo hace *(arreglo + n), donde n es el n-ésimo byte en el arreglo (asumiendo que es un char matriz) - Iósif Murariu

Tienes un número de 32 bits. Puede tratar los bits como partes del número y simplemente modificar este número con algún número aleatorio de 5 bits.

int count_1s(int )
{
  int m = 0x55555555;
  int r = (foo&m) + ((foo>>>1)&m);
  m = 0x33333333;
  r = (r&m) + ((r>>>2)&m);
  m = 0x0F0F0F0F;
  r = (r&m) + ((r>>>4)&m);
  m = 0x00FF00FF;
  r = (r&m) + ((r>>>8)&m);
  m = 0x0000FFFF;
  return r = (r&m) + ((r>>>16)&m);
}

void main()
{
   char input[] = "0A F5 6D 02";
   char data[4] = {};
   scanf("%2x %2x %2x %2x", &data[0], &data[1], &data[2], &data[3]);
   int *x = reinterpret_cast<int*>(data);
   int y = rand();
   while(count_1s(y) != 5)
   {
      y = rand(); // let's have this more random
   }
   *x ^= y;
   printf("%2x %2x %2x %2x" data[0], data[1], data[2], data[3]);
   return 0;
}

Respondido el 12 de junio de 14 a las 13:06

No veo ninguna razón para convertir toda la cadena de ida y vuelta desde y hacia la notación hexadecimal. Simplemente elija un carácter aleatorio de la cadena hexadecimal, conviértalo en un dígito, cámbielo un poco, vuelva a convertirlo en carácter hexadecimal.

En llano C:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main (void)
{
    char *hexToDec_lookup = "0123456789ABCDEF";
    char hexstr[] = "0A F5 6D 02";

    /* 0. make sure we're fairly random */
    srand(time(0));

    /* 1. loop 5 times .. */
    int i;

    for (i=0; i<5; i++)
    {
        /* 2. pick a random hex digit
              we know it's one out of 8, grouped per 2 */
        int hexdigit = rand() & 7;
        hexdigit += (hexdigit>>1);

        /* 3. convert the digit to binary */
        int hexvalue = hexstr[hexdigit] > '9' ? hexstr[hexdigit] - 'A'+10 : hexstr[hexdigit]-'0';

        /* 4. flip a random bit */
        hexvalue ^= 1 << (rand() & 3);

        /* 5. write it back into position */
        hexstr[hexdigit] = hexToDec_lookup[hexvalue];

        printf ("[%s]\n", hexstr);
    }

    return 0;
}

It podría incluso sería posible omitir los pasos de conversión a y desde ASCII: cambie un poco la cadena de caracteres, verifique si todavía es un dígito hexadecimal válido y, si es necesario, ajústelo.

Respondido el 12 de junio de 14 a las 22:06

  1. Primero, elija al azar x posiciones (cada posición consiste en el índice de matriz y la posición del bit).

  2. Ahora si quieres voltear ith bit desde la derecha para un número n. Encuentre el resto de n by 2n como :

código:

int divisor = (2,i);
int remainder = n % divisor;
int quotient = n / divisor;
remainder = (remainder == 0) ? 1 : 0; // flip the remainder or the i th bit from right. 

n = divisor * quotient + remainder;

Respondido 25 Feb 21, 17:02

  1. Tome mod 8 de entrada (5% 8)

  2. cambio 0x80 a la derecha por valor de entrada (por ejemplo, 5)

  3. XOR este valor con (entrada/8) elemento de su matriz de caracteres.

código:

void flip_bit(int bit)
{
    Array[bit/8]  ^= (0x80>>(bit%8));
}

Respondido 25 Feb 21, 17:02

¿Qué es Ex-OR? solo he oído hablar de XOR o Exclusive OR :) - Iósif Murariu

El operador para Ex-OR en C es "^" (a^b). - Vago

ohh, lo llamo Ex-OR (Exclusive OR) lo siento. - Vago

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.