1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 
<?php

/**
 * This file provides compatibility functions and code for older versions of
 * PHP, such as the sha1() function, missing extensions, or 64-bit vs 32-bit
 * systems. It is only included for those older versions or when the respective
 * extension or function cannot be found.
 *
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2019 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 RC1
 */

if (!defined('SMF'))
    die('No direct access...');

/**
 * Define the old SMF sha1 function. Uses mhash if available
 *
 * @param string $str The string
 * @return string The sha1 hashed version of $str
 */
function sha1_smf($str)
{
    // If we have mhash loaded in, use it instead!
    if (function_exists('mhash') && defined('MHASH_SHA1'))
        return bin2hex(mhash(MHASH_SHA1, $str));

    $nblk = (strlen($str) + 8 >> 6) + 1;
    $blks = array_pad(array(), $nblk * 16, 0);

    for ($i = 0; $i < strlen($str); $i++)
        $blks[$i >> 2] |= ord($str{$i}) << (24 - ($i % 4) * 8);

    $blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);

    return sha1_core($blks, strlen($str) * 8);
}

/**
 * This is the core SHA-1 calculation routine, used by sha1().
 *
 * @param string $x
 * @param int $len
 * @return string
 */
function sha1_core($x, $len)
{
    @$x[$len >> 5] |= 0x80 << (24 - $len % 32);
    $x[(($len + 64 >> 9) << 4) + 15] = $len;

    $w = array();
    $a = 1732584193;
    $b = -271733879;
    $c = -1732584194;
    $d = 271733878;
    $e = -1009589776;

    for ($i = 0, $n = count($x); $i < $n; $i += 16)
    {
        $olda = $a;
        $oldb = $b;
        $oldc = $c;
        $oldd = $d;
        $olde = $e;

        for ($j = 0; $j < 80; $j++)
        {
            if ($j < 16)
                $w[$j] = isset($x[$i + $j]) ? $x[$i + $j] : 0;
            else
                $w[$j] = sha1_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);

            $t = sha1_rol($a, 5) + sha1_ft($j, $b, $c, $d) + $e + $w[$j] + sha1_kt($j);
            $e = $d;
            $d = $c;
            $c = sha1_rol($b, 30);
            $b = $a;
            $a = $t;
        }

        $a += $olda;
        $b += $oldb;
        $c += $oldc;
        $d += $oldd;
        $e += $olde;
    }

    return sprintf('%08x%08x%08x%08x%08x', $a, $b, $c, $d, $e);
}

/**
 * Helper function for the core SHA-1 calculation
 *
 * @param int $t
 * @param int $b
 * @param int $c
 * @param int $d
 * @return int
 */
function sha1_ft($t, $b, $c, $d)
{
    if ($t < 20)
        return ($b & $c) | ((~$b) & $d);
    if ($t < 40)
        return $b ^ $c ^ $d;
    if ($t < 60)
        return ($b & $c) | ($b & $d) | ($c & $d);

    return $b ^ $c ^ $d;
}

/**
 * Helper function for the core SHA-1 calculation
 *
 * @param int $t
 * @return int 1518500249, 1859775393, -1894007588 or -899497514 depending on the value of $t
 */
function sha1_kt($t)
{
    return $t < 20 ? 1518500249 : ($t < 40 ? 1859775393 : ($t < 60 ? -1894007588 : -899497514));
}

/**
 * Helper function for the core SHA-1 calculation
 *
 * @param int $num
 * @param int $cnt
 * @return int
 */
function sha1_rol($num, $cnt)
{
    // Unfortunately, PHP uses unsigned 32-bit longs only.  So we have to kludge it a bit.
    if ($num & 0x80000000)
        $a = ($num >> 1 & 0x7fffffff) >> (31 - $cnt);
    else
        $a = $num >> (32 - $cnt);

    return ($num << $cnt) | $a;
}

/**
 * Available since: (PHP 5)
 * If the optional raw_output is set to TRUE, then the sha1 digest is instead returned in raw binary format with a length of 20,
 * otherwise the returned value is a 40-character hexadecimal number.
 *
 * @param string $text The text to hash
 * @return string The sha1 hash of $text
 */
function sha1_raw($text)
{
    return sha1($text, true);
}

/**
 * Compatibility function.
 * crc32 doesn't work as expected on 64-bit functions - make our own.
 * https://php.net/crc32#79567
 *
 * @param string $number
 * @return string The crc32 polynomial of $number
 */
if (!function_exists('smf_crc32'))
{
    function smf_crc32($number)
    {
        $crc = crc32($number);

        if ($crc & 0x80000000)
        {
            $crc ^= 0xffffffff;
            $crc += 1;
            $crc = -$crc;
        }

        return $crc;
    }
}

?>