3 * An abstract mixer to implement a common mixing strategy
7 * @category PHPCryptLib
9 * @author Anthony Ferrara <ircmaxell@ircmaxell.com>
10 * @copyright 2011 The Authors
11 * @license http://www.opensource.org/licenses/mit-license.html MIT License
12 * @version Build @@version@@
15 namespace CryptLib\Random
;
18 * An abstract mixer to implement a common mixing strategy
20 * @see http://tools.ietf.org/html/rfc4086#section-5.2
21 * @category PHPCryptLib
23 * @author Anthony Ferrara <ircmaxell@ircmaxell.com>
25 abstract class AbstractMixer
implements \CryptLib\Random\Mixer
{
28 * Get the block size (the size of the individual blocks used for the mixing)
30 * @return int The block size
32 abstract protected function getPartSize();
35 * Mix 2 parts together using one method
37 * @param string $part1 The first part to mix
38 * @param string $part2 The second part to mix
40 * @return string The mixed data
42 abstract protected function mixParts1($part1, $part2);
45 * Mix 2 parts together using another different method
47 * @param string $part1 The first part to mix
48 * @param string $part2 The second part to mix
50 * @return string The mixed data
52 abstract protected function mixParts2($part1, $part2);
55 * Mix the provided array of strings into a single output of the same size
57 * All elements of the array should be the same size.
59 * @param array $parts The parts to be mixed
61 * @return string The mixed result
63 public function mix(array $parts) {
67 $len = strlen($parts[0]);
68 $parts = $this->normalizeParts($parts);
69 $stringSize = count($parts[0]);
70 $partsSize = count($parts);
73 for ($i = 0; $i < $stringSize; $i++
) {
74 $stub = $parts[$offset][$i];
75 for ($j = 1; $j < $partsSize; $j++
) {
76 $newKey = $parts[($j +
$offset) %
$partsSize][$i];
77 //Alternately mix the output for each source
79 $stub ^
= $this->mixParts1($stub, $newKey);
81 $stub ^
= $this->mixParts2($stub, $newKey);
85 $offset = ($offset +
1) %
$partsSize;
87 return substr($result, 0, $len);
91 * Normalize the part array and split it block part size.
93 * This will make all parts the same length and a multiple
96 * @param array $parts The parts to normalize
98 * @return array The normalized and split parts
100 protected function normalizeParts(array $parts) {
101 $blockSize = $this->getPartSize();
102 $callback = function($value) {
103 return strlen($value);
105 $maxSize = max(array_map($callback, $parts));
106 if ($maxSize %
$blockSize != 0) {
107 $maxSize +
= $blockSize - ($maxSize %
$blockSize);
109 foreach ($parts as &$part) {
110 $part = str_pad($part, $maxSize, chr(0));
111 $part = str_split($part, $blockSize);