Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.60
nubo
113 / 70 / 8
Регистрация: 31.07.2010
Сообщений: 334
#1

Шифратор пароля. Покритикуйте пожалуйста. - C++

06.08.2010, 01:48. Просмотров 1878. Ответов 24
Метки нет (Все метки)

Это моя первая программка на С++, если кому не лень, натычте меня носом в ляпы.
Чтобы не топтаться по граблям.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
 
using namespace std;
 
char randChar()
{
    int n, i = 0;
 
    while(i < 500)
    { 
        n = -32 + rand() % 210;
 
        if((n > -32 && n < -15) || (n > 33 && n < 176))
        {
            i++;
            return char(n);
        } 
    }
}
 
 
int encodePass(string main_pass, string new_pass, string resours_name)
{
 
    int num;
    string code, len_pass;
    size_t new_len  = new_pass.size();
    size_t main_len = main_pass.size();
    size_t max_len, code_len;
 
    srand(time(0));
    resours_name = "data\\"+ resours_name +".txt";
 
    if(main_len <= new_len)
    {
        for(int i = main_len - 1; i < new_len; ++i)
            main_pass += main_pass;
 
        max_len = main_pass.size();
    }
    else
        max_len = new_len + 1; 
 
    len_pass = char(new_len + 100);
 
    for(int j = 0; j < max_len; ++j)
    {
        if(j > new_len)
            break;
 
            num = abs((int)main_pass[j]);
 
        for(int i = 0; i < num; ++i)
            code += randChar();
 
        if(j == 0)
            code += len_pass;
        else
            code += new_pass[j - 1];
    }
 
    code_len = code.size();
 
    if(code_len < 20000)
        for(int i = code_len; i < 20000; ++i)
            code  += randChar();    
 
    ofstream ofs;
    ofs.open(resours_name.c_str());
    ofs << code;
    ofs.close();
        cout << "Готово\n";
    return 0;
}
 
 
int decodePass(string main_pass, string resours)
{
    int num = 0, pos = -1, len_pass;
    string code_pass, pass, cript, file_name;
    file_name = "data\\"+ resours +".txt";
    size_t max_len = main_pass.size();
 
    ifstream ifs; 
    ifs.open(file_name.c_str());
        if(!ifs)
        {
            cout << "Не найден файл с паролем для ресурса " << resours <<"\n";
            return EXIT_FAILURE;
        }
    ifs >> code_pass;
 
    cript = main_pass;
 
    for(int i = 0; i < 30; ++i)
        cript += main_pass;
 
    max_len = cript.size();
 
    for(int j = 0; j < max_len; ++j)
    {
        num = abs((int)cript[j]);
        pos = pos + num + 1;
 
        if(j == 0)
            len_pass = (int)code_pass[pos] - 100;
        else
            pass  += code_pass[pos];
 
        if(j > len_pass - 1)
            break;
    }
 
    if(pass != "")
        cout << "Пароль к ресурсу "<< resours <<" - "<< pass << endl;
    else
        cout << "Основной пароль введен неверно. Включилась система самоликвидации. "<< endl;
 
    return 0;
}
 
 
int main()
{
    setlocale(LC_ALL,"Russian");
 
    string select, main_pass, new_pass, resours_name;
    cout << "Для шифрации пароля введите 1, для дешифрации 2  ";
    getline(cin, select);
 
 
     while(true)
     {
        if(select == "1")
        {
 
            while(true)
            {
                cout << "Введите и запомните основной пароль (минимум 3 символа, максимум 30) ";
                getline(cin, main_pass);
 
                if(main_pass.size() > 2 && main_pass.size() < 31 )
                    break;
                else
                    cout << "Слишком короткий либо слишком длинный пароль\n";
            }
 
            cout << "Введите название ресурса, для которого предназначен пароль ";
            getline(cin, resours_name);
 
            while(true)
            {
                cout << "Введите пароль, который нужно зашифровать (минимум 3 символа, максимум 30)";
                getline(cin, new_pass);
 
                if(new_pass.size() > 2 && new_pass.size() < 31 )
                    break;
                else
                    cout << "Слишком короткий либо слишком длинный пароль\n";
            }
                        
            encodePass(main_pass.c_str(), new_pass.c_str(), resours_name.c_str());
            break;
        }
        
        if(select == "2")
        {
            cout << "Введите название ресурса, для которого предназначен пароль ";
            getline(cin, resours_name);
            cout << "Введите основной пароль ";
            getline(cin, main_pass);
            decodePass(main_pass.c_str(), resours_name.c_str());
            break;
        }
        else
        {
            cout << "Для шифрации пароля введите 1, для дешифрации 2 ";
            getline(cin, select);
        }
     }          
  
   return 0;
}
благодарю за терпение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.08.2010, 01:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шифратор пароля. Покритикуйте пожалуйста. (C++):

Покритикуйте пожалуйста программу - C++
Student.h#ifndef _STUDENT_H #define _STUDENT_H class Student { public: Student(); void del(); ...

Оценка безопасности пароля путем перебора пароля из словаря - C++
Разработать программное обеспечение для оценки степени безопасности паролей пользователей. Я уже скачал пару словарей паролей из...

Покритикуйте код - C++
Покритикуйте код, я точно знаю, что он нубовский но все же. Это моя первая программа на с++ которая делает , что то полезное и типо мой...

Покритикуйте код - C++
Есть класс Студенты (реализован через односвязный список), хотел бы услышать критику по поводу его улучшения, если кому не лень разбираться...

Покритикуйте мою игру - C++
Выкладываю код своей первой игры. Она готова процентов на 90, но уже работает. Интересно узнать мнение людей, что в ней можно улучшить,...

Графы. Покритикуйте код - C++
Нужно помощь тех кто работает и пишет хороший и красивый код. У меня построено три матрицы, подскажите как улучшить код. Где можно...

24
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
06.08.2010, 05:43 #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char randChar()
{
    int n, i = 0;
 
    while(i < 500)
    { 
        n = -32 + rand() % 210;
 
        if((n > -32 && n < -15) || (n > 33 && n < 176))
        {
            i++;
            return char(n);
        } 
    }
}
i++ не там

C++
1
2
    ofs.open(resours_name.c_str());
    ofs << code;
проверить, открылся ли файл
ofs.is_open(), ofs.is_good()

C++
1
int encodePass(string main_pass, string new_pass, string resours_name)
C++
1
encodePass(main_pass.c_str(), new_pass.c_str(), resours_name.c_str());
надо без c_str(), строка предполагает, что пароль не может содержать нуль-символ
то есть string - это удобно, но пароль типа { '\0', '\1', '\2', '\3', 0xFF } передать не получится, он будет как бы нулевой длины

C++
1
int decodePass(string main_pass, string resours)
C++
1
decodePass(main_pass.c_str(), resours_name.c_str());
тоже по типам несовпадение, без c_str() надо
2
nubo
113 / 70 / 8
Регистрация: 31.07.2010
Сообщений: 334
06.08.2010, 09:33  [ТС] #3
Спасибо.
i++ не там
Действительно не там. Вернее оно там вообще не нужно. Смысл этой функции в том, чтобы выдать случайный символ из заданного прерывного диапазона. Надежнее вот так надо было:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
char randChar()
{
    int n;
 
    while(true)
    { 
        n = rand() % 210 - 32;
 
        if((n > -32 && n < -15) || (n > 33 && n < 176))
            return char(n);
 
    }
}
хотя циклы без явного условия выхода меня малость напрягают... Но это все же лучше, чем goto.

С проверкой открытия файла - упущение. Спасибо.

А вот с типы данных меня в гроб загонят.
Про нуль-символы впопыхах не подумал. Вот теперь вообще не представляю, как можно по другому.
c_str() я убрал, а все равно не то.

И у меня еще один вопрос. В чем разница между
C++
1
std::cout<<
и
C++
1
2
using namespace std;
cout<<
Вторая форма удобнее, но почему то постоянно встречаю первую. Где то тут не чисто...

Еще раз спасибо.
0
Nameless One
Эксперт С++
5774 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
06.08.2010, 10:41 #4
Цитата Сообщение от nubo Посмотреть сообщение
И у меня еще один вопрос. В чем разница между...
И в первом, и во втором случае ты обращаешься к объекту cout, объявленному в пространстве имен std. Но во втором случае ты "засоряешь" глобальное пространство имен, т.к. теперь ты уже не сможешь объявить и использовать идентификатор для объекта, если этот идентификатор уже объявлен пространстве имен std (или объявить функцию, если ее сигнатура совпадает с сигнатурой функции, объявленной в std).
Так что использовать первую форму записи считается более правильным. Если же лень постоянно писать что-то типа std::cout, то в крайнем случае можно поступить так:
C++
1
2
3
4
5
6
7
8
using std::cout;
using std::cin;
using std::endl;
//.....
int i;
cout << "Input i: ";
cin >> i;
cout << "i = " << i << endl
Это уже не является таким страшным грехом, как использование всего пространства имен
1
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 12:12 #5
Цитата Сообщение от nubo Посмотреть сообщение
Смысл этой функции в том, чтобы выдать случайный символ из заданного прерывного диапазона.
Цитата Сообщение от nubo Посмотреть сообщение
хотя циклы без явного условия выхода меня малость напрягают... Но это все же лучше, чем goto.
может стоит подумать по поводу подобных методов генерации?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <cstdlib>
 
char rand_char_range(char min, char max)
{
    return min + (char)((max - min + 1) * rand() / RAND_MAX);
}
 
int main()
{
    for(int i = 0; i < 30; ++i)
        std::cout << rand_char_range('!', '~');
    std::cout << std::endl;
 
    system("pause");
}
Код
!U3mWNAung1qcQ=")C.0}J,!!DRVYZ
0
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
06.08.2010, 12:18 #6
Цитата Сообщение от nubo
Про нуль-символы впопыхах не подумал.
передаешь char *, и bufsize, который определяет длину пароля

C++
1
2
3
4
5
    do
        int n = rand() % 210 - 32;
    while (!( (n > -32 && n < -15) || (n > 33 && n < 176) ));
 
    return char(n);
1
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 12:23 #7
Цитата Сообщение от accept Посмотреть сообщение
то есть string - это удобно
vector<char>
0
nubo
113 / 70 / 8
Регистрация: 31.07.2010
Сообщений: 334
06.08.2010, 12:23  [ТС] #8
Nameless One,
спасибо за std, теперь ясно. Вот такие моменты в литературе трудно найти.
И за do... while спасибо. Чет я о нем не подумал совсем... В php он очень редко применяется.

fasked,
может стоит подумать по поводу подобных методов генерации?
это было бы слишком просто. Но я хотел качественный мусор, состоящий из наиболее используемых символов. А они находятся в двух диапазонах.

А с типами мне еще долго пырхаться. Изнежела пыха, там все задарма.
0
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 12:30 #9
Цитата Сообщение от accept Посмотреть сообщение
передаешь char *, и bufsize, который определяет длину пароля
C++
1
2
3
4
5
    do
        int n = rand() % 210 - 32;
    while (!( (n > -32 && n < -15) || (n > 33 && n < 176) ));
 
    return char(n);
да, только переменную n надо определить до цикла.
0
nubo
113 / 70 / 8
Регистрация: 31.07.2010
Сообщений: 334
06.08.2010, 12:57  [ТС] #10
Это я понял))) Не суть.

Добавлено через 24 минуты
accept,
передаешь char *, и bufsize, который определяет длину пароля
ничего по этому поводу не могу нарыть.
Можно обнаглеть и попрасить пруф или примерчик?
0
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 13:26 #11
Цитата Сообщение от nubo Посмотреть сообщение
примерчик
ну вот как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cstdlib>
 
char rand_char()
{
    int n = 0;
 
    do
        n = rand() % 210 - 32;
    while (!( (n > -32 && n < -15) || (n > 33 && n < 176) ));
 
    return char(n);
}
 
// передаем указатель на массив и длинну массива
void generate_pass(char * buf, size_t size)
{
    for(int i = 0; i < size; ++i)
        buf[i] = rand_char();
}
 
int main()
{
    const int length = 11;
    char pass[length];
 
    generate_pass(pass, length);
 
    for(int i = 0; i < length; ++i)
        std::cout << pass[i];
    std::cout << std::endl;
 
    system("pause");
}
0
nubo
113 / 70 / 8
Регистрация: 31.07.2010
Сообщений: 334
06.08.2010, 14:07  [ТС] #12
Спасибо.

Какой же я всетки тугодум. Никак не могу уловить простых вещей...
Вот этот пример мне совершенно ясен и понятен. Только он немного не в тему.

Смысл всей этой аферы в том, что мне нужно не просто сгенерировать случайную строку нужной длинны. Мне нужно расставить символы шифруемого пароля на позиции, соответствующие кодам символов основного. А для этого нужно сначала привести его в удобоваримую форму.
1. Заменить первый символ другим, код которого соответствует длине шифруемого.
2. Увеличить его за счет повторений самого себя (конкатенация)
3. Узнать получившуюся длину.
4. В цикле считать посимвольно и определить код каждого символа.
Ну еще там пара моментов.

Так вот что получается. Что бы выполнить пункт 1, предаваемый тип должен быть один. Чтобы 2 - другой. И так далее. Получилось у меня только с типом string.

Вот тут упростил, чтобы было понятнее (работает):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <ctime>
 
using namespace std;
 
int encodePass(string main_pass, string new_pass)
{
 
    int num;
    string code, len_pass;
    size_t max_len, new_len  = new_pass.size(), main_len = main_pass.size();
 
    srand(time(0));
 
 
    if(main_len <= new_len)
    {
        for(int i = main_len - 1; i < new_len; ++i)
            main_pass += main_pass;
 
        max_len = main_pass.size();
    }
    else
        max_len = new_len + 1; 
 
    len_pass = char(new_len + 100);
 
    for(int j = 0; j < max_len; ++j)
    {
        if(j > new_len)
            break;
 
            num = abs((int)main_pass[j]);
 
        for(int i = 0; i < num; ++i)
            code += "-";
 
        if(j == 0)
            code += len_pass;
        else
            code += new_pass[j - 1];
    }
    
    cout << "Результат: " << code << endl;
    return 0;
}
 
 
int main()
{
    setlocale( LC_ALL,"Russian" );
 
    string main_pass, new_pass;
 
                cout << "Введите и запомните основной пароль (минимум 3 символа, максимум 30) ";
                getline(cin, main_pass);
                cout << "Введите пароль, который нужно зашифровать (минимум 3 символа, максимум 30)";
                getline(cin, new_pass);
                        
                encodePass(main_pass, new_pass);
         
  
   return 0;
}
Никак не пойму, какие типы куда приторочить по другому...

Добавлено через 12 минут
с комментариями
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <ctime>
 
using namespace std;
 
int encodePass(string main_pass, string new_pass)
{
 
    int num;
    string code, len_pass;
    size_t max_len, new_len  = new_pass.size(), main_len = main_pass.size();
 
    srand(time(0));
 
 
    if(main_len <= new_len) // если длина основного пароля меньше или равна длине шифруемого
    {
        for(int i = main_len - 1; i < new_len; ++i)// увеличиваю добавляя такой же
            main_pass += main_pass;
 
        max_len = main_pass.size();// узнаю новую длину
    }
    else
        max_len = new_len + 1; 
 
    len_pass = char(new_len + 100); //Символ с кодом, соответствующим длине шифрунмого
 
    for(int j = 0; j < max_len; ++j)
    {
        if(j > new_len) // если шифруемый кончился - выход из цикла
            break;
 
            num = abs((int)main_pass[j]); // получаю код символа
 
        for(int i = 0; i < num; ++i)
            code += "-"; // заполняю строку мусором
 
        if(j == 0)
            code += len_pass; // первый символ для определения длины зашифрованного пароля
        else
            code += new_pass[j - 1]; //вставляю символ шифруемого на свою позицию
    }
    
    cout << "Результат: " << code << endl;
    return 0;
}
 
 
int main()
{
    setlocale( LC_ALL,"Russian" );
 
    string main_pass, new_pass;
 
                cout << "Введите и запомните основной пароль (минимум 3 символа, максимум 30) ";
                getline(cin, main_pass);
                cout << "Введите пароль, который нужно зашифровать (минимум 3 символа, максимум 30)";
                getline(cin, new_pass);
                        
                encodePass(main_pass, new_pass);
         
  
   return 0;
}
0
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 15:03 #13
Цитата Сообщение от nubo Посмотреть сообщение
Что бы выполнить пункт 1, предаваемый тип должен быть один. Чтобы 2 - другой. И так далее. Получилось у меня только с типом string.
я же намекал вам на использование типа std::vector<char> - это динамический массив для хранения символов, в принципе таже строка, если рассматривать его на этом уровне абстракции, только с возможностью хранения непечатаемых символов (то есть вообще всех символов).

посмотрите подобный пример работы с вектором, может он чем-то поможет. здесь выполняются аналогичные действия над строкой и над вектором, результат тоже одинаков:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <iterator>
 
void string_foo(std::string &s)
{
    std::string temporary(s); // временная строка для хранения исходного значения
 
    for(int i = 0; i < temporary.size(); ++i)
        s.append(temporary); // конкатенация строки s со строкой temp
 
    s[0] = '5'; // изменение элемента строки
}
 
void vector_foo(std::vector<char> &v)
{
    std::vector<char> temporary(v); // временный вектор
 
    for(int i = 0; i < temporary.size(); ++i)
        std::copy(temporary.begin(), temporary.end(), std::back_inserter(v)); // конкатенация вектора v с ветором temp
 
    v[0] = '5'; // изменение элемента вектора
}
 
int main()
{
    std::vector<char> v;    // вектор для хранения символов
    std::string str("qwe"); // строка
    
    std::copy(str.begin(), str.end(), std::back_inserter(v)); // копирование строки в вектор
 
    std::cout << str << std::endl; // вывод строки на экран
 
    std::copy(v.begin(), v.end(), std::ostream_iterator<char>(std::cout)); // вывод вектора на экран
    std::cout << std::endl;
 
    string_foo(str); // действия над строкой
    vector_foo(v);   // действия над вектором
 
    std::cout << str << std::endl; // вывод строки на экран
 
    std::copy(v.begin(), v.end(), std::ostream_iterator<char>(std::cout)); // вывод вектора на экран
    std::cout << std::endl;
 
    system("pause");
}
в целом семантика очень похожа.
конечно некоторые операции могу смотреться немного неестественно, но если представлять это как массив, а не строку...
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
06.08.2010, 16:14 #14
nubo, а можешь немного расширить функциональность? Чтобы программа сравнивала не строку со строкой,а вычисляла хеш пароля и сравнивала его с заданным значением? Интересно поглядеть,как всё это дело выглядит в реальной жизни
0
fasked
Эксперт С++
4942 / 2522 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 16:27 #15
Цитата Сообщение от #pragma Посмотреть сообщение
сравнивала его с заданным значением
с каким еще заданным значением?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.08.2010, 16:27
Привет! Вот еще темы с ответами:

XOR Шифратор - C++
Сделал шифратор на основе XOR’а, но если ввести пробел в сообщении которое надо зашифровать, програма во всю отказывается шифровать, то...

Шифратор Дешифратор - C++
Ребят, нужна очень программа которая будет шифровать и дешифровать информацию, слова например. Метод не важен, можно Цезаря например ...

Простой шифратор - C++
Задача такая: пользователь вводит четырехзначное число, после этого программа отображает это число в шифрованном виде. Шифрование...

Шифратор и дешифратор - C++
Помогите пожалуйста написать программу, которая зашифровывает файл и расшифровывает, заранее благодарю!


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
06.08.2010, 16:27
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru