Bit Shuffle

I’m trying to generate a random bit mask of n bits.

I’m using this algorithm, but it is not portable… it uses bitRead() and bitWrite() macros.

void setup()
{
  Serial.begin(9600);
  Serial.println(setRandomBits(4), BIN);
}

void loop()
{
  
}

byte setRandomBits(byte number_Bits)
{
  randomSeed(analogRead(A4));
  byte mask = 1;
  for(int i = 0; i < number_Bits - 1; i++)
  {
    mask <<= 1;
    mask |= 1;
  }
  Serial.println(mask, BIN);
  for(int i = 0; i < 8; i++)
  {
    byte swapLocation = random(i, 8);
    byte currentBit = mask & (1 << i);  // grab the byte in the i-th location
    byte targetBit = mask & (1 << swapLocation);  // get the bit in the swapLocation 
    bitWrite(mask, i, targetBit);
    bitWrite(mask, swapLocation, currentBit);
  }
  return mask;
}

I’ve spent some time with just using bitwise tools, but I’m stumped.

messing about in this direction:

if (targetBit)
{
  mask &= (currentBit << swapLocation);  // keep bit lit only if both are lit
}
else
{
  mask |= (currentBit << swapLocation);  // keep bit lit if currentBit is lit
}
if (currentBit)
{
  //mask &=
}

I think it should be simpler, so I’m calling for fresh minds.

Please no comments on the randomness of reading an analog pin… :wink:

What about selecting a byte value from 0 to 255 at random. Then you have 8 random bits.

If you want fewer than 8 bits limit the range. For example a random number from 0 to 127 will give you 7 random bits.

…R

I’m trying to generate a random bit mask of n bits

From that description, if it is truly a random mask, then any random integer < 2n satisfies your criterion. Or do you mean “n” one bits?

Robin2: What about selecting a byte value from 0 to 255 at random. Then you have 8 random bits.

If you want fewer than 8 bits limit the range. For example a random number from 0 to 127 will give you 7 random bits.

...R

I like that approach, thought about it but I want to be able to know exactly how many bits (passed in the argument) will be randomized.

The application is a Daily Timer library I am writing that uses a bit mask to determine if a timer is supposed to activate on certain (specified or random) days of the week at certain (random or specified) times of the day.

I want to be able to randomly select say two, three, four etc. days in a week and shuffle them. So, the random byte must end up with a preset number of ones.

A simple array, perhaps... eight bytes and shuffle that. I was hoping a cleverer person may have an easy bitwise solution. Sometimes you can spend so much time on an elegant solution that you get tunnel vision.

like this:

byte setRandomBits(byte number_Bits)
{
  randomSeed(analogRead(A4));
  byte mask = 0;
  byte array[8] = {0};
  for (int i = 0; i < number_Bits; i++)
  {
    array[i] = 1;
  }
  for(int i = 0; i < 8; i++)
  {
    byte index = random(i, 8);
    byte temp = array[i];
    array[i] = array[index];
    array[index] = temp;
  }
  for (int i = 0; i < 8; i++)
  {
    mask |= (array[i] << i);
  }
  return mask;
}

BulldogLowell: I want to be able to randomly select say two, three, four etc. days in a week and shuffle them. So, the random byte must end up with a preset number of ones.

I misunderstood. I don't think my idea would be suitable.

...R

Robin2: I misunderstood. I don't think my idea would be suitable.

...R

It is possible to generate random numbers until given criteria are met. It may slow if criteria are tight but in this application it looks like you have plenty of time.

I’m using this algorithm, but it is not portable… it uses bitRead() and bitWrite() macros.

You can easily look up what they do in the source.

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

Another random thought - could you make an array of bytes with qualifying values - for example every byte from the 256 possibles that has 4 bits set. Then you could select from that array at random.

...R