Completed
Push — master ( e5d930...4cc314 )
by Michael
01:28
created

Str::substr()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Str.php.
7
 *
8
 * PHP version 7
9
 *
10
 * @category Dcrypt
11
 *
12
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
13
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
14
 *
15
 * @link     https://github.com/mmeyer2k/dcrypt
16
 */
17
18
namespace Dcrypt;
19
20
use Exception;
21
22
/**
23
 * Provides time-safe string comparison facilities, and safe string operations
24
 * on systems that have mb_* function overloading enabled.
25
 *
26
 * The functions in this class were inspired by the symfony's StringUtils class.
27
 *
28
 * @category Dcrypt
29
 *
30
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
31
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
32
 *
33
 * @link     https://github.com/mmeyer2k/dcrypt
34
 * @link     https://github.com/symfony/Security/blob/master/Core/Util/StringUtils.php
35
 * @link     https://php.net/manual/en/mbstring.overload.php
36
 */
37
final class Str
38
{
39
    /**
40
     * Compares two strings in constant time. Strings are hashed before
41
     * comparison so information is not leaked when strings are not of
42
     * equal length.
43
     *
44
     * @param string $known The string of known length to compare against
45
     * @param string $given The string that the user can control
46
     *
47
     * @throws Exception
48
     *
49
     * @return bool
50
     */
51 37
    public static function equal(string $known, string $given): bool
52
    {
53
        // Create some entropy
54 37
        $nonce = random_bytes(16);
55
56
        // Prehash the input strings with the nonce
57 37
        $known = hash_hmac('sha256', $known, $nonce, true);
58 37
        $given = hash_hmac('sha256', $given, $nonce, true);
59
60 37
        return hash_equals($known, $given);
61
    }
62
63
    /**
64
     * Determine the length of the output of a given hash algorithm in bytes.
65
     *
66
     * @param string $algo Name of algorithm to look up
67
     *
68
     * @return int
69
     */
70 38
    public static function hashSize(string $algo): int
71
    {
72 38
        return self::strlen(hash($algo, 'hash me', true));
73
    }
74
75
    /**
76
     * Returns the number of bytes in a string.
77
     *
78
     * @param string $string The string whose length we wish to obtain
79
     *
80
     * @return int
81
     */
82 39
    public static function strlen(string $string): int
83
    {
84 39
        return mb_strlen($string, '8bit');
85
    }
86
87
    /**
88
     * Returns part of a string.
89
     *
90
     * @param string   $string The string whose length we wish to obtain
91
     * @param int      $start  Offset to start gathering output
92
     * @param int|null $length Distance from starting offset to gather
93
     *
94
     * @return string
95
     */
96 36
    public static function substr(string $string, int $start, int $length = null): string
97
    {
98 36
        return mb_substr($string, $start, $length, '8bit');
99
    }
100
101
    /**
102
     * Shifts bytes off of the front of a string and return. Input string is modified.
103
     *
104
     * @param string $input
105
     * @param int    $bytes
106
     *
107
     * @return string
108
     */
109 36
    public static function shift(string &$input, int $bytes): string
110
    {
111 36
        $shift = self::substr($input, 0, $bytes);
112
113 36
        $input = self::substr($input, $bytes);
114
115 36
        return $shift;
116
    }
117
}
118