Cómo voltear aleatoriamente un bit binario de char en C/C++
Frecuentes
Visto 3,132 equipos
2
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"
6 Respuestas
2
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
- generar una semilla de número aleatorio
- 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
0
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
0
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
0
Primero, elija al azar x posiciones (cada posición consiste en el índice de matriz y la posición del bit).
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
0
Tome mod 8 de entrada (5% 8)
cambio
0x80
a la derecha por valor de entrada (por ejemplo, 5)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 c++ c or haz tu propia pregunta.
¿Podría explicar qué significa "elegir al azar 5 bits"? - Vlad from Moscow
muéstrenos algún código que declare/defina la matriz de caracteres A - Iosif Murariu
¿Se puede voltear el mismo bit más de una vez? Por favor, elabore su pregunta. - Parag Gangil
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"; - Liam
No, un bit solo cambia como máximo una vez. - Liam