|
|
|
| Задала мне училка написать программку на VC++, которая зашифровывает и расшифровывает строку. Так как я ленивый и пишу мало, то возникла куча вопросов.
1. При шифровании данные заносятся в текстовый файл(например строку crypt зашифровало так: 57 4 88 70 51), как считать из файла эти числа, чтобы расшифровать???
2. Как расшифрованое число перевести в символ(из символьного я делал так int(text[i]))?
3. И наверное самое главное(но не обязательно), что меня бесило это большие числа. Нарыл я где-то функцию, которая возводит в степень и берет остаток по модулю, но не врублюсь каким макаром она работает. Если не сложно, то растолкуйте
//a^m % m
int modpow(int a, unsigned long long n, int m) {
if (n == 1)
return a % m;
unsigned long long z;
z = modpow(a, n / 2, m);
z = (z * z) % m;
if (n % 2 == 1)
z = (z * a) % m;
return (int)z;
}
|
Сам алгоритм подробно рассказан
habrahabr_ru/blogs/infosecurity/49634/ или paveldvlip_ru/algorithms/rsa.html | |
|
|
|
|
|
|
|
для: morgan18
(06.12.2011 в 18:52)
| | 3. На пальцах это вот что. Число a^m - очень большое и не убирается в базовом типе, поэтому его нужно либо хранить в строке, что медленно и требуется много памяти, либо вообще не вычислять, тем более оно нам не нужно, нам нужен a^m % m, т.е. узнать, будет ли это конечное число делиться без остатка на m или нет, а если будет, то какой будет остаток. Поэтому операция a^m разгалается на m отдельных операций a * a * a * ... * a. Цикл по этим итерациям реализован в виде рекурсии - вызова функции modpow() самой себя. Причем на каждой итерации мы не вычисляем значение a * a, а вычисляем какой будет остаток. Это позволяет оставаться в рамках базовых чисел не вылезая за границы числа. | |
|
|
|
|
|
|
|
для: cheops
(06.12.2011 в 19:38)
| | сдесь я чуть ошибся a^m % m. нужно было так a^n % m. | |
|
|
|
|
|
|
|
для: cheops
(06.12.2011 в 19:38)
| | эта функция аналогичная той рекурсивной или нет?
// ищем ( x ^ e ) % n
int modpow(int x, unsigned long long e, int n)
{
int r = 1;
while(e > 0)
{
if( (e%2)==1 )
{
r = (r*x) % n;
}
e = e/2;
x = (x * x) % n;
}
return r;
}
|
| |
|
|
|
|
|
|
|
для: morgan18
(06.12.2011 в 18:52)
| | 1. А нельзя файл прикрепить, чтобы было над чем по-экспериментировать? | |
|
|
|
|
13 байт |
|
|
для: cheops
(06.12.2011 в 19:39)
| | там зашифрована строка crypt. Я брал ASCII код букв и шифровал так сказать. | |
|
|
|
|
|
|
|
для: morgan18
(06.12.2011 в 20:07)
| | При разборе такого файла можно начать отталкиваться от следующей программы (при условии конечно, строго формата, для простоты большинство проверок опущены)
#include <stdio.h>
#include <io.h>
#include <iostream>
using namespace std;
// Прототипы функций
long filesize(FILE *pFile);
// Главная функция
int main()
{
// Вспомогательные структуры и дескрипторы
FILE * pFile;
long i, k, chartotal, numbertotal = 0;
// Открываем файл
pFile = fopen ("crypt.txt", "rb");
if (pFile == NULL)
{
cerr << "Не удалось открыть файл" << endl;
return 1;
}
// Определяем размер файла
chartotal = filesize(pFile);
// Резервируем строку под содержимое файла
char *str = new char[chartotal];
// Читаем содержимое файла
long result = fread (str, 1, chartotal, pFile);
if (result != chartotal)
{
cerr << "Не удалось прочитать файл" << endl;
return 1;
}
// Закрываем файл
fclose (pFile);
// Подсчитываем количество целых чисел:
// количество пробелов + 1
for(i = 0; i < chartotal; i++)
{
if(str[i] == ' ') numbertotal++;
}
if(numbertotal) numbertotal++;
// Выделяем память под массив чисел
int *arr = new int[numbertotal];
// Заполняем массив
char test[80];
int beg = 0, end = 0;
for(i = 0, k = 0; i < chartotal; i++)
{
if(str[i] == ' ')
{
beg = end;
end = i + 1;
strncpy(test, str + beg, end - 1 - beg);
test[end - 1 - beg] = '\0';
arr[k++] = atoi(test);
}
}
// Обрабатываем последнее число отдельно
strncpy(test, str + end, chartotal - 1 - end);
arr[k++] = atoi(test);
// Выводим содержимое массива arr с числами
for(i = 0; i < numbertotal; i++)
{
cout << arr[i] << endl;
}
// Освобождаем выделенную память
delete [] str;
delete [] arr;
// Пауза перед закрытием
system("PAUSE");
return 0;
}
long filesize(FILE *pFile)
{
long result;
fseek (pFile , 0 , SEEK_END);
result = ftell (pFile);
rewind (pFile);
return result;
} |
| |
|
|
|
|
|
|
|
для: cheops
(06.12.2011 в 21:51)
| | спасибо большое)))) посмотрю еще, поэксперементирую. | |
|
|
|
|
|
|
|
для: morgan18
(06.12.2011 в 18:52)
| | 2. Имеется в виду как получить код символа или перевести код в символ? Для этого есть специальные функции atoi() и itoa(). | |
|
|
|
|
|
|
|
для: cheops
(06.12.2011 в 19:47)
| | за функции спасибо, попробую. нужно перевести код в символ. | |
|
|
|