如何在C / C ++中随机翻转char的二进制位

时间:2014-06-12 10:13:50

标签: c++ c

如果我有一个char数组A,我用它来存储十六进制

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

此char数组的二进制表示形式为:

00001010 11110101 01101101 00000010  

我想问一下是否有任何功能可以随意翻转位?

那是:
如果参数是5

00001010 11110101 01101101 00000010   
-->

10001110 11110001 01101001 00100010  

它将随机选择5位翻转。

我正在尝试将此十六进制数据转换为二进制数据并使用位掩码方法来实现我的要求。然后将其转回十六进制。我很好奇有没有办法更快地完成这项工作?

抱歉,我的问题描述不够明确。简而言之,我有一些十六进制数据,我想模拟这些数据中的位错误。例如,如果我有5个字节的十六进制数据:

    "FF00FF00FF" 

二进制表示是

    "1111111100000000111111110000000011111111" 

如果误码率为10%。然后我想让这40位有4位错误。一个极端随机结果:前4位发生错误:

    "0000111100000000111111110000000011111111" 

6 个答案:

答案 0 :(得分:2)

首先,找出该位代表的字符:

param是你要翻转的......

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

这样就会给你一个指向该数组偏移量的char的指针(-1代表0数组偏移量与大小)

然后得到模数(如果你感觉冒险的话,或者更多的位移)来找出这里要翻转的位:

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

因此,对于A [10]处的字节,应该得到5的参数,以使其第5位切换。

答案 1 :(得分:1)

  1. 将数组2 ^ n存储在数组
  2. 生成随机数种子
  3. 循环x次(在本例中为5)并转到数据^ = stored_values [random_num]
  4. 除了将2 ^ n值存储在数组中之外,您可以将某些位移位到2的随机幂,如:

    data ^= (1<<random%7)
    

    反映第一条评论,你真的可以在函数中写出5行,并完全避免for循环的开销。

答案 2 :(得分:0)

1.取输入的mod 8(5%8)

2.按输入值(例如5)向右移动0x80

3.XX使用字符数组的(input / 8)元素。

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

      }

答案 3 :(得分:0)

1.)首先随机选择x个位置(每个位置由数组索引和位位置组成)。

2。)现在,如果你想从右边翻转 th 位,那么 n 。通过 2 n 查找 n 的剩余部分:

int divisor = (2,i);

int remainder = n % divisor;

int quotient = n / divisor;

remainder = (remainder==0) ? 1 : 0; //从右边翻转余数或i th 位。

n = divisor * quotient + remainder;

答案 4 :(得分:0)

你有32位数。您可以将这些位视为数字的一部分,并将该数字与一些随机的5位数字进行对比。

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

答案 5 :(得分:0)

我认为没有理由将整个字符串来回转换为十六进制表示法。只需从十六进制字符串中选择一个随机字符,将其转换为数字,稍稍更改一下,转换回十六进制字符。

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

可能甚至可以省略转换为和从ASCII转换的步骤 - 在字符串中翻转一下,检查它是否仍然是有效的十六进制数字,如有必要,请进行调整。