Completed
Branch master (3439e9)
by Tony Karavasilev (Тони
19:43 queued 16:40
created

CipherDataFormatsTrait::encryptionFormat()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0073

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 17
ccs 14
cts 15
cp 0.9333
rs 9.4555
cc 5
nc 5
nop 1
crap 5.0073
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:
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:
45 120
                $bytes = StringBuilder::stringReplace(['+', '/', '='], ['-', '_', ''], base64_encode($bytes));
46 120
                break;
47
            default: // Then nothing
48
                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
        $isHex = in_array(
62 96
            $this->cipherFormat,
63 96
            [self::ENCRYPTION_OUTPUT_HEX_LOWER, self::ENCRYPTION_OUTPUT_HEX_UPPER],
64 96
            true
65
        );
66
67 96
        $isBase64 = in_array(
68 96
            $this->cipherFormat,
69 96
            [self::ENCRYPTION_OUTPUT_BASE_64, self::ENCRYPTION_OUTPUT_BASE_64_URL],
70 96
            true
71
        );
72
73 96
        if ($isHex) {
74 12
            if (preg_match('/^[a-f0-9]+$/', StringBuilder::stringToLower($bytes))) {
75 12
                $bytes = hex2bin(StringBuilder::stringToLower($bytes));
76
            }
77 96
        } elseif ($isBase64) {
78 96
            if (preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $bytes) && StringBuilder::stringLength($bytes) % 4 === 0) {
79 14
                $bytes = base64_decode($bytes);
80 94
            } elseif (preg_match('/^[a-zA-Z0-9_-]+$/', $bytes)) {
81 82
                $bytes = StringBuilder::stringReplace(['-', '_'], ['+', '/'], $bytes);
82 82
                $bytes .= str_repeat('=', StringBuilder::stringLength($bytes) % 4);
83 82
                $bytes = base64_decode($bytes);
84
            }
85
        }
86 96
    }
87
88
    /**
89
     * Internal method for converting the output format representation via the chosen format.
90
     *
91
     * @param string $bytes The bytes for conversion.
92
     * @param bool|int|null $direction Flag for encryption direction (encrypt => `true` or decrypt => `false`).
93
     *
94
     * @return string The formatted bytes.
95
     */
96 156
    protected function changeOutputFormat($bytes, $direction = true)
97
    {
98 156
        if ($this->cipherFormat === self::ENCRYPTION_OUTPUT_RAW) {
99 36
            return $bytes;
100
        }
101
102 132
        if ($direction == true) {
103 120
            $this->encryptionFormat($bytes);
104
        } else {
105 96
            $this->decryptionFormat($bytes);
106
        }
107
108 132
        return $bytes;
109
    }
110
111
    /**
112
     * Setter for the output cipher format code property.
113
     *
114
     * @param int $cipherFormat The output cipher format code.
115
     *
116
     * @return $this The encryption algorithm object.
117
     * @throws \Exception Validation errors.
118
     */
119 48
    public function setCipherFormat($cipherFormat)
120
    {
121 48
        $cipherFormat = filter_var(
122 48
            $cipherFormat,
123 48
            FILTER_VALIDATE_INT,
124
            [
125
                "options" => [
126 48
                    "min_range" => self::ENCRYPTION_OUTPUT_RAW,
127 48
                    "max_range" => self::ENCRYPTION_OUTPUT_BASE_64_URL,
128
                ],
129
            ]
130
        );
131
132 48
        if ($cipherFormat === false) {
133 12
            throw new \InvalidArgumentException(
134
                'The output format mode must be an integer between ' .
135 12
                self::ENCRYPTION_OUTPUT_RAW . ' and ' . self::ENCRYPTION_OUTPUT_BASE_64_URL . '.'
136
            );
137
        }
138
139 36
        $this->cipherFormat = $cipherFormat;
140
141 36
        return $this;
142
    }
143
144
    /**
145
     * Getter for the output cipher format code property.
146
     *
147
     * @return int The output cipher format code.
148
     */
149 48
    public function getCipherFormat()
150
    {
151 48
        return $this->cipherFormat;
152
    }
153
}
154