'Generate a random byte stream

I'm testing a network program that sends packet to a remote server using UDP/TCP, and for that, I want to generate some random byte streams.

Here's the function:

unsigned char *gen_rdm_bytestream(int num_bytes)
{
    unsigned char *stream = malloc(num_bytes);
    /*
     * here how to generate?
     */
    return stream;
}
c


Solution 1:[1]

For each byte, you can call a random number generator function. The C standard provides the function rand. Before using it, you should initialize the random sequence with a call to srand.

gen_rdm_bytestream may then look something like that:

#include <stdlib.h>
#include <time.h>

unsigned char *gen_rdm_bytestream (size_t num_bytes)
{
  unsigned char *stream = malloc (num_bytes);
  size_t i;

  for (i = 0; i < num_bytes; i++)
  {
    stream[i] = rand ();
  }

  return stream;
}

srand ((unsigned int) time (NULL));

Since stream is unsigned, if the value returned by rand is greater than UCHAR_MAX, she will be reduced (modulo UCHAR_MAX). Therefore you will get pseudo-random numbers between 0 and 255.

Solution 2:[2]

Yes, you have int rand (void); function in C,

Returns a pseudo-random integral number in the range between 0 and RAND_MAX. RAND_MAX is a constant defined in <cstdlib>.

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function srand().

EDIT:

As you are commenting, I have written a code for you that may help you to demonstrate, How to use rand(), the program and its output are:

#include <stdio.h>     
#include <stdlib.h>  /* srand, rand */
#include <time.h>    
int main (){
 int i=0;
 srand (time(NULL));
 printf("Five rand numbers: \n");
 for(i = 1; i <= 5; i++){
   printf("\n %d", rand());
 }
 printf("Five rand numbersb between 2 to 5: \n");
 for(i = 1; i <= 5; i++){
   printf("\n %d", (2 + rand()%4));
 }    
 return 1;
} 

Output:

 Five rand numbers: 

 1482376850
 1746468296
 1429725746
 595545676
 1544987577

 Five rand numbers, between 2 to 5: 

 2
 5
 3
 4
 3

Codepad Link

Solution 3:[3]

Here's a general function for producing random integer values in a given range:

#include <stdlib>

/**
 * Assumes srand has already been called
 */
int randInRange( int min, int max )
{
  double scale = 1.0 / (RAND_MAX + 1);
  double range = max - min + 1;
  return min + (int) ( rand() * scale * range );
}

Leveraging this to create unsigned char values:

u_char randomByte()
{
  return (u_char) randInRange( 0, 255 );
}

So,

for ( i = 0; i < numBytes; i++ )
  stream[i] = randomByte();

Solution 4:[4]

On UNIX, there is the getrandom system call.

#include <sys/random.h>
#include <stdlib.h>

unsigned char * gen_rdm_bytestream(size_t const num_bytes) {
    unsigned char * const stream = malloc(num_bytes);
    getrandom(stream, num_bytes, 0);
    return stream;
}

Solution 5:[5]

The following is an actually stream (std::istream) and uses the C++11 <random> library.

This is not particularly written to be fast, but it it's fun:

#include <iostream>
#include <string>
#include <array>
#include <algorithm>
#include <random>

class RandomBuf : public std::streambuf
{
 private:
  size_t m_size;
  std::array<char, 64> m_buf;
  std::mt19937_64 m_twister;
  std::uniform_int_distribution<char> m_dist;

 protected:
  int_type underflow() override {
    if (m_size == 0)
      return EOF;

    size_t size = std::min(m_size, m_buf.size());
    setg(&m_buf[0], &m_buf[0], &m_buf[size]);
    for (size_t i = 0; i < size; ++i)
      m_buf[i] = m_dist(m_twister);
    m_size -= size;
    return 0;
  }

 public:
  RandomBuf(size_t size, char b, char e) : m_size(size), m_dist(b, e) { }
};

class Random : public std::istream
{
  private:
   RandomBuf m_streambuf;

  public:
   Random(size_t size, char b, char e) : m_streambuf(size, b, e)  {
     rdbuf(&m_streambuf);
   }
};

// Example usage:

int main()
{
  Random random(100, 'a', 'z'); // Create an istream that produces 100 pseudo-random characters in the interval ['a', 'z'].
  // Read random stream to a string:
  std::string str;
  random >> str;
  // Print result.
  std::cout << str << std::endl;
}

The output of this program (exactly, because the standard guarantees that a default constructed Mersenne twister has a given seed):

ugsyakganihodonwmktggixegfszuclgupylingbnscxadzqhjmhhyqtssbmctlpchqfflzfwhvjywmajtnkaxczrmtpnlvwmzxd

EDIT:

For extra bonus points I added a StreamHasher class: https://wandbox.org/permlink/bIDCVTnJjkdafARo

Just the added classes:

class StreamHasherBuf : public std::streambuf
{
 private:
  size_t m_hash;
  std::array<char, 64> m_buf;   // The resulting hash value is a function of the size of the array!
  static constexpr size_t bufsize = std::tuple_size_v<decltype(m_buf)>;

  void add_and_reset_put_area()
  {
    boost::hash_combine(m_hash, boost::hash_range(pbase(), pptr()));
    setp(&m_buf[0], &m_buf[bufsize]);
  }

 protected:
  int_type overflow(int_type c) override
  {
    if (c != EOF)
    {
      if (pptr() == epptr())
        add_and_reset_put_area();
      *pptr() = c;
      pbump(1);
    }
    return 0;
  }

 public:
  StreamHasherBuf() : m_hash(0) { setp(&m_buf[0], &m_buf[bufsize]); }

  size_t hash()
  {
    add_and_reset_put_area();
    return m_hash;
  }
};

class StreamHasher : public std::ostream
{
 private:
  StreamHasherBuf m_streambuf;

 public:
  StreamHasher() { rdbuf(&m_streambuf); }
  size_t hash() { return m_streambuf.hash(); }
};

For example

int main()
{
  RandomBuf random(100, 'a', 'z'); // Create a streambuf that produces 100 pseudo-random characters in the interval ['a', 'z'].
  StreamHasher hasher;
  hasher << &random;
  std::cout << hasher.hash() << '\n';
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Daniel Marschall
Solution 3 John Bode
Solution 4 nog642
Solution 5