#include #include #include template class Stream { public: virtual bool more() = 0; virtual T value() { return _value; } protected: T _value; }; class BitStream : public Stream { }; typedef unsigned char byte; class ByteStream : public Stream { }; class FileToByteStream : public ByteStream { public: FileToByteStream(const char* name) { _f = fopen(name, "rb"); } virtual bool more() { if (_f == 0) return false; _value = fgetc(_f); if (feof(_f)) { fclose(_f); _f = 0; return false; } return true; } private: FILE *_f; }; void byteStreamToFile(ByteStream &input, const char* name) { FILE *f = fopen(name, "wb"); if (f == 0) return; while (input.more()) fputc(input.value(), f); fclose(f); } class BitToByteStreamConverter : public ByteStream { public: BitToByteStreamConverter(BitStream &bitStream) : _bitStream(bitStream) {} virtual bool more() { _value = 0; for (int i = 7; i >= 0; i--) { if (!_bitStream.more()) { if (i == 7) return false; break; } if (_bitStream.value()) _value |= 1 << i; } return true; } private: BitStream &_bitStream; byte _result; }; class BitToUnsigedStreamConverter : public Stream { public: BitToUnsigedStreamConverter(BitStream &bitStream, int n) : _bitStream(bitStream), _n(n) {} virtual bool more() { _value = 0; for (int i = _n - 1; i >= 0; i--) { if (!_bitStream.more()) { if (i == 0) return false; break; } if (_bitStream.value()) _value |= 1 << i; } return true; } private: BitStream &_bitStream; int _n; byte _result; }; class ByteToBitStreamConverter : public BitStream { public: ByteToBitStreamConverter(ByteStream &byteStream) : _byteStream(byteStream), _i(0) {} virtual bool more() { if (_i == 0) { if (!_byteStream.more()) return false; _v = _byteStream.value(); _i = 128; } _value = (_v & _i) != 0; _i /= 2; return true; } private: ByteStream &_byteStream; int _i; byte _v; }; class BalancedBitArray { public: BalancedBitArray(BitStream &key) : _key(key) {} void next() { bool filled[32]; for (int i = 0; i < 32; i++) filled[i] = false; BitToUnsigedStreamConverter perm(_key, 15); perm.more(); BitToByteStreamConverter p(_key); for (int nr_left = 32; nr_left > 0;) { p.more(); int j = 0; for (; j < 32; j++) if (!filled[j]) { _pattern[j] = p.value(); filled[j] = true; nr_left--; break; } int i2 = perm.value() % nr_left; for (; j < 32; j++) if (!filled[j]) { if (i2 == 0) { _pattern[j] = ~p.value(); filled[j] = true; nr_left--; break; } i2--; } } } bool getBit(int i) { return (_pattern[i / 8] & (1 << (i % 8))) != 0; } private: byte _pattern[32]; BitStream &_key; }; class EncryptWithRandomStream : public ByteStream { public: EncryptWithRandomStream(BitStream &input, BitStream &key, BitStream &random) : _input(input), _balancedBitArray(key), _random(random) {} virtual bool more() { if (!_input.more()) return false; _balancedBitArray.next(); BitToUnsigedStreamConverter ran(_random, 7); ran.more(); int r = ran.value(); for (_value = 0; _value < 256; _value++) if (_balancedBitArray.getBit(_value) == _input.value()) { if (r == 0) break; r--; } return true; } private: BitStream &_input; BalancedBitArray _balancedBitArray; BitStream &_random; }; class DecryptWithRandomStream : public BitStream { public: DecryptWithRandomStream(ByteStream &input, BitStream &key) : _input(input), _balancedBitArray(key) {} virtual bool more() { if (!_input.more()) return false; _balancedBitArray.next(); _value = _balancedBitArray.getBit(_input.value()); return true; } private: ByteStream &_input; BalancedBitArray _balancedBitArray; }; class RandomByteStream : public ByteStream { public: RandomByteStream() : _rng(std::chrono::steady_clock::now().time_since_epoch().count()) {} RandomByteStream(int seed) : _rng(seed) {} virtual bool more() { _value = std::uniform_int_distribution(0, 255)(_rng); return true; } private: std::mt19937 _rng; }; class PasskeyByteStream : public ByteStream { public: PasskeyByteStream(const char *key) : _rng(getSeed(key)), _key(key), _i(0) {} virtual bool more() { if (_key[++_i] == '\0') _i = 0; _value = _key[_i] ^ std::uniform_int_distribution(0, 255)(_rng); return true; } private: int getSeed(const char *key) { unsigned int seed = 0; int i = 0; int n = sizeof(int) * 8 - 7; for (const char *s = key; *s != '\0'; s++, i++) seed ^= (*s << (i & n)); return seed; } std::mt19937 _rng; const char *_key; int _i; }; int main(int argc, char *argv[]) { const char *passkey = argc > 1 ? argv[1] : "MyPassKey"; { FileToByteStream inputStream("Encrypt.cpp"); ByteToBitStreamConverter inputBitStream(inputStream); PasskeyByteStream key(passkey); ByteToBitStreamConverter keyBitStream(key); RandomByteStream random; ByteToBitStreamConverter randomBitStream(random); EncryptWithRandomStream encrypt(inputBitStream, keyBitStream, randomBitStream); byteStreamToFile(encrypt, "output.data"); } { FileToByteStream inputStream("output.data"); PasskeyByteStream key(passkey); ByteToBitStreamConverter keyBitStream(key); DecryptWithRandomStream decrypt(inputStream, keyBitStream); BitToByteStreamConverter decryptBytes(decrypt); byteStreamToFile(decryptBytes, "input_Encrypt.cpp"); } return 0; }