corrade-vassal – Blame information for rev 16

Subversion Repositories:
Rev:
Rev Author Line No. Line
13 eva 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 {
16 eva 15 public static class Cryptography
13 eva 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>
28 public static string ENIGMA(string message, char[] rotors, char[] plugs, char reflector)
29 {
16 eva 30 var def_rotors = new Dictionary<char, char[]>
13 eva 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  
16 eva 144 var def_reflectors = new Dictionary<char, char[]>
13 eva 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.
16 eva 185 foreach (var rotor in rotors)
13 eva 186 {
16 eva 187 var plug = plugs[Array.IndexOf(rotors, rotor)];
188 var i = Array.IndexOf(def_rotors[rotor], plug);
13 eva 189 if (i.Equals(0)) continue;
190 def_rotors[rotor] = Arrays.ConcatenateArrays(new[] {plug},
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));
193 }
194  
16 eva 195 var result = new StringBuilder();
196 foreach (var c in message)
13 eva 197 {
198 if (!char.IsLetter(c))
199 {
200 result.Append(c);
201 continue;
202 }
203  
204 // Normalize to lower.
16 eva 205 var l = char.ToLower(c);
13 eva 206  
207 Action<char[]> rotate = o =>
208 {
16 eva 209 var i = o.Length - 1;
13 eva 210 do
211 {
212 def_rotors[o[0]] = Arrays.ForwardPermuteArrayElements(def_rotors[o[0]], 1);
213 if (i.Equals(0))
214 {
215 rotors = Arrays.ReversePermuteArrayElements(o, 1);
216 continue;
217 }
218 l = Arrays.GetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1);
219 o = Arrays.ReversePermuteArrayElements(o, 1);
220 } while (--i > -1);
221 };
222  
223 // Forward pass through the Enigma's rotors.
224 rotate.Invoke(rotors);
225  
226 // Reflect
16 eva 227 var x = Array.IndexOf(def_reflectors[reflector], l);
13 eva 228 l = (x + 1)%2 == 0 ? def_reflectors[reflector][x - 1] : def_reflectors[reflector][x + 1];
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>
255 public static string VIGENEREExpandKey(string input, string enc_key)
256 {
16 eva 257 var exp_key = string.Empty;
13 eva 258 int i = 0, j = 0;
259 do
260 {
16 eva 261 var p = input[i];
13 eva 262 if (!char.IsLetter(p))
263 {
264 exp_key += p;
265 ++i;
266 continue;
267 }
16 eva 268 var m = j%enc_key.Length;
13 eva 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>
285 public static string EncryptVIGENERE(string input, string enc_key)
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  
293 enc_key = VIGENEREExpandKey(input, enc_key);
16 eva 294 var result = string.Empty;
295 var i = 0;
13 eva 296 do
297 {
16 eva 298 var p = input[i];
13 eva 299 if (!char.IsLetter(p))
300 {
301 result += p;
302 ++i;
303 continue;
304 }
16 eva 305 var q =
13 eva 306 Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i]))[
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>
327 public static string DecryptVIGENERE(string input, string enc_key)
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  
335 enc_key = VIGENEREExpandKey(input, enc_key);
16 eva 336 var result = string.Empty;
337 var i = 0;
13 eva 338 do
339 {
16 eva 340 var p = input[i];
13 eva 341 if (!char.IsLetter(p))
342 {
343 result += p;
344 ++i;
345 continue;
346 }
16 eva 347 var q =
13 eva 348 a[
349 Array.IndexOf(Arrays.ReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i])),
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>
369 public static string ATBASH(string data)
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  
16 eva 377 var input = data.ToCharArray();
13 eva 378  
379 Parallel.ForEach(Enumerable.Range(0, data.Length), i =>
380 {
16 eva 381 var e = input[i];
13 eva 382 if (!char.IsLetter(e)) return;
16 eva 383 var x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e));
13 eva 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 }
395 }