-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContents.swift
More file actions
98 lines (73 loc) · 2.61 KB
/
Copy pathContents.swift
File metadata and controls
98 lines (73 loc) · 2.61 KB
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
import UIKit
typealias CodeMap = [Character : Character]
class AlphabetCipher {
var key: String
static var matrix = [Character : CodeMap]()
static var alphabet = Array("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
lazy var encryptionMaps : [CodeMap] = {
return pickCodeMaps(key: key)
}()
lazy var decryptionMaps: [CodeMap] = {
return pickCodeMaps(key: key, invert: true)
}()
init(key: String) {
// initialize class property matrix - if not yet done.
if Self.matrix.isEmpty {
for (shift, char) in Self.alphabet.enumerated() {
// create codemap by shifting alphabet
var codemap = [Character : Character]()
for (idx, ch) in Self.alphabet.enumerated() {
codemap[ch] = Self.alphabet[(idx + shift) % Self.alphabet.count]
}
Self.matrix[char] = codemap
}
}
self.key = key
}
func encrypt(_ plaintText: String) -> String {
return substitute(text: plaintText, codeMaps: encryptionMaps)
}
func decrypt(_ cipherText: String) -> String {
return substitute(text: cipherText, codeMaps: decryptionMaps)
}
func substitute(text: String, codeMaps: [CodeMap]) -> String {
var current = 0
let mappedText = text.map { (char) -> Character in
if let ch = codeMaps[current][char] {
current = (current + 1) % codeMaps.count
return ch
}
return char
}
return String(mappedText)
}
func pickCodeMaps(key: String, invert: Bool = false) -> [CodeMap] {
var codeMaps = [CodeMap]()
for ch in key {
if let codeMap = Self.matrix[ch] {
if invert {
codeMaps.append(inverse(codeMap))
} else {
codeMaps.append(codeMap)
}
} else {
assertionFailure("Only ASCII characters supported in encoding key")
}
}
return codeMaps
}
func inverse(_ codeMap: CodeMap) -> CodeMap {
var inverseMap = CodeMap()
for key in codeMap.keys {
if let mappedKey = codeMap[key] {
inverseMap[mappedKey] = key
}
}
return inverseMap
}
}
var cipher = AlphabetCipher(key: "vigilance")
let cipherText = cipher.encrypt("meet me😀 at tuesday evening 🎯at seven")
let plainText = cipher.decrypt(cipherText)
print(cipherText)
print(plainText)