Create random byte stream

I am testing a network program that sends a packet to a remote server using UDP / TCP, and for this 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; } 
+7
source share
4 answers

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

gen_rdm_bytestream might look something like this:

 #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 the stream is unsigned, if the value returned by rand greater than UCHAR_MAX , it will be reduced (modulo UCHAR_MAX ). Therefore, you will get pseudo-random numbers from 0 to 255.

+6
source

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

Returns a pseudo-random integer ranging from 0 to RAND_MAX. RAND_MAX is a constant defined in.

This number is generated by an algorithm that, with each call, returns a sequence of apparently unrelated numbers. This algorithm uses seed to generate a series that must be initialized with some distinguishing value using the srand () function .

EDIT :

As you comment, I wrote code for you that can help you demonstrate how to use rand (), the program, and its output:

 #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

+1
source

Here's a general function for getting 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 ); } 

Using 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(); 
+1
source

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

It is not particularly written to be quick, but it is 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 (precisely because the standard guarantees that the default Mersenne twister has a given initial number):

ugsyakganihodonwmktggixegfszuclgupylingbnscxadzqhjmhhyqtssbmctlpchqfflzfwhvjywmajtnkaxczrmtpnlvwmzxd

EDIT:

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

Just 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 instance

 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'; } 
0
source

All Articles