А вот теперь я приведу подход к созданию простых, но устойчивых шифров. Суть подхода заключается в том, что для надежного шифрования длина ключа должна быть больше длины шифруемого сообщения, не содержать повторений и прочих артефактов, по которым можно определить формат сообщения. Такими свойствами обладают неприводимые многочлены Галуа - многочлены, период повторения которых очень велик по сравнению с длиной и сложностью самого многочлена. С помощью таких многочленов можно генерить сверх длинные неповторяющиеся последовательности, к примеру, многочлен третьего порядка (с тремя коэффициентами) - позволяет сгенерировать 7 неповторяющихся чисел (2^x-1) Файл KeyGenerator.h /*/////////////////////////////////////////////////////////////// KeyGenerator, GNU C++, 2005-01-18 Генератор длинных ключей на основе неприводимых многочленов Галуа Artix, master@7masterov.ru, icq:53666599, skype:artixmaster * Error in code? Nothing is perfect! * Free source for free Linux, use it for free! * Please, do not remove this comment! ///////////////////////////////////////////////////////////////*/ #ifndef KeyGeneratorH #define KeyGeneratorH class KeyGenerator { private: unsigned int vKeyValue; // Значение unsigned int vBitMaskLen; // Битовая длина маски (0xFF) unsigned int vBitMask; // = 2^vBitMaskLen-1 unsigned int vPolinom; // Битовый полином public: KeyGenerator(); unsigned int GetKey(); void SetBitMaskLen(unsigned int iBitMaskLen); void SetKeyValue(unsigned int iStartValue); }; // class #end Файл KeyGenerator.c #include "KeyGenerator.h" KeyGenerator::KeyGenerator() { vPolinom = 0x05; vKeyValue = 1; vBitMaskLen = 3; vBitMask = 0x07; } // Установка "рабочего поля" void KeyGenerator::SetBitMaskLen(unsigned int iBitMaskLen) { vBitMask = 1; vBitMaskLen = iBitMaskLen; for(unsigned int i=1;i<vBitMaskLen;i++) vBitMask|=(vBitMask<<1); } // Установка стартового значения void KeyGenerator::SetKeyValue(unsigned int iStartValue) { vKeyValue = iStartValue; } // Получение псевдослучайного числа unsigned int KeyGenerator::GetKey() { // bit = бит переноса // vBitMask = поле маски // vPolinom = неприводимый многочлен unsigned int bit=0; for(unsigned int i=0,b=1; i<vBitMaskLen; i++,b<<=1) bit+=(((vKeyValue&b&vPolinom)!=0)?1:0); bit&=0x01; vKeyValue<<=1; vKeyValue|=bit; vKeyValue&=vBitMask; return vKeyValue; } Пример использования класса: KeyGenerator p; // Стартовое значение p.SetKeyValue( 1 ); // Период повторения ключа = 2^3-1 = 7 p.SetBitMaskLen( 3 ); int rndKey; // Получаем псевдослучайную последовательность for(int i=0;i<32;i++) { rndKey = p.GetKey(); } В дальнейшем с полученной последовательностью ключей можно делать XOR, сдвиг, замену - но лучше сделать обмен блоков, что-то типа упрощенного алгоритма DES, и тогда надежность шифра сильно-сильно возрастет. Стоит также отметить, что неприводимых многочленов не так уж и много, поиск таких многочленов - это отдельная задача, и в реальных боевых задачах лучше использовать многочлены 32-ого порядка и выше, всегда осложняя их перестановками блоков.
Справочник алгоритмов v0.05 © 2007-2025 Igor Salnikov aka SunDoctor