Completed
Push — master ( 974273...f24470 )
by Magnar Ovedal
37:37 queued 31:22
created

LeetspeakMap::getLengths()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\PasswordPolice\CodeMap;
6
7
use Stadly\PasswordPolice\CharTree;
8
use Stadly\PasswordPolice\CodeMap;
9
use Stadly\PasswordPolice\Formatter\LengthFilter;
10
use Stadly\PasswordPolice\Formatter\Truncator;
11
12
final class LeetspeakMap implements CodeMap
13
{
14
    private const ENCODE_MAP = [
15
        'A' => ['4', '@', '∂'],
16
        'B' => ['8', 'ß'],
17
        'C' => ['(', '¢', '<', '[', '©'],
18
        'D' => ['∂'],
19
        'E' => ['3', '€', 'є'],
20
        'F' => ['ƒ'],
21
        'G' => ['6', '9'],
22
        'H' => ['#'],
23
        'I' => ['1', '!', '|', ':'],
24
        'J' => ['¿'],
25
        'K' => ['X'],
26
        'L' => ['1', '£', 'ℓ'],
27
        'O' => ['0', '°'],
28
        'R' => ['2', '®', 'Я'],
29
        'S' => ['5', '$', '§'],
30
        'T' => ['7', '†'],
31
        'U' => ['µ'],
32
        'W' => ['vv'],
33
        'X' => ['×'],
34
        'Y' => ['φ', '¥'],
35
        'Z' => ['2', '≥'],
36
    ];
37
38
    /**
39
     * @var array<int, array<string|int, string[]>> Leetspeak code map.
40
     */
41
    private $codeMap = [];
42
43
    /**
44
     * @var Truncator[] Formatter for extracting the first characters.
45
     */
46
    private $charExtractors;
47
48
    /**
49
     * @param bool $encode Whether the map should encode or decode Leetspeak.
50
     */
51 6
    public function __construct($encode = false)
52
    {
53 6
        if ($encode) {
54 3
            foreach (self::ENCODE_MAP as $char => $codedChars) {
55 3
                $this->codeMap[mb_strlen($char)][mb_strtoupper($char)] = $codedChars;
56
            }
57
        } else {
58 3
            foreach (self::ENCODE_MAP as $char => $codedChars) {
59 3
                foreach ($codedChars as $codedChar) {
60 3
                    $this->codeMap[mb_strlen($codedChar)][mb_strtoupper($codedChar)][] = $char;
61
                }
62
            }
63
        }
64 6
        foreach (array_keys($this->codeMap + [1 => true]) as $length) {
65 6
            $truncator = new Truncator($length);
66 6
            $truncator->setNext(new LengthFilter($length, $length));
67 6
            $this->charExtractors[$length] = $truncator;
68
        }
69 6
    }
70
71
    /**
72
     * {@inheritDoc}
73
     */
74 6
    public function getMap(CharTree $charTree): array
75
    {
76 6
        $codeMap = [];
77
78
        // Add coded characters.
79 6
        foreach ($this->codeMap as $length => $chars) {
80 6
            foreach ($this->charExtractors[$length]->apply($charTree) as $char) {
81 2
                if (isset($chars[mb_strtoupper($char)])) {
82 6
                    $codeMap[$char] = $chars[mb_strtoupper($char)];
83
                }
84
            }
85
        }
86
87
        // Add uncoded characters.
88 6
        foreach ($this->charExtractors[1]->apply($charTree) as $char) {
89 2
            $codeMap[$char][] = $char;
90
        }
91
92 6
        return $codeMap;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    public function getLengths(): array
99
    {
100
        return array_keys($this->codeMap);
101
    }
102
}
103