Completed
Push — development ( 1fb984...7ea9e3 )
by Nils
08:29
created

HybridPasswordGenerator   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 178
rs 10
c 0
b 0
f 0
wmc 19
lcom 2
cbo 2

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A getCharacterList() 0 7 1
A generatePassword() 0 21 4
A getLength() 0 4 1
A setLength() 0 6 1
A getSegmentCount() 0 4 1
A setSegmentCount() 0 10 3
A getSegmentLength() 0 4 1
A setSegmentLength() 0 10 3
A getSegmentSeparator() 0 4 1
A setSegmentSeparator() 0 10 2
1
<?php
2
3
namespace PasswordGenerator\Generator;
4
5
use PasswordGenerator\Model\CharacterSet;
6
use PasswordGenerator\Model\Option\Option;
7
8
require_once(dirname(__FILE__).'/../Model/Option/Option.php');
9
10
class HybridPasswordGenerator extends ComputerPasswordGenerator
11
{
12
    const OPTION_SEGMENT_COUNT = 'SEGMENT_COUNT';
13
    const OPTION_SEGMENT_LENGTH = 'SEGMENT_LENGTH';
14
15
    const PARAMETER_SEPARATOR = 'SEPARATOR';
16
17
    public function __construct()
18
    {
19
        parent::__construct();
20
21
        $this
22
            ->removeOption(self::OPTION_LENGTH)
23
            ->setOption(self::OPTION_SEGMENT_COUNT, array('type' => Option::TYPE_INTEGER, 'default' => 4))
24
            ->setOption(self::OPTION_SEGMENT_LENGTH, array('type' => Option::TYPE_INTEGER, 'default' => 3))
25
            ->setParameter(self::PARAMETER_SEPARATOR, '-')
26
        ;
27
    }
28
29
    /**
30
     * Generate character list for us in generating passwords
31
     * and remove segment separator from character list pool.
32
     *
33
     * @return CharacterSet Character list
34
     *
35
     * @throws \Exception
36
     */
37
    public function getCharacterList()
38
    {
39
        $characterList = parent::getCharacterList();
40
        $characterList = \str_replace($this->getSegmentSeparator(), '', $characterList);
41
42
        return new CharacterSet($characterList);
43
    }
44
45
    /**
46
     * Generate one password based on options.
47
     *
48
     * @return string password
49
     */
50
    public function generatePassword()
51
    {
52
        $characterList = $this->getCharacterList()->getCharacters();
53
        $characters = \strlen($characterList);
54
        $password = '';
55
56
        $segmentCount = $this->getSegmentCount();
57
        $segmentLength = $this->getSegmentLength();
58
59
        for ($i = 0; $i < $segmentCount; ++$i) {
60
            if ($password) {
61
                $password .= $this->getSegmentSeparator();
62
            }
63
64
            for ($j = 0; $j < $segmentLength; ++$j) {
65
                $password .= $characterList[$this->randomInteger(0, $characters - 1)];
66
            }
67
        }
68
69
        return $password;
70
    }
71
72
    /**
73
     * Get number of words in desired password.
74
     *
75
     * @return int
76
     */
77
    public function getLength()
78
    {
79
        return $this->getSegmentCount();
80
    }
81
82
    /**
83
     * Set length of desired password(s).
84
     *
85
     * @param int $characterCount
86
     *
87
     * @return $this
88
     *
89
     * @throws \InvalidArgumentException
90
     */
91
    public function setLength($characterCount)
92
    {
93
        $this->setSegmentCount($characterCount);
94
95
        return $this;
96
    }
97
98
    /**
99
     * Get number of segments in desired password.
100
     *
101
     * @return int
102
     */
103
    public function getSegmentCount()
104
    {
105
        return $this->getOptionValue(self::OPTION_SEGMENT_COUNT);
106
    }
107
108
    /**
109
     * Set number of segments in desired password(s).
110
     *
111
     * @param int $segmentCount
112
     *
113
     * @return $this
114
     *
115
     * @throws \InvalidArgumentException
116
     */
117
    public function setSegmentCount($segmentCount)
118
    {
119
        if (!is_int($segmentCount) || $segmentCount < 1) {
120
            throw new \InvalidArgumentException('Expected positive integer');
121
        }
122
123
        $this->setOptionValue(self::OPTION_SEGMENT_COUNT, $segmentCount);
124
125
        return $this;
126
    }
127
128
    /**
129
     * Get number of segments in desired password.
130
     *
131
     * @return int
132
     */
133
    public function getSegmentLength()
134
    {
135
        return $this->getOptionValue(self::OPTION_SEGMENT_LENGTH);
136
    }
137
138
    /**
139
     * Set length of segment.
140
     *
141
     * @param int $segmentLength
142
     *
143
     * @return $this
144
     *
145
     * @throws \InvalidArgumentException
146
     */
147
    public function setSegmentLength($segmentLength)
148
    {
149
        if (!is_int($segmentLength) || $segmentLength < 1) {
150
            throw new \InvalidArgumentException('Expected positive integer');
151
        }
152
153
        $this->setOptionValue(self::OPTION_SEGMENT_LENGTH, $segmentLength);
154
155
        return $this;
156
    }
157
158
    /**
159
     * Get Segment Separator.
160
     *
161
     * @return string
162
     */
163
    public function getSegmentSeparator()
164
    {
165
        return $this->getParameter(self::PARAMETER_SEPARATOR);
166
    }
167
168
    /**
169
     * Set segment separator.
170
     *
171
     * @param string $segmentSeparator
172
     *
173
     * @return \Hackzilla\PasswordGenerator\Generator\HybridPasswordGenerator
174
     *
175
     * @throws \InvalidArgumentException
176
     */
177
    public function setSegmentSeparator($segmentSeparator)
178
    {
179
        if (!is_string($segmentSeparator)) {
180
            throw new \InvalidArgumentException('Expected string');
181
        }
182
183
        $this->setParameter(self::PARAMETER_SEPARATOR, $segmentSeparator);
184
185
        return $this;
186
    }
187
}
188