Completed
Push — master ( de8919...8d59f2 )
by Tony Karavasilev (Тони
16:47
created

CipherDataFormatsTrait::encryptionFormat()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 17
ccs 15
cts 15
cp 1
rs 9.4555
cc 5
nc 5
nop 1
crap 5
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 120
    protected function encryptionFormat(&$bytes)
33
    {
34 120
        switch ($this->cipherFormat) {
35 120
            case self::ENCRYPTION_OUTPUT_HEX_LOWER:
1 ignored issue
show
Bug introduced by
The constant CryptoManana\Core\Traits...YPTION_OUTPUT_HEX_LOWER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
36 12
                $bytes = bin2hex($bytes);
37 12
                break;
38 120
            case self::ENCRYPTION_OUTPUT_HEX_UPPER:
39 12
                $bytes = StringBuilder::stringToUpper(bin2hex($bytes));
40 12
                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:
1 ignored issue
show
Bug introduced by
The constant CryptoManana\Core\Traits...TION_OUTPUT_BASE_64_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
45
            default:
46 120
                $bytes = base64_encode($bytes);
47 120
                $bytes = StringBuilder::stringReplace(['+', '/', '='], ['-', '_', ''], $bytes);
48 120
                break;
49
        }
50 120
    }
51
52
    /**
53
     * Internal method for converting format after decryption operations.
54
     *
55
     * @param string $bytes The bytes for conversion.
56
     *
57
     * @internal The parameter is passed via reference from the main logical method for performance reasons.
58
     */
59 96
    protected function decryptionFormat(&$bytes)
60
    {
61 96
        $hexCasePattern = '/^[a-f0-9]+$/';
62 96
        $base64Pattern = '%^[a-zA-Z0-9/+]*={0,2}$%';
63 96
        $base64UrlFriendlyPattern = '/^[a-zA-Z0-9_-]+$/';
64
65 96
        switch ($this->cipherFormat) {
66 96
            case self::ENCRYPTION_OUTPUT_HEX_LOWER:
67 96
            case self::ENCRYPTION_OUTPUT_HEX_UPPER:
1 ignored issue
show
Bug introduced by
The constant CryptoManana\Core\Traits...YPTION_OUTPUT_HEX_UPPER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
68 12
                if (preg_match($hexCasePattern, StringBuilder::stringToLower($bytes))) {
69 12
                    $bytes = hex2bin(StringBuilder::stringToLower($bytes));
70
                }
71 12
                break;
72 96
            case self::ENCRYPTION_OUTPUT_BASE_64:
1 ignored issue
show
Bug introduced by
The constant CryptoManana\Core\Traits...CRYPTION_OUTPUT_BASE_64 was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
73 12
                if (preg_match($base64Pattern, $bytes) && StringBuilder::stringLength($bytes) % 4 === 0) {
74 12
                    $bytes = base64_decode($bytes);
75
                }
76 12
                break;
77 96
            case self::ENCRYPTION_OUTPUT_BASE_64_URL:
78
            default:
79 96
                if (preg_match($base64UrlFriendlyPattern, $bytes)) {
80 84
                    $bytes = StringBuilder::stringReplace(['-', '_'], ['+', '/'], $bytes);
81 84
                    $times = StringBuilder::stringLength($bytes) % 4;
82
83
                    // Instead of str_pad for encoding friendly appending
84 84
                    for ($i = 0; $i < $times; $i++) {
85 72
                        $bytes .= '=';
86
                    }
87
88 84
                    $bytes = base64_decode($bytes);
89
                }
90 96
                break;
91
        }
92 96
    }
93
94
    /**
95
     * Internal method for converting the output format representation via the chosen format.
96
     *
97
     * @param string $bytes The bytes for conversion.
98
     * @param bool|int|null $direction Flag for encryption direction (encrypt => `true` or decrypt => `false`).
99
     *
100
     * @return string The formatted bytes.
101
     */
102 156
    protected function changeOutputFormat($bytes, $direction = true)
103
    {
104 156
        if ($this->cipherFormat === self::ENCRYPTION_OUTPUT_RAW) {
105 36
            return $bytes;
106
        }
107
108 132
        if ($direction == true) {
109 120
            $this->encryptionFormat($bytes);
110
        } else {
111 96
            $this->decryptionFormat($bytes);
112
        }
113
114 132
        return $bytes;
115
    }
116
117
    /**
118
     * Setter for the output cipher format code property.
119
     *
120
     * @param int $cipherFormat The output cipher format code.
121
     *
122
     * @return $this The encryption algorithm object.
123
     * @throws \Exception Validation errors.
124
     */
125 48
    public function setCipherFormat($cipherFormat)
126
    {
127 48
        $cipherFormat = filter_var(
128 48
            $cipherFormat,
129 48
            FILTER_VALIDATE_INT,
130
            [
131
                "options" => [
132 48
                    "min_range" => self::ENCRYPTION_OUTPUT_RAW,
133 48
                    "max_range" => self::ENCRYPTION_OUTPUT_BASE_64_URL,
134
                ],
135
            ]
136
        );
137
138 48
        if ($cipherFormat === false) {
139 12
            throw new \InvalidArgumentException(
140
                'The output format mode must be an integer between ' .
141 12
                self::ENCRYPTION_OUTPUT_RAW . ' and ' . self::ENCRYPTION_OUTPUT_BASE_64_URL . '.'
142
            );
143
        }
144
145 36
        $this->cipherFormat = $cipherFormat;
146
147 36
        return $this;
148
    }
149
150
    /**
151
     * Getter for the output cipher format code property.
152
     *
153
     * @return int The output cipher format code.
154
     */
155 48
    public function getCipherFormat()
156
    {
157 48
        return $this->cipherFormat;
158
    }
159
}
160