«Алгоритм шифрования DES»
Учебная программа на C++ Visual Studio.
Задание:
Программно реализовать алгоритм шифрования и дешифрования для любых типов файлов по следующим правилам:
- Исходный текст (массив байт) сжимается по алгоритму RLE;
- Полученный массив кодируется по алгоритму Хаффмана;
- Полученный массив кодируется с помощью алгоритма DES.
Дешифрование проводится в обратном порядке…
Размер ключа (массива) должен быть 64 бита (или 8 байт) и храниться в отдельном файле.
Решение:
Понятно, что, в реальной жизни, от надежности (случайности) ключа зависит многое, но здесь в задании ни слова не говорится об этом. То есть можно брать (пусть даже одинаковые) первые 8 байт ключевого файла.
Интерфейс пусть будет наипростейший. Две кнопки «Обзор» для выбора файлов подлежащих шифрованию и дешифрованию и для
соответствующих операций кнопки «Кодирование» и «Декодирование».
Успешная работа кнопок "Кодирование" и "Декодирование" заканчивается сообщением "Файл успешно сохранен...". Создаваемый файл (закодированный или декодированный) всегда сохраняется в ту же папку, где указывался исходный файл... Изменяются только расширения файлов.
Так, закодированный файл сохранит исходное название и расширение файла, но получит дополнительное расширение ".des" .
А декодированный файл восстановит первоначальное расширение, но чтобы его не путали с исходным файлом, в конце имени
появится окончание "_des" .
Как видите, исходным файлом являлся «Notebook.txt». После кодирования появился «Notebook.txt.des», а после декодирования «Notebook_des.txt». Неудивительно, что размеры первоначального и конечного файлов совпадают…
Об алгоритме сжатия RLE можно прочитать здесь
C++ Visual Studio
RLE - алгоритм сжатия данных без потерь
Об алгоритме сжатия Хаффмана (Huffman) можно прочитать здесь
C++ Visual Studio
алгоритм Хаффмана (Huffman) -сжатие данных без потерь
Об наложении этих алгоритмов (RLE + Huffman) можно прочитать здесь
C++ Visual Studio
Двойное сжатие (RLE + Huffman)
Программная реализация алгоритма DES (фрагменты)
Идея алгоритма DES проста. Исходный файл рубится на пакеты по 8 байт (64 бита) и биты каждого пакета перемешиваются настолько тщательно (производится несколько различных стандартных перестановок + некоторые из них с использованием битов ключа), что собрать их обратно (в исходный порядок) весьма проблематично… особенно если не знаешь ключа…
Процедура кодирования отдельного пакета у меня выглядят так:
Void DES_pak::encodeDES(void){ //
for(unsigned int i=0; i<8; i++)
{ unsigned char c=0;
for(unsigned int j=0; j<8; j++)
if(BitValue(psourc,IP[8*i+j])) c+=1<<j;
pres[i]=c;
}// начальная перестановка закончена
psourc=CycleFeistel(pres); //Циклы с функц Фейстеля
for(unsigned int i=0; i<8; i++)
{ unsigned char c=0;
for(unsigned int j=0; j<8; j++)
if(BitValue(psourc,IP_rev[8*i+j])) c+=1<<j;
pres[i]=c;
}// конечная перестановка закончена (обратная начальной)
}
Как видите, алгоритмы начальной и конечной перестановок бит абсолютно одинаковы, но используют различные (взаимообратные)
константные массивы const int IP[64] или const int IP_rev[64]. Данные константные массивы описаны в алгоритме
и не являются секретом…
А между ними используется прямой Цикл функций Фейстеля CycleFeistel(pres);
Вспомогательная функция «Значение бита» возвращает либо 1, либо 0 (в зависимости, установлен заданный бит в исходном пакете или нет). Вот ее код (параметр num - номер бита в блоке)…
bool DES_pak::BitValue(unsigned char *blok, unsigned int num){
UINT_64 tmp=*(UINT_64*)blok;
tmp >>= num;
tmp &= 1;
return (tmp!=0);
}
Процедура декодирования отдельного пакета очень похожа и выглядят так:
Void DES_pak::decodeDES(void){ //
for(unsigned int i=0; i<8; i++)
{ unsigned char c=0;
for(unsigned int j=0; j<8; j++)
if(BitValue(psourc,IP[8*i+j])) c+=1<<j;
pres[i]=c;
}// начальная перестановка закончена
psourc=CycleFeistel_rev(pres); //Циклы с функц Фейстеля
for(unsigned int i=0; i<8; i++)
{ unsigned char c=0;
for(unsigned int j=0; j<8; j++)
if(BitValue(psourc,IP_rev[8*i+j])) c+=1<<j;
pres[i]=c;
}// конечная перестановка закончена (обратная начальной)
}
От процедуры кодирования её отличает то, что Цикл функций Фейстеля здесь обратный CycleFeistel_rev(pres);
В общем, ничего сложного… Тестируйте… Желающих могу проконсультировать по Skype…
скачать exe-файл для тестирования
Другие примеры на тему «Шифрование, Кодирование и/или Сжатие Информации»
Другие примеры на языках «C»,«C++»,«C#»
Поделиться в соц сетях: