Do the rotors right!
Major thanks to Aimee. ^_^
This commit is contained in:
parent
07073b9dc1
commit
f6f870d7dd
1 changed files with 63 additions and 3 deletions
|
@ -112,6 +112,11 @@ class Rotor: FixedRotor {
|
||||||
case EnigmaM4R2Gamma = "FSOKANUERHMBTIYCWLQPZXVGJD"
|
case EnigmaM4R2Gamma = "FSOKANUERHMBTIYCWLQPZXVGJD"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override init(series: [Character]) throws {
|
||||||
|
try super.init(series: series)
|
||||||
|
rotatedSeries = series
|
||||||
|
}
|
||||||
|
|
||||||
convenience init(_ wiring: Wiring) throws {
|
convenience init(_ wiring: Wiring) throws {
|
||||||
try self.init(series: wiring.rawValue)
|
try self.init(series: wiring.rawValue)
|
||||||
}
|
}
|
||||||
|
@ -128,6 +133,9 @@ class Rotor: FixedRotor {
|
||||||
willSet {
|
willSet {
|
||||||
self.ringPosition = newValue % series.count
|
self.ringPosition = newValue % series.count
|
||||||
}
|
}
|
||||||
|
didSet {
|
||||||
|
rotatedSeries = Array(series[ringPosition..<series.endIndex]) + Array(series[0..<ringPosition])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An offset at which the adjacent rotor should be advanced by one position. */
|
/** An offset at which the adjacent rotor should be advanced by one position. */
|
||||||
|
@ -139,16 +147,68 @@ class Rotor: FixedRotor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var rotatedSeries: [Character]!
|
||||||
|
|
||||||
func advance(count: Int = 1) {
|
func advance(count: Int = 1) {
|
||||||
position = (position + count) % Rotor.alphabet.count
|
position = (position + count) % series.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIndexAdjustedForRotation(c: Character) throws -> Int {
|
||||||
|
let entryPosition = try indexOfInAlphabet(c)
|
||||||
|
let adjustedPosition = (entryPosition + position) % Cryptor.alphabet.count
|
||||||
|
return adjustedPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInverseIndexAdjustedForRotation(c: Character) throws -> Int {
|
||||||
|
let entryPosition = try indexOfInAlphabet(c)
|
||||||
|
let adjustedPosition = (entryPosition + position) % Cryptor.alphabet.count
|
||||||
|
let adjustedChar = Cryptor.alphabet[adjustedPosition]
|
||||||
|
let inversePosition = try indexOfInSeries(adjustedChar)
|
||||||
|
return inversePosition
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToExitCharacter(c: Character) throws -> Character {
|
||||||
|
let encodedPosition = try indexOfInAlphabet(c)
|
||||||
|
var adjustedPosition = (encodedPosition - position) % Cryptor.alphabet.count
|
||||||
|
if adjustedPosition < 0 {
|
||||||
|
adjustedPosition += Cryptor.alphabet.count
|
||||||
|
}
|
||||||
|
return Cryptor.alphabet[adjustedPosition]
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToInverseExitCharacter(c: Character) throws -> Character {
|
||||||
|
let encodedPosition = try indexOfInAlphabet(c)
|
||||||
|
var adjustedPosition = (encodedPosition - position) % Cryptor.alphabet.count
|
||||||
|
if adjustedPosition < 0 {
|
||||||
|
adjustedPosition += Cryptor.alphabet.count
|
||||||
|
}
|
||||||
|
return Cryptor.alphabet[adjustedPosition]
|
||||||
}
|
}
|
||||||
|
|
||||||
override func encode(c: Character) throws -> Character {
|
override func encode(c: Character) throws -> Character {
|
||||||
return series[(try indexOfInAlphabet(c) + ringPosition + position) % series.count]
|
let adjustedPosition = try getIndexAdjustedForRotation(c)
|
||||||
|
let encodedChar = rotatedSeries[adjustedPosition]
|
||||||
|
let finalChar = try convertToExitCharacter(encodedChar)
|
||||||
|
print("Encode (pos \(position): \(c) -> \(finalChar)")
|
||||||
|
return finalChar
|
||||||
}
|
}
|
||||||
|
|
||||||
override func inverseEncode(c: Character) throws -> Character {
|
override func inverseEncode(c: Character) throws -> Character {
|
||||||
return Cryptor.alphabet[(try indexOfInSeries(c) + ringPosition + position) % Rotor.alphabet.count]
|
let adjustedPosition = try getInverseIndexAdjustedForRotation(c)
|
||||||
|
let adjustedChar = rotatedSeries[adjustedPosition]
|
||||||
|
let lookMeUp = try indexOfInSeries(adjustedChar)
|
||||||
|
let decodedChar = Cryptor.alphabet[lookMeUp]
|
||||||
|
let finalChar = try convertToInverseExitCharacter(decodedChar)
|
||||||
|
print("Encode (pos \(position): \(c) -> \(finalChar)")
|
||||||
|
return finalChar
|
||||||
|
}
|
||||||
|
|
||||||
|
override func indexOfInSeries(c: Character) throws -> Int {
|
||||||
|
if let index = rotatedSeries.indexOf(c) {
|
||||||
|
return index
|
||||||
|
} else {
|
||||||
|
throw EncoderError.CharacterNotInSeries(ch: c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue