_rotor=$rotor; } public function setRotorOffset ($offset) { if(preg_match('/^[A-Z]$/',$offset)) { $offset=$this->_charToAlphabetPosition($offset); } else if(!is_integer($offset) || ($offset<1) || ($offset>26)) { throw new Exception("Offset must be integer in range 1..26"); } $this->_rotorOffset = $offset; } public function getOutputCharacterForInputCharacter ($inputCharacter) { $inputCharacter = strtoupper($inputCharacter); $rotorInputCharacter = $this->_getCharacterOffsetBy($inputCharacter, $this->_rotorOffset-1); $rotorOutputCharacter = $this->_rotor->getOutputCharacterForInputCharacter( $rotorInputCharacter ); $outputCharacter = $this->_getCharacterOffsetBy( $rotorOutputCharacter, 0 - ($this->_rotorOffset - 1) ); return ($outputCharacter); } public function getOutputCharacterForInputCharacterReverse ($inputCharacter) { $inputCharacter = strtoupper($inputCharacter); $rotorInputCharacter = $this->_getCharacterOffsetBy($inputCharacter, $this->_rotorOffset-1); $rotorOutputCharacter = $this->_rotor->getOutputCharacterForInputCharacterReverse( $rotorInputCharacter ); $outputCharacter = $this->_getCharacterOffsetBy( $rotorOutputCharacter, 0 - ($this->_rotorOffset -1) ); return ($outputCharacter); } private function _getCharacterOffsetBy ($character, $offset) { if(!is_numeric($offset)) { throw new Exception('Character offsets must be numeric'); } $offset=(26+$offset)%26; $charAsInt = $this->_charToAlphabetPosition($character); $newInteger = (26 + $charAsInt + $offset) % 26; if($newInteger==0) { $newInteger=26; } $newCharacter = $this->_alphabetPositionToCharacter($newInteger); return ($newCharacter); } private function _charToAlphabetPosition ($char) { if(!preg_match('/^[A-Z]$/',$char)) { throw new Exception ("Bad Character '$char'"); } $position= (ord($char)-64); return $position; } private function _alphabetPositionToCharacter ($position) { if(($position<1) || ($position>26)){ throw new Exception ("Bad alphaoffset '$position'"); } $char= (chr($position+64)); return $char; } public function getRotorOffset() { return($this->_rotorOffset); } public function getRotorOffsetAsCharacter () { return $this->_alphabetPositionToCharacter($this->getRotorOffset()); } public function incrementRotorOffset() { $this->_rotorOffset++; if($this->_rotorOffset>26) { $this->_rotorOffset=1; } //If we're in turnover position, notify the next slot if($this->turnoverDue()) { $this->notifyTurnoverObserver(); } } public function turnoverDue() { return($this->_rotor->hasPegAtPosition($this->getRotorOffsetAsCharacter())); } public function registerTurnoverObserver(Enigma_RotorSlot $observer) { $this->_turnoverObserver=$observer; } public function notifyTurnoverObserver() { if($this->_turnoverObserver) { $this->_turnoverObserver->incrementRotorOffset(); } } }