以下は実際のストリーム(std :: istream)であり、C ++11<random>ライブラリを使用します。
これは特に高速であるように書かれていませんが、それは楽しいです:
#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;
}
このプログラムの出力(正確には、標準では、デフォルトで構築されたメルセンヌツイスターに特定のシードがあることが保証されているため):
ugsyakganihodonwmktggixegfszuclgupylingbnscxadzqhjmhhyqtssbmctlpchqfflzfwhvjywmajtnkaxczrmtpnlvwmzxd
編集:
追加のボーナスポイントとして、StreamHasherクラスを追加しました:
https ://wandbox.org/permlink/bIDCVTnJjkdafARo
追加されたクラスのみ:
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(); }
};
例えば
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';
}