fork download
  1. #include <algorithm>
  2. #include <array>
  3. #include <cstdlib>
  4. #include <ctime>
  5. #include <iostream>
  6. #include <memory>
  7.  
  8. using namespace std;
  9.  
  10. class RBG;
  11. class SimpleRBG;
  12. class SHA1;
  13. class BitInputStream;
  14. template <class X> class PrimitiveBitInputStream;
  15.  
  16. class RBG {
  17. public:
  18. virtual bool getBit() = 0;
  19. };
  20.  
  21. class SimpleRBG : public RBG {
  22. public:
  23. SimpleRBG();
  24. virtual bool getBit();
  25. protected:
  26. shared_ptr<array<unsigned long, 5> > hash;
  27. unsigned int pos;
  28. };
  29.  
  30. class SHA1 {
  31. public:
  32. static shared_ptr<array<unsigned long, 5> > computeHash(const shared_ptr<BitInputStream>& msg);
  33. protected:
  34. SHA1();
  35. typedef unsigned long (*FUNCTION)(const unsigned long& x, const unsigned long& y, const unsigned long& z);
  36. static const FUNCTION FUNCTIONS[4];
  37. static const unsigned long K[4];
  38. static const unsigned long INITIAL_HASH_VALUES[5];
  39. static unsigned long ch(const unsigned long& x, const unsigned long& y, const unsigned long& z);
  40. static unsigned long parity(const unsigned long& x, const unsigned long& y, const unsigned long& z);
  41. static unsigned long maj(const unsigned long& x, const unsigned long& y, const unsigned long& z);
  42. };
  43.  
  44. class BitInputStream {
  45. public:
  46. virtual bool getBit() = 0;
  47. virtual bool isEOF() = 0;
  48. };
  49.  
  50. template <class X>
  51. class PrimitiveBitInputStream : public BitInputStream {
  52. public:
  53. PrimitiveBitInputStream(const X& x);
  54. virtual bool getBit();
  55. virtual bool isEOF();
  56. protected:
  57. X x;
  58. unsigned int pos;
  59. PrimitiveBitInputStream(const PrimitiveBitInputStream& sbin);
  60. PrimitiveBitInputStream& operator =(const PrimitiveBitInputStream& sbin);
  61. };
  62.  
  63. template <class X> X rotateLeft(const X& x, const unsigned int& n, const unsigned int& w = (sizeof(X) << 3));
  64.  
  65. SimpleRBG::SimpleRBG() : hash(nullptr), pos(160) {
  66. srand((unsigned int)time(nullptr) ^ (unsigned int)clock());
  67. }
  68.  
  69. bool SimpleRBG::getBit() {
  70. if (this->pos >= 160) {
  71. this->hash = SHA1::computeHash(shared_ptr<BitInputStream>(new PrimitiveBitInputStream<int>(rand())));
  72. this->pos = 0;
  73. }
  74. bool res = ((this->hash->at(this->pos >> 5) >> (32 - 1 - (this->pos & 0x1F))) & 1) == 1;
  75. this->pos++;
  76. return res;
  77. }
  78.  
  79. const SHA1::FUNCTION SHA1::FUNCTIONS[4] = {
  80. ch,
  81. parity,
  82. maj,
  83. parity,
  84. };
  85.  
  86. const unsigned long SHA1::K[4] = {
  87. 0x5a827999,
  88. 0x6ed9eba1,
  89. 0x8f1bbcdc,
  90. 0xca62c1d6,
  91. };
  92.  
  93. const unsigned long SHA1::INITIAL_HASH_VALUES[5] = {
  94. 0x67452301,
  95. 0xefcdab89,
  96. 0x98badcfe,
  97. 0x10325476,
  98. 0xc3d2e1f0,
  99. };
  100.  
  101. shared_ptr<array<unsigned long, 5> > SHA1::computeHash(const shared_ptr<BitInputStream>& msg) {
  102. shared_ptr<array<unsigned long, 5> > hash(new array<unsigned long, 5>);
  103. copy(INITIAL_HASH_VALUES, INITIAL_HASH_VALUES + 5, &hash->front());
  104. shared_ptr<array<unsigned long, 16> > block(new array<unsigned long, 16>);
  105. shared_ptr<array<unsigned long, 80> > sche(new array<unsigned long, 80>);
  106. unsigned long long len = 0;
  107. bool put_end = false;
  108. bool put_len = false;
  109. while (!put_len) {
  110. block->fill(0);
  111. unsigned int block_pos = 0;
  112. for (; block_pos < 512 && !msg->isEOF(); block_pos++) {
  113. block->at(block_pos >> 5) |= (msg->getBit() == true ? 1 : 0) << (32 - 1 - (block_pos & 0x1f));
  114. len++;
  115. }
  116. if (block_pos < 512) {
  117. if (!put_end) {
  118. block->at(block_pos >> 5) |= 1 << (32 - 1 - (block_pos & 0x1f));
  119. block_pos++;
  120. put_end = true;
  121. }
  122. if (block_pos + 64 <= 512) {
  123. block->at(14) = len >> 32;
  124. block->at(15) = len & 0xffffffff;
  125. put_len = true;
  126. }
  127. }
  128. for (unsigned int i = 0; i < 80; i++) {
  129. if (i < 16) sche->at(i) = block->at(i);
  130. else sche->at(i) = rotateLeft(
  131. sche->at(i - 3) ^
  132. sche->at(i - 8) ^
  133. sche->at(i - 14) ^
  134. sche->at(i - 16), 1);
  135. }
  136. unsigned long a = hash->at(0);
  137. unsigned long b = hash->at(1);
  138. unsigned long c = hash->at(2);
  139. unsigned long d = hash->at(3);
  140. unsigned long e = hash->at(4);
  141. for (unsigned int i = 0; i < 80; i++) {
  142. unsigned long t =
  143. rotateLeft(a, 5) +
  144. FUNCTIONS[i / 20](b, c, d) +
  145. e +
  146. K[i / 20] +
  147. sche->at(i);
  148. e = d;
  149. d = c;
  150. c = rotateLeft(b, 30);
  151. b = a;
  152. a = t;
  153. }
  154. hash->at(0) += a;
  155. hash->at(1) += b;
  156. hash->at(2) += c;
  157. hash->at(3) += d;
  158. hash->at(4) += e;
  159. }
  160. return hash;
  161. }
  162.  
  163. unsigned long SHA1::ch(const unsigned long& x, const unsigned long& y, const unsigned long& z) {
  164. return (x & y) ^ (~x & z);
  165. }
  166.  
  167. unsigned long SHA1::parity(const unsigned long& x, const unsigned long& y, const unsigned long& z) {
  168. return x ^ y ^ z;
  169. }
  170.  
  171. unsigned long SHA1::maj(const unsigned long& x, const unsigned long& y, const unsigned long& z) {
  172. return (x & y) ^ (x & z) ^ (y & z);
  173. }
  174.  
  175. template <class X>
  176. PrimitiveBitInputStream<X>::PrimitiveBitInputStream(const X& x) : x(x), pos(0) {}
  177.  
  178. template <class X>
  179. bool PrimitiveBitInputStream<X>::getBit() {
  180. bool res = ((this->x >> ((sizeof(X) << 3) - 1 - this->pos)) & 1) == 1;
  181. this->pos++;
  182. return res;
  183. }
  184.  
  185. template <class X>
  186. bool PrimitiveBitInputStream<X>::isEOF() {
  187. return this->pos >= (sizeof(X) << 3);
  188. }
  189.  
  190. template <class X> X rotateLeft(const X& x, const unsigned int& n, const unsigned int& w) {
  191. return (x << n) | (x >> (w - n));
  192. }
  193.  
  194. int main() {
  195. shared_ptr<RBG> rbg(new SimpleRBG());
  196. for (unsigned int i = 0; i < 20; i++) {
  197. for (unsigned int j = 0; j < 40; j++) {
  198. cout << (rbg->getBit() == true ? '.' : ' ');
  199. }
  200. cout << endl;
  201. }
  202. return 0;
  203. }
  204.  
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
........... .....  .. . .. ...   .....  
.....   ...  ..... . . . .. .. .   .  . 
  ..  .   .. .. ...   .. ..    ... . .. 
  ..  . . .... ....... .  .. ....     . 
 ..  .   ... . .  ..  .  . .  . .. .. . 
.   .. .. ... ..  .. ..  .... . .. ... .
  ..   . . ...  ..... .   .   ...   .. .
..  ...    ...      . . .. .. . .  .  . 
     ..  ....     .   . ... .......  . .
   ....   .  ..  . ....    . .     .... 
. .....  . .. .   .   .. . .    ..  ... 
.   .. .   .  . .. .. .    .. . .  .  ..
 .    ..   ..... .......  ....   . .  . 
. . ..   ... .  . .  .  .. . .  .   .  .
........ .   .. ..  ..  . . .......  ...
.. .    .  .. . ... .   . . ..       ...
. ...... .   ...  .  .. .. .. .. .  .  .
  ... . .. ..... .  ..   . . . .    . ..
 ...    . ... . ....  . .  . ..... .  ..
. . ... .. ..  . .  . .  ..   ..  ..