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
| /////////////////////////////////////////////////////////////////////////////////////////
//нужно сделать программу что будет зашифровывать и расшифровывать текст с помощью
//перестановочного шифра.
//
//Буквы открытого текста записываются в клетки прямоугольной таблицы по ее строчкам.
//Буквы ключевого слова пишутся над столбцами и указывают порядок этих столбцов
//(по возрастанию номеров букв в алфавите).
//Чтобы получить зашифрованный текст, надо выписывать буквы по столбцам с учетом их нумерации:
//Открытый текст: прикладная математика
//Ключ: Шифр
//
//Ш и ф р
//4 1 3 2
//П р и к
//л а д н
//а я м а
//т е м а
//т и к а
//
//Криптограмма: раяеикнаааидммкплатт
//
//Ключевое слово(последовательность столбцов) известно адресату, который легко сможет
//расшифровать сообщение.
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cmath>
#include <iostream>
#include <locale>
#include <map>
#include <set>
#include <string>
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string T_str;
typedef std::map<T_str::value_type, T_str> T_key_symb_cols;
typedef std::set<T_str::value_type> T_char_set;
/////////////////////////////////////////////////////////////////////////////////////////
T_str from_DOS(T_str DOS_string)
{
T_str::value_type buf[1000000];
OemToCharA(DOS_string.c_str(), buf);
return buf;
}
/////////////////////////////////////////////////////////////////////////////////////////
T_str remove_spaces(const T_str& s)
{
struct T_is_rus_space
{
bool operator() (T_str::value_type c)
{
return std::isspace(c, std::locale(""));
}
};
T_str s_res;
std::remove_copy_if(s.begin(), s.end(), std::back_inserter(s_res), T_is_rus_space());
return s_res;
}
/////////////////////////////////////////////////////////////////////////////////////////
T_str encode
(
const T_str& sss,
const T_str& key
)
{
T_str s = remove_spaces(sss);
T_key_symb_cols key_symb_cols;
for(T_str::size_type pos = 0; pos < s.length();)
{
for(T_str::const_iterator key_symb_it = key.begin();
key_symb_it != key.end(); ++key_symb_it)
{
key_symb_cols[*key_symb_it] += s[pos++];
if(pos == s.length()) break;
}
}
struct T_get_code_str
{
T_str coded_str_;
//-------------------------------------------------------------------------------
void operator() (const T_key_symb_cols::value_type& key_symb_cols_elem)
{
coded_str_ += key_symb_cols_elem.second;
}
//-------------------------------------------------------------------------------
operator T_str()
{
return coded_str_;
}
};
return std::for_each(key_symb_cols.begin(), key_symb_cols.end(), T_get_code_str());
}
/////////////////////////////////////////////////////////////////////////////////////////
T_str decode
(
T_str coded_s,
const T_str& key
)
{
int col_len = int(ceil(double(coded_s.length()) / key.length()));
int tail_len = coded_s.length() % key.length();
T_str short_cols_symbols;
if(tail_len)
{
short_cols_symbols = key.substr(tail_len);
}
T_char_set short_cols_symbols_set(short_cols_symbols.begin(), short_cols_symbols.end());
T_char_set sort_key(key.begin(), key.end());
T_key_symb_cols key_symb_cols;
for(T_char_set::const_iterator sort_key_symb_it = sort_key.begin();
sort_key_symb_it != sort_key.end(); ++sort_key_symb_it)
{
int symb_col_len = col_len;
if(short_cols_symbols_set.count(*sort_key_symb_it))
{
--symb_col_len;
}
key_symb_cols[*sort_key_symb_it] = coded_s.substr(0, symb_col_len);
coded_s.erase(0, symb_col_len);
}
T_str s_res;
for(;;)
{
for(T_str::const_iterator key_symb_it = key.begin();
key_symb_it != key.end(); ++key_symb_it)
{
if(key_symb_cols[*key_symb_it].empty()) return s_res;
s_res += key_symb_cols[*key_symb_it][0];
key_symb_cols[*key_symb_it].erase(0, 1);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
bool key_is_valid(const T_str& key)
{
T_char_set key_set(key.begin(), key.end());
return key_set.size() == key.size();
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
std::locale::global(std::locale(""));
T_str key;
do
{
std::cout << "Введите ключевое слово без повторяющихся букв: ";
T_str DOS_key;
std::cin >> DOS_key;
key = from_DOS(DOS_key);
}while(!key_is_valid(key));
std::cin.ignore();
for(;;)
{
std::cout << std::endl
<< std::endl
<< std::endl
<< "Введите строку: "
<< std::endl;
T_str DOS_s;
getline(std::cin, DOS_s);
if(DOS_s.empty()) break;
T_str s = from_DOS(DOS_s);
T_str coded_s = encode(s, key);
std::cout << std::endl
<< "Зашифрованная строка: "
<< std::endl
<< coded_s;
T_str decoded_s = decode(coded_s, key);
std::cout << std::endl
<< std::endl
<< "Расшифрованная строка: "
<< std::endl
<< decoded_s
<< std::endl;
}
} |