wasSharp – Blame information for rev 1
?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 | { |
||
15 | public class Cryptography |
||
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 wasEnigma(string message, char[] rotors, char[] plugs, char reflector) |
||
29 | { |
||
30 | Dictionary<char, char[]> def_rotors = new Dictionary<char, char[]> |
||
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 | |||
144 | Dictionary<char, char[]> def_reflectors = new Dictionary<char, char[]> |
||
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. |
||
185 | foreach (char rotor in rotors) |
||
186 | { |
||
187 | char plug = plugs[Array.IndexOf(rotors, rotor)]; |
||
188 | int i = Array.IndexOf(def_rotors[rotor], plug); |
||
189 | if (i.Equals(0)) continue; |
||
190 | def_rotors[rotor] = Arrays.wasConcatenateArrays(new[] {plug}, |
||
191 | Arrays.wasGetSubArray(Arrays.wasDeleteSubArray(def_rotors[rotor], i, i), i, -1), |
||
192 | Arrays.wasGetSubArray(Arrays.wasDeleteSubArray(def_rotors[rotor], i + 1, -1), 0, i - 1)); |
||
193 | } |
||
194 | |||
195 | StringBuilder result = new StringBuilder(); |
||
196 | foreach (char c in message) |
||
197 | { |
||
198 | if (!char.IsLetter(c)) |
||
199 | { |
||
200 | result.Append(c); |
||
201 | continue; |
||
202 | } |
||
203 | |||
204 | // Normalize to lower. |
||
205 | char l = char.ToLower(c); |
||
206 | |||
207 | Action<char[]> rotate = o => |
||
208 | { |
||
209 | int i = o.Length - 1; |
||
210 | do |
||
211 | { |
||
212 | def_rotors[o[0]] = Arrays.wasForwardPermuteArrayElements(def_rotors[o[0]], 1); |
||
213 | if (i.Equals(0)) |
||
214 | { |
||
215 | rotors = Arrays.wasReversePermuteArrayElements(o, 1); |
||
216 | continue; |
||
217 | } |
||
218 | l = Arrays.wasGetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1); |
||
219 | o = Arrays.wasReversePermuteArrayElements(o, 1); |
||
220 | } while (--i > -1); |
||
221 | }; |
||
222 | |||
223 | // Forward pass through the Enigma's rotors. |
||
224 | rotate.Invoke(rotors); |
||
225 | |||
226 | // Reflect |
||
227 | int x = Array.IndexOf(def_reflectors[reflector], l); |
||
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 wasVigenereExpandKey(string input, string enc_key) |
||
256 | { |
||
257 | string exp_key = string.Empty; |
||
258 | int i = 0, j = 0; |
||
259 | do |
||
260 | { |
||
261 | char p = input[i]; |
||
262 | if (!char.IsLetter(p)) |
||
263 | { |
||
264 | exp_key += p; |
||
265 | ++i; |
||
266 | continue; |
||
267 | } |
||
268 | int m = j%enc_key.Length; |
||
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 wasEncryptVIGENERE(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 = wasVigenereExpandKey(input, enc_key); |
||
294 | string result = string.Empty; |
||
295 | int i = 0; |
||
296 | do |
||
297 | { |
||
298 | char p = input[i]; |
||
299 | if (!char.IsLetter(p)) |
||
300 | { |
||
301 | result += p; |
||
302 | ++i; |
||
303 | continue; |
||
304 | } |
||
305 | char q = |
||
306 | Arrays.wasReversePermuteArrayElements(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 wasDecryptVIGENERE(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 = wasVigenereExpandKey(input, enc_key); |
||
336 | string result = string.Empty; |
||
337 | int i = 0; |
||
338 | do |
||
339 | { |
||
340 | char p = input[i]; |
||
341 | if (!char.IsLetter(p)) |
||
342 | { |
||
343 | result += p; |
||
344 | ++i; |
||
345 | continue; |
||
346 | } |
||
347 | char q = |
||
348 | a[ |
||
349 | Array.IndexOf(Arrays.wasReversePermuteArrayElements(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 wasATBASH(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 | |||
377 | char[] input = data.ToCharArray(); |
||
378 | |||
379 | Parallel.ForEach(Enumerable.Range(0, data.Length), i => |
||
380 | { |
||
381 | char e = input[i]; |
||
382 | if (!char.IsLetter(e)) return; |
||
383 | int x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e)); |
||
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 | } |