ReferenceNumber::secureCrypt()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 3
nc 2
nop 2
1
<?php
2
/*
3
 *
4
 *
5
 * Source http://stackoverflow.com/a/13733588/179104
6
 *
7
 */
8
9
namespace Parkwayprojects\PayWithBank3D;
10
11
class ReferenceNumber
12
{
13
    /**
14
     * Get the pool to use based on the type of prefix hash.
15
     * @param  string $type
16
     * @return string
17
     */
18
    private static function getPool($type = 'alnum')
19
    {
20
        switch ($type) {
21
            case 'alnum':
22
                $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
23
                break;
24
            case 'alpha':
25
                $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
26
                break;
27
            case 'hexdec':
28
                $pool = '0123456789abcdef';
29
                break;
30
            case 'numeric':
31
                $pool = '0123456789';
32
                break;
33
            case 'nozero':
34
                $pool = '123456789';
35
                break;
36
            case 'distinct':
37
                $pool = '2345679ACDEFHJKLMNPRSTUVWXYZ';
38
                break;
39
            default:
40
                $pool = (string) $type;
41
                break;
42
        }
43
44
        return $pool;
45
    }
46
47
    /**
48
     * Generate a random secure crypt figure.
49
     * @param  int $min
50
     * @param  int $max
51
     * @return int
52
     */
53
    private static function secureCrypt($min, $max)
54
    {
55
        $range = $max - $min;
56
57
        if ($range < 0) {
58
            return $min; // not so random...
59
        }
60
61
        $log = log($range, 2);
62
        $bytes = (int) ($log / 8) + 1; // length in bytes
63
        $bits = (int) $log + 1; // length in bits
64
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
65
        do {
66
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
67
            $rnd = $rnd & $filter; // discard irrelevant bits
68
        } while ($rnd >= $range);
69
70
        return $min + $rnd;
71
    }
72
73
    /**
74
     * Finally, generate a hashed token.
75
     * @param  int $length
76
     * @return string
77
     */
78
    public static function getHashedToken($length = 25)
79
    {
80
        $token = '';
81
        $max = strlen(static::getPool());
0 ignored issues
show
Bug introduced by
Since getPool() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getPool() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
82
        for ($i = 0; $i < $length; $i++) {
83
            $token .= static::getPool()[static::secureCrypt(0, $max)];
0 ignored issues
show
Bug introduced by
Since getPool() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getPool() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
Bug introduced by
Since secureCrypt() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of secureCrypt() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
84
        }
85
86
        return $token;
87
    }
88
}
89