wasSharp – Blame information for rev 27

Subversion Repositories:
Rev:
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 }