wasSharp – Blame information for rev 33
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | zed | 1 | /////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
||
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
||
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
||
5 | /////////////////////////////////////////////////////////////////////////// |
||
6 | |||
7 | using System; |
||
8 | using System.Collections.Generic; |
||
9 | using System.Linq; |
||
10 | using System.Text; |
||
11 | using System.Threading.Tasks; |
||
12 | |||
13 | namespace wasSharp |
||
14 | { |
||
7 | office | 15 | public static class Cryptography |
1 | zed | 16 | { |
17 | /////////////////////////////////////////////////////////////////////////// |
||
18 | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
||
19 | /////////////////////////////////////////////////////////////////////////// |
||
20 | /// <summary> |
||
21 | /// Encrypt or decrypt a message given a set of rotors, plugs and a reflector. |
||
22 | /// </summary> |
||
23 | /// <param name="message">the message to encyrpt or decrypt</param> |
||
24 | /// <param name="rotors">any combination of: 1, 2, 3, 4, 5, 6, 7, 8, b, g</param> |
||
25 | /// <param name="plugs">the letter representing the start character for the rotor</param> |
||
26 | /// <param name="reflector">any one of: B, b, C, c</param> |
||
27 | /// <returns>either a decrypted or encrypted string</returns> |
||
5 | eva | 28 | public static string ENIGMA(string message, char[] rotors, char[] plugs, char reflector) |
1 | zed | 29 | { |
7 | office | 30 | var def_rotors = new Dictionary<char, char[]> |
1 | zed | 31 | { |
32 | { |
||
33 | '1', new[] |
||
34 | { |
||
35 | 'e', 'k', 'm', 'f', 'l', |
||
36 | 'g', 'd', 'q', 'v', 'z', |
||
37 | 'n', 't', 'o', 'w', 'y', |
||
38 | 'h', 'x', 'u', 's', 'p', |
||
39 | 'a', 'i', 'b', 'r', 'c', |
||
40 | 'j' |
||
41 | } |
||
42 | }, |
||
43 | { |
||
44 | '2', new[] |
||
45 | { |
||
46 | 'a', 'j', 'd', 'k', 's', |
||
47 | 'i', 'r', 'u', 'x', 'b', |
||
48 | 'l', 'h', 'w', 't', 'm', |
||
49 | 'c', 'q', 'g', 'z', 'n', |
||
50 | 'p', 'y', 'f', 'v', 'o', |
||
51 | 'e' |
||
52 | } |
||
53 | }, |
||
54 | { |
||
55 | '3', new[] |
||
56 | { |
||
57 | 'b', 'd', 'f', 'h', 'j', |
||
58 | 'l', 'c', 'p', 'r', 't', |
||
59 | 'x', 'v', 'z', 'n', 'y', |
||
60 | 'e', 'i', 'w', 'g', 'a', |
||
61 | 'k', 'm', 'u', 's', 'q', |
||
62 | 'o' |
||
63 | } |
||
64 | }, |
||
65 | { |
||
66 | '4', new[] |
||
67 | { |
||
68 | 'e', 's', 'o', 'v', 'p', |
||
69 | 'z', 'j', 'a', 'y', 'q', |
||
70 | 'u', 'i', 'r', 'h', 'x', |
||
71 | 'l', 'n', 'f', 't', 'g', |
||
72 | 'k', 'd', 'c', 'm', 'w', |
||
73 | 'b' |
||
74 | } |
||
75 | }, |
||
76 | { |
||
77 | '5', new[] |
||
78 | { |
||
79 | 'v', 'z', 'b', 'r', 'g', |
||
80 | 'i', 't', 'y', 'u', 'p', |
||
81 | 's', 'd', 'n', 'h', 'l', |
||
82 | 'x', 'a', 'w', 'm', 'j', |
||
83 | 'q', 'o', 'f', 'e', 'c', |
||
84 | 'k' |
||
85 | } |
||
86 | }, |
||
87 | { |
||
88 | '6', new[] |
||
89 | { |
||
90 | 'j', 'p', 'g', 'v', 'o', |
||
91 | 'u', 'm', 'f', 'y', 'q', |
||
92 | 'b', 'e', 'n', 'h', 'z', |
||
93 | 'r', 'd', 'k', 'a', 's', |
||
94 | 'x', 'l', 'i', 'c', 't', |
||
95 | 'w' |
||
96 | } |
||
97 | }, |
||
98 | { |
||
99 | '7', new[] |
||
100 | { |
||
101 | 'n', 'z', 'j', 'h', 'g', |
||
102 | 'r', 'c', 'x', 'm', 'y', |
||
103 | 's', 'w', 'b', 'o', 'u', |
||
104 | 'f', 'a', 'i', 'v', 'l', |
||
105 | 'p', 'e', 'k', 'q', 'd', |
||
106 | 't' |
||
107 | } |
||
108 | }, |
||
109 | { |
||
110 | '8', new[] |
||
111 | { |
||
112 | 'f', 'k', 'q', 'h', 't', |
||
113 | 'l', 'x', 'o', 'c', 'b', |
||
114 | 'j', 's', 'p', 'd', 'z', |
||
115 | 'r', 'a', 'm', 'e', 'w', |
||
116 | 'n', 'i', 'u', 'y', 'g', |
||
117 | 'v' |
||
118 | } |
||
119 | }, |
||
120 | { |
||
121 | 'b', new[] |
||
122 | { |
||
123 | 'l', 'e', 'y', 'j', 'v', |
||
124 | 'c', 'n', 'i', 'x', 'w', |
||
125 | 'p', 'b', 'q', 'm', 'd', |
||
126 | 'r', 't', 'a', 'k', 'z', |
||
127 | 'g', 'f', 'u', 'h', 'o', |
||
128 | 's' |
||
129 | } |
||
130 | }, |
||
131 | { |
||
132 | 'g', new[] |
||
133 | { |
||
134 | 'f', 's', 'o', 'k', 'a', |
||
135 | 'n', 'u', 'e', 'r', 'h', |
||
136 | 'm', 'b', 't', 'i', 'y', |
||
137 | 'c', 'w', 'l', 'q', 'p', |
||
138 | 'z', 'x', 'v', 'g', 'j', |
||
139 | 'd' |
||
140 | } |
||
141 | } |
||
142 | }; |
||
143 | |||
7 | office | 144 | var def_reflectors = new Dictionary<char, char[]> |
1 | zed | 145 | { |
146 | { |
||
147 | 'B', new[] |
||
148 | { |
||
149 | 'a', 'y', 'b', 'r', 'c', 'u', 'd', 'h', |
||
150 | 'e', 'q', 'f', 's', 'g', 'l', 'i', 'p', |
||
151 | 'j', 'x', 'k', 'n', 'm', 'o', 't', 'z', |
||
152 | 'v', 'w' |
||
153 | } |
||
154 | }, |
||
155 | { |
||
156 | 'b', new[] |
||
157 | { |
||
158 | 'a', 'e', 'b', 'n', 'c', 'k', 'd', 'q', |
||
159 | 'f', 'u', 'g', 'y', 'h', 'w', 'i', 'j', |
||
160 | 'l', 'o', 'm', 'p', 'r', 'x', 's', 'z', |
||
161 | 't', 'v' |
||
162 | } |
||
163 | }, |
||
164 | { |
||
165 | 'C', new[] |
||
166 | { |
||
167 | 'a', 'f', 'b', 'v', 'c', 'p', 'd', 'j', |
||
168 | 'e', 'i', 'g', 'o', 'h', 'y', 'k', 'r', |
||
169 | 'l', 'z', 'm', 'x', 'n', 'w', 't', 'q', |
||
170 | 's', 'u' |
||
171 | } |
||
172 | }, |
||
173 | { |
||
174 | 'c', new[] |
||
175 | { |
||
176 | 'a', 'r', 'b', 'd', 'c', 'o', 'e', 'j', |
||
177 | 'f', 'n', 'g', 't', 'h', 'k', 'i', 'v', |
||
178 | 'l', 'm', 'p', 'w', 'q', 'z', 's', 'x', |
||
179 | 'u', 'y' |
||
180 | } |
||
181 | } |
||
182 | }; |
||
183 | |||
184 | // Setup rotors from plugs. |
||
7 | office | 185 | foreach (var rotor in rotors) |
1 | zed | 186 | { |
7 | office | 187 | var plug = plugs[Array.IndexOf(rotors, rotor)]; |
188 | var i = Array.IndexOf(def_rotors[rotor], plug); |
||
1 | zed | 189 | if (i.Equals(0)) continue; |
27 | office | 190 | def_rotors[rotor] = Arrays.ConcatenateArrays(new[] { plug }, |
5 | eva | 191 | Arrays.GetSubArray(Arrays.DeleteSubArray(def_rotors[rotor], i, i), i, -1), |
192 | Arrays.GetSubArray(Arrays.DeleteSubArray(def_rotors[rotor], i + 1, -1), 0, i - 1)); |
||
1 | zed | 193 | } |
194 | |||
7 | office | 195 | var result = new StringBuilder(); |
196 | foreach (var c in message) |
||
1 | zed | 197 | { |
198 | if (!char.IsLetter(c)) |
||
199 | { |
||
200 | result.Append(c); |
||
201 | continue; |
||
202 | } |
||
203 | |||
204 | // Normalize to lower. |
||
7 | office | 205 | var l = char.ToLower(c); |
1 | zed | 206 | |
207 | Action<char[]> rotate = o => |
||
208 | { |
||
7 | office | 209 | var i = o.Length - 1; |
1 | zed | 210 | do |
211 | { |
||
5 | eva | 212 | def_rotors[o[0]] = Arrays.ForwardPermuteArrayElements(def_rotors[o[0]], 1); |
1 | zed | 213 | if (i.Equals(0)) |
214 | { |
||
5 | eva | 215 | rotors = Arrays.ReversePermuteArrayElements(o, 1); |
1 | zed | 216 | continue; |
217 | } |
||
5 | eva | 218 | l = Arrays.GetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1); |
219 | o = Arrays.ReversePermuteArrayElements(o, 1); |
||
1 | zed | 220 | } while (--i > -1); |
221 | }; |
||
222 | |||
223 | // Forward pass through the Enigma's rotors. |
||
224 | rotate.Invoke(rotors); |
||
225 | |||
226 | // Reflect |
||
7 | office | 227 | var x = Array.IndexOf(def_reflectors[reflector], l); |
27 | office | 228 | l = (x + 1) % 2 == 0 ? def_reflectors[reflector][x - 1] : def_reflectors[reflector][x + 1]; |
1 | zed | 229 | |
230 | // Reverse the order of the rotors. |
||
231 | Array.Reverse(rotors); |
||
232 | |||
233 | // Reverse pass through the Enigma's rotors. |
||
234 | rotate.Invoke(rotors); |
||
235 | |||
236 | if (char.IsUpper(c)) |
||
237 | { |
||
238 | l = char.ToUpper(l); |
||
239 | } |
||
240 | result.Append(l); |
||
241 | } |
||
242 | |||
243 | return result.ToString(); |
||
244 | } |
||
245 | |||
246 | /////////////////////////////////////////////////////////////////////////// |
||
247 | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
||
248 | /////////////////////////////////////////////////////////////////////////// |
||
249 | /// <summary> |
||
250 | /// Expand the VIGENRE key to the length of the input. |
||
251 | /// </summary> |
||
252 | /// <param name="input">the input to expand to</param> |
||
253 | /// <param name="enc_key">the key to expand</param> |
||
254 | /// <returns>the expanded key</returns> |
||
5 | eva | 255 | public static string VIGENEREExpandKey(string input, string enc_key) |
1 | zed | 256 | { |
7 | office | 257 | var exp_key = string.Empty; |
1 | zed | 258 | int i = 0, j = 0; |
259 | do |
||
260 | { |
||
7 | office | 261 | var p = input[i]; |
1 | zed | 262 | if (!char.IsLetter(p)) |
263 | { |
||
264 | exp_key += p; |
||
265 | ++i; |
||
266 | continue; |
||
267 | } |
||
27 | office | 268 | var m = j % enc_key.Length; |
1 | zed | 269 | exp_key += enc_key[m]; |
270 | ++j; |
||
271 | ++i; |
||
272 | } while (i < input.Length); |
||
273 | return exp_key; |
||
274 | } |
||
275 | |||
276 | /////////////////////////////////////////////////////////////////////////// |
||
277 | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
||
278 | /////////////////////////////////////////////////////////////////////////// |
||
279 | /// <summary> |
||
280 | /// Encrypt using VIGENERE. |
||
281 | /// </summary> |
||
282 | /// <param name="input">the input to encrypt</param> |
||
283 | /// <param name="enc_key">the key to encrypt with</param> |
||
284 | /// <returns>the encrypted input</returns> |
||
5 | eva | 285 | public static string EncryptVIGENERE(string input, string enc_key) |
1 | zed | 286 | { |
287 | char[] a = |
||
288 | { |
||
289 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
||
290 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
||
291 | }; |
||
292 | |||
5 | eva | 293 | enc_key = VIGENEREExpandKey(input, enc_key); |
7 | office | 294 | var result = string.Empty; |
295 | var i = 0; |
||
1 | zed | 296 | do |
297 | { |
||
7 | office | 298 | var p = input[i]; |
1 | zed | 299 | if (!char.IsLetter(p)) |
300 | { |
||
301 | result += p; |
||
302 | ++i; |
||
303 | continue; |
||
304 | } |
||
7 | office | 305 | var q = |
5 | eva | 306 | Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i]))[ |
1 | zed | 307 | Array.IndexOf(a, char.ToLowerInvariant(p))]; |
308 | if (char.IsUpper(p)) |
||
309 | { |
||
310 | q = char.ToUpperInvariant(q); |
||
311 | } |
||
312 | result += q; |
||
313 | ++i; |
||
314 | } while (i < input.Length); |
||
315 | return result; |
||
316 | } |
||
317 | |||
318 | /////////////////////////////////////////////////////////////////////////// |
||
319 | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
||
320 | /////////////////////////////////////////////////////////////////////////// |
||
321 | /// <summary> |
||
322 | /// Decrypt using VIGENERE. |
||
323 | /// </summary> |
||
324 | /// <param name="input">the input to decrypt</param> |
||
325 | /// <param name="enc_key">the key to decrypt with</param> |
||
326 | /// <returns>the decrypted input</returns> |
||
5 | eva | 327 | public static string DecryptVIGENERE(string input, string enc_key) |
1 | zed | 328 | { |
329 | char[] a = |
||
330 | { |
||
331 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
||
332 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
||
333 | }; |
||
334 | |||
5 | eva | 335 | enc_key = VIGENEREExpandKey(input, enc_key); |
7 | office | 336 | var result = string.Empty; |
337 | var i = 0; |
||
1 | zed | 338 | do |
339 | { |
||
7 | office | 340 | var p = input[i]; |
1 | zed | 341 | if (!char.IsLetter(p)) |
342 | { |
||
343 | result += p; |
||
344 | ++i; |
||
345 | continue; |
||
346 | } |
||
7 | office | 347 | var q = |
1 | zed | 348 | a[ |
5 | eva | 349 | Array.IndexOf(Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i])), |
1 | zed | 350 | char.ToLowerInvariant(p))]; |
351 | if (char.IsUpper(p)) |
||
352 | { |
||
353 | q = char.ToUpperInvariant(q); |
||
354 | } |
||
355 | result += q; |
||
356 | ++i; |
||
357 | } while (i < input.Length); |
||
358 | return result; |
||
359 | } |
||
360 | |||
361 | /////////////////////////////////////////////////////////////////////////// |
||
362 | // Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 // |
||
363 | /////////////////////////////////////////////////////////////////////////// |
||
364 | /// <summary> |
||
365 | /// An implementation of the ATBASH cypher for latin alphabets. |
||
366 | /// </summary> |
||
367 | /// <param name="data">the data to encrypt or decrypt</param> |
||
368 | /// <returns>the encrypted or decrypted data</returns> |
||
5 | eva | 369 | public static string ATBASH(string data) |
1 | zed | 370 | { |
371 | char[] a = |
||
372 | { |
||
373 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
||
374 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
||
375 | }; |
||
376 | |||
7 | office | 377 | var input = data.ToCharArray(); |
1 | zed | 378 | |
379 | Parallel.ForEach(Enumerable.Range(0, data.Length), i => |
||
380 | { |
||
7 | office | 381 | var e = input[i]; |
1 | zed | 382 | if (!char.IsLetter(e)) return; |
7 | office | 383 | var x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e)); |
1 | zed | 384 | if (!char.IsUpper(e)) |
385 | { |
||
386 | input[i] = a[x]; |
||
387 | return; |
||
388 | } |
||
389 | input[i] = char.ToUpperInvariant(a[x]); |
||
390 | }); |
||
391 | |||
392 | return new string(input); |
||
393 | } |
||
394 | } |
||
27 | office | 395 | } |