File: /var/www/epamokos.kaunokolegija.lt/wp-content/plugins/lifterlms/includes/class.llms.hasher.php
<?php
/**
* LifterLMS hash ID encrypt/decrypt
*
* Based on PseudoCrypt by KevBurns (http://blog.kevburnsjr.com/php-unique-hash).
*
* Modified from original source to remove reliance on bcmath functions.
*
* @package LifterLMS/Classes
*
* @since 3.16.7
* @version 3.24.0
*
* @link http://stackoverflow.com/a/1464155/933782
*/
defined( 'ABSPATH' ) || exit;
/**
* LLMS_Hasher
*
* @since 3.16.7
* @since 3.24.0 Unknown.
*/
class LLMS_Hasher {
/**
* Key: Next prime greater than 62 ^ n / 1.618033988749894848
* Value: modular multiplicative inverse
*
* @var array
*/
private static $golden_primes = array(
'1' => '1',
'41' => '59',
'2377' => '1677',
'147299' => '187507',
'9132313' => '5952585',
'566201239' => '643566407',
'35104476161' => '22071637057',
'2176477521929' => '294289236153',
'134941606358731' => '88879354792675',
'8366379594239857' => '7275288500431249',
'518715534842869223' => '280042546585394647',
);
/**
* Ascii = 0 9, A Z, a z
* $chars = array_merge(range(48,57), range(65,90), range(97,122))
*
* @var array
*/
private static $chars62 = array(
0 => 48,
1 => 49,
2 => 50,
3 => 51,
4 => 52,
5 => 53,
6 => 54,
7 => 55,
8 => 56,
9 => 57,
10 => 65,
11 => 66,
12 => 67,
13 => 68,
14 => 69,
15 => 70,
16 => 71,
17 => 72,
18 => 73,
19 => 74,
20 => 75,
21 => 76,
22 => 77,
23 => 78,
24 => 79,
25 => 80,
26 => 81,
27 => 82,
28 => 83,
29 => 84,
30 => 85,
31 => 86,
32 => 87,
33 => 88,
34 => 89,
35 => 90,
36 => 97,
37 => 98,
38 => 99,
39 => 100,
40 => 101,
41 => 102,
42 => 103,
43 => 104,
44 => 105,
45 => 106,
46 => 107,
47 => 108,
48 => 109,
49 => 110,
50 => 111,
51 => 112,
52 => 113,
53 => 114,
54 => 115,
55 => 116,
56 => 117,
57 => 118,
58 => 119,
59 => 120,
60 => 121,
61 => 122,
);
/**
* Modulo function
*
* @todo figure this out better...
* 64 bit systems can use % without issue
* 32 bit systems have problems with % and needs to use fmod
* however after 100001 unhash no longer works correctly when using fmod
*
* @param int $a first int
* @param int $b second int
* @return int
* @since 3.16.10
* @version 3.16.10
*/
private static function mod( $a, $b ) {
// 64 bit systems
if ( 8 === PHP_INT_SIZE ) {
return $a % $b;
}
// 32 bit systems?
return fmod( $a, $b );
}
/**
* Base 62 encode a number
*
* @param int $int number to encode
* @return string
* @since 3.16.7
* @version 3.16.10
*/
public static function base62( $int ) {
$key = '';
while ( $int > 0 ) {
$mod = self::mod( $int, 62 );
$key .= chr( self::$chars62[ $mod ] );
$int = floor( $int / 62 );
}
return strrev( $key );
}
/**
* Hash a number
*
* @param int $num number to hash
* @return string
* @since 3.16.7
* @version 3.24.0
*/
public static function hash( $num ) {
$numlen = strlen( $num );
if ( $numlen <= 3 ) {
$len = 3;
} elseif ( 4 === $numlen || 5 === $numlen ) {
$len = 4;
} else {
$len = 5;
}
$ceil = pow( 62, $len );
$primes = array_keys( self::$golden_primes );
$prime = $primes[ $len ];
$dec = self::mod( ( $num * $prime ), $ceil );
$hash = self::base62( $dec );
return str_pad( $hash, $len, '0', STR_PAD_LEFT );
}
/**
* Decode a base62 encoded string to get the associated number
*
* @param string $key encoded character
* @return int
* @since 3.16.7
* @version 3.16.7
*/
public static function unbase62( $key ) {
$int = 0;
foreach ( str_split( strrev( $key ) ) as $i => $char ) {
$dec = array_search( ord( $char ), self::$chars62 );
$int = ( ( $dec * pow( 62, $i ) ) + $int );
}
return $int;
}
/**
* Decode a hashed string to get the original number
*
* @param [type] $hash encoded hash string
* @return int
* @since 3.16.7
* @version 3.16.10
*/
public static function unhash( $hash ) {
$len = strlen( $hash );
$ceil = pow( 62, $len );
$mmiprimes = array_values( self::$golden_primes );
$mmi = $mmiprimes[ $len ];
$num = self::unbase62( $hash );
$dec = self::mod( ( $num * $mmi ), $ceil );
return $dec;
}
}