Passed
Push — master ( 2242a1...272748 )
by Tony Karavasilev (Тони
16:42
created

CipherDataFormatsTrait::decryptionFormatHex()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
/**
4
 * Trait implementation of the cipher/encryption data output formats for encryption algorithms.
5
 */
6
7
namespace CryptoManana\Core\Traits\MessageEncryption;
8
9
use \CryptoManana\Core\Interfaces\MessageEncryption\CipherDataFormatsInterface as CipherDataFormatsSpecification;
10
use \CryptoManana\Core\StringBuilder as StringBuilder;
11
12
/**
13
 * Trait CipherDataFormatsTrait - Reusable implementation of `CipherDataFormatsInterface`.
14
 *
15
 * @see \CryptoManana\Core\Interfaces\MessageDigestion\CipherDataFormatsInterface The abstract specification.
16
 *
17
 * @package CryptoManana\Core\Traits\MessageEncryption
18
 *
19
 * @property int $cipherFormat The output cipher format property storage.
20
 *
21
 * @mixin CipherDataFormatsSpecification
22
 */
23
trait CipherDataFormatsTrait
24
{
25
    /**
26
     * Internal method for converting format after encryption operations.
27
     *
28
     * @param string $bytes The bytes for conversion.
29
     *
30
     * @internal The parameter is passed via reference from the main logical method for performance reasons.
31
     */
32
    protected function encryptionFormat(&$bytes)
33 156
    {
34
        switch ($this->cipherFormat) {
35 156
            case self::ENCRYPTION_OUTPUT_HEX_LOWER:
36 36
                $bytes = bin2hex($bytes);
37
                break;
38
            case self::ENCRYPTION_OUTPUT_HEX_UPPER:
39 132
                $bytes = StringBuilder::stringToUpper(bin2hex($bytes));
40 120
                break;
41 120
            case self::ENCRYPTION_OUTPUT_BASE_64:
42 12
                $bytes = base64_encode($bytes);
43 12
                break;
44 120
            case self::ENCRYPTION_OUTPUT_BASE_64_URL:
45 12
                $bytes = StringBuilder::stringReplace(['+', '/', '='], ['-', '_', ''], base64_encode($bytes));
46 12
                break;
47 120
        }
48 12
    }
49 12
50 120
    /**
51
     * Internal method for converting from HEX formatted string after decryption operations.
52 120
     *
53 120
     * @param string $bytes The bytes for conversion.
54 120
     *
55
     * @internal The parameter is passed via reference from the main logical method for performance reasons.
56
     */
57 96
    protected function decryptionFormatHex(&$bytes)
58 96
    {
59 96
        if (preg_match('/^[a-f0-9]+$/', $bytes)) {
60
            $bytes = hex2bin($bytes);
61 96
        } elseif (preg_match('/^[A-F0-9]+$/', $bytes)) {
62 96
            $bytes = hex2bin(StringBuilder::stringToLower($bytes));
63 96
        }
64 12
    }
65 12
66
    /**
67 12
     * Internal method for converting from Base64 formatted string after decryption operations.
68 96
     *
69 12
     * @param string $bytes The bytes for conversion.
70 12
     *
71
     * @internal The parameter is passed via reference from the main logical method for performance reasons.
72 12
     */
73 96
    protected function decryptionFormatBase64(&$bytes)
74
    {
75 96
        if (preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $bytes) && StringBuilder::stringLength($bytes) % 4 === 0) {
76 84
            $bytes = base64_decode($bytes);
77 84
        } elseif (preg_match('/^[a-zA-Z0-9_-]+$/', $bytes)) {
78
            $bytes = StringBuilder::stringReplace(['-', '_'], ['+', '/'], $bytes);
79
            $bytes .= str_repeat('=', StringBuilder::stringLength($bytes) % 4);
80 84
            $bytes = base64_decode($bytes);
81 72
        }
82
    }
83
84 84
    /**
85
     * Internal method for converting format after decryption operations.
86 96
     *
87
     * @param string $bytes The bytes for conversion.
88
     *
89
     * @internal The parameter is passed via reference from the main logical method for performance reasons.
90 132
     */
91
    protected function decryptionFormat(&$bytes)
92
    {
93
        $isHex = in_array(
94
            $this->cipherFormat,
95
            [self::ENCRYPTION_OUTPUT_HEX_LOWER, self::ENCRYPTION_OUTPUT_HEX_UPPER],
96
            true
97
        );
98
99
        $isBase64 = in_array(
100
            $this->cipherFormat,
101 48
            [self::ENCRYPTION_OUTPUT_BASE_64, self::ENCRYPTION_OUTPUT_BASE_64_URL],
102
            true
103 48
        );
104 48
105 48
        if ($isHex) {
106
            $this->decryptionFormatHex($bytes);
107
        } elseif ($isBase64) {
108 48
            $this->decryptionFormatBase64($bytes);
109 48
        }
110
    }
111
112
    /**
113
     * Internal method for converting the output format representation via the chosen format.
114 48
     *
115 12
     * @param string $bytes The bytes for conversion.
116
     * @param bool|int|null $direction Flag for encryption direction (encrypt => `true` or decrypt => `false`).
117 12
     *
118
     * @return string The formatted bytes.
119
     */
120
    protected function changeOutputFormat($bytes, $direction = true)
121 36
    {
122
        if ($this->cipherFormat === self::ENCRYPTION_OUTPUT_RAW) {
123 36
            return $bytes;
124
        }
125
126
        if ($direction == true) {
127
            $this->encryptionFormat($bytes);
128
        } else {
129
            $this->decryptionFormat($bytes);
130
        }
131 48
132
        return $bytes;
133 48
    }
134
135
    /**
136
     * Setter for the output cipher format code property.
137
     *
138
     * @param int $cipherFormat The output cipher format code.
139
     *
140
     * @return $this The encryption algorithm object.
141
     * @throws \Exception Validation errors.
142
     */
143
    public function setCipherFormat($cipherFormat)
144
    {
145
        $cipherFormat = filter_var(
146
            $cipherFormat,
147
            FILTER_VALIDATE_INT,
148
            [
149
                "options" => [
150
                    "min_range" => self::ENCRYPTION_OUTPUT_RAW,
151
                    "max_range" => self::ENCRYPTION_OUTPUT_BASE_64_URL,
152
                ],
153
            ]
154
        );
155
156
        if ($cipherFormat === false) {
157
            throw new \InvalidArgumentException(
158
                'The output format mode must be an integer between ' .
159
                self::ENCRYPTION_OUTPUT_RAW . ' and ' . self::ENCRYPTION_OUTPUT_BASE_64_URL . '.'
160
            );
161
        }
162
163
        $this->cipherFormat = $cipherFormat;
164
165
        return $this;
166
    }
167
168
    /**
169
     * Getter for the output cipher format code property.
170
     *
171
     * @return int The output cipher format code.
172
     */
173
    public function getCipherFormat()
174
    {
175
        return $this->cipherFormat;
176
    }
177
}
178