Passed
Push — master ( 12ec71...6a4e7a )
by Magnar Ovedal
02:59
created

Leetspeak::getDecodeMap()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\PasswordPolice\WordFormatter;
6
7
use Stadly\PasswordPolice\WordFormatter;
8
use Traversable;
9
10
final class Leetspeak implements WordFormatter
11
{
12
    /**
13
     * @var array<string, string[]>
14
     */
15
    private $encodeMap = [
16
        'A' => ['4', '@', '∂'],
17
        'B' => ['8', 'ß'],
18
        'C' => ['(', '¢', '<', '[', '©'],
19
        'D' => ['∂'],
20
        'E' => ['3', '€', 'є'],
21
        'F' => ['ƒ'],
22
        'G' => ['6', '9'],
23
        'H' => ['#'],
24
        'I' => ['1', '!', '|', ':'],
25
        'J' => ['¿'],
26
        'K' => ['X'],
27
        'L' => ['1', '£', 'ℓ'],
28
        'O' => ['0', '°'],
29
        'R' => ['2', '®', 'Я'],
30
        'S' => ['5', '$', '§'],
31
        'T' => ['7', '†'],
32
        'U' => ['µ'],
33
        'W' => ['vv'],
34
        'X' => ['×'],
35
        'Y' => ['φ', '¥'],
36
        'Z' => ['2', '≥'],
37
    ];
38
39
    /**
40
     * @var array<string|int, string[]>
41
     */
42
    private $decodeMap = [];
43
44 1
    public function __construct()
45
    {
46 1
        foreach ($this->encodeMap as $char => $encodedChars) {
47 1
            foreach ($encodedChars as $encodedChar) {
48 1
                $this->decodeMap[$encodedChar][] = $char;
49
            }
50
        }
51 1
    }
52
53
    /**
54
     * @param string $word Word to get decode map for.
55
     * @return array<string|int, string[]> Map for decoding the word prefix.
56
     */
57 2
    private function getDecodeMap(string $word): array
58
    {
59 2
        $decodeMap = [];
60 2
        foreach ($this->decodeMap as $encodedChar => $chars) {
61 2
            if ((string)$encodedChar === mb_substr($word, 0, mb_strlen((string)$encodedChar))) {
62 2
                $decodeMap[$encodedChar] = $chars;
63
            }
64
        }
65 2
        $decodeMap[mb_substr($word, 0, 1)][] = mb_substr($word, 0, 1);
66
67 2
        return $decodeMap;
68
    }
69
70
    /**
71
     * {@inheritDoc}
72
     */
73 2
    public function apply(string $word): Traversable
74
    {
75 2
        if ($word === '') {
76 2
            yield '';
77 2
            return;
78
        }
79
80 2
        foreach ($this->getDecodeMap($word) as $encodedChar => $chars) {
81 2
            foreach ($this->apply(mb_substr($word, mb_strlen((string)$encodedChar))) as $suffix) {
82 2
                foreach ($chars as $char) {
83 2
                    yield $char.$suffix;
84
                }
85
            }
86
        }
87 2
    }
88
}
89