Bcmath随机添加小数位

时间:2014-05-10 00:19:27

标签: php bcmath

我有一个从网上使用bcmath函数的PHP函数:

function SteamID64to32($steamId64) {
    $iServer = "1";
    if(bcmod($steamId64, "2") == "0") {
        $iServer = "0";
    }
    $steamId64 = bcsub($steamId64,$iServer);
    if(bccomp("76561197960265728",$steamId64) == -1) {
        $steamId64 = bcsub($steamId64,"76561197960265728");
    }
    $steamId64 = bcdiv($steamId64, "2");
    return ("STEAM_0:" . $iServer . ":" . $steamId64);
}

对于任何有效输入,该函数将随机添加" .0000000000"到输出。

例如:

$input = 76561198014791430;
SteamID64to32($input);

//result for each run
STEAM_0:0:27262851
STEAM_0:0:27262851.0000000000
STEAM_0:0:27262851
STEAM_0:0:27262851
STEAM_0:0:27262851.0000000000
STEAM_0:0:27262851
STEAM_0:0:27262851.0000000000
STEAM_0:0:27262851.0000000000
STEAM_0:0:27262851.0000000000

这是在运行php-fpm的2个不同的nginx服务器上测试的。 请帮我理解这里有什么问题。感谢

2 个答案:

答案 0 :(得分:1)

我发现了这个:SteamProfile

/**
 *      This file is part of SteamProfile.
 *
 *      Written by Nico Bergemann <barracuda415@yahoo.de>
 *      Copyright 2009 Nico Bergemann
 *
 *      SteamProfile is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      SteamProfile is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with SteamProfile.  If not, see <http://www.gnu.org/licenses/>.
 */

// thanks to voogru for the id transformation algorithm (http://forums.alliedmods.net/showthread.php?t=60899)

class SteamID {
        private $sSteamID = '';
        private $sSteamComID = '';

        const STEAMID64_BASE = '76561197960265728';

        public function __construct($sID) {
                // make sure the bcmath extension is loaded
                if(!extension_loaded('bcmath')) {
                        throw new RuntimeException("BCMath extension required");
                }

                if($this->isValidSteamID($sID)) {
                        $this->sSteamID = $sID;
                        $this->sSteamComID = $this->convertToSteamComID($sID);
                } elseif($this->isValidComID($sID)) {
                        $this->sSteamID = $this->convertToSteamID($sID);
                        $this->sSteamComID = $sID;
                } else {
                        $this->sSteamID = '';
                        $this->sSteamComID = '';
                }
        }

        public function getSteamID() {
                return $this->sSteamID;
        }

        public function getSteamComID() {
                return $this->sSteamComID;
        }

        public function isValid() {
                return $this->sSteamID != '';
        }

        private function isValidSteamID($sSteamID) {
                return preg_match('/^(STEAM_)?[0-5]:[0-9]:\d+$/i', $sSteamID);
        }

        private function isValidComID($sSteamComID) {
                // anything else than a number is invalid
                // (is_numeric() doesn't work for 64 bit integers)
                if(!preg_match('/^\d+$/i', $sSteamComID)) {
                        return false;
                }

                // the community id must be bigger than STEAMID64_BASE
                if(bccomp(self::STEAMID64_BASE, $sSteamComID) == 1) {
                        return false;
                }

                // TODO: Upper limit?

                return true;
        }

        private function convertToSteamComID($sSteamID) {
                $aTMP = explode(':', $sSteamID);

                $sServer = $aTMP[1];
                $sAuth = $aTMP[2];

                if((count($aTMP) == 3) && $sAuth != '0' && is_numeric($sServer) && is_numeric($sAuth)) {
                        $sComID = bcmul($sAuth, "2"); // multipy Auth-ID with 2
                        $sComID = bcadd($sComID, $sServer); // add Server-ID
                        $sComID = bcadd($sComID, self::STEAMID64_BASE); // add this odd long number

                        // It seems that PHP appends ".0000000000" at the end sometimes.
                        // I can't find a reason for this, so I'll take the dirty way...
                        $sComID = str_replace('.0000000000', '', $sComID);

                        return $sComID;
                } else {
                        throw new RuntimeException("Unable to convert Steam-ID");
                }
        }

        private function convertToSteamID($sSteamComID) {
                $sServer = bcmod($sSteamComID, '2') == '0' ? '0' : '1';
                $sCommID = bcsub($sSteamComID, $sServer);
                $sCommID = bcsub($sCommID, self::STEAMID64_BASE);
                $sAuth = bcdiv($sCommID, '2');

                return "STEAM_0:$sServer:$sAuth";
        }
}

答案 1 :(得分:1)

JD提供的答案并未考虑所有可能的STEAM_ ID类型,即STEAM_0:1范围内的任何内容。这段代码将:

<?php

function Steam64ToSteam32($Steam64ID)
{
    $offset = $Steam64ID - 76561197960265728;
    $id = ($offset / 2);
    if($offset % 2 != 0)
    {
        $Steam32ID = 'STEAM_0:1:' . bcsub($id, '0.5');
    }
    else
    {
        $Steam32ID = "STEAM_0:0:" . $id;
    }
    return $Steam32ID;
}

echo Steam64ToSteam32(76561197960435530);
echo "<br/>";
echo Steam64ToSteam32(76561197990323733);
echo "<br/>";
echo Steam64ToSteam32(76561198014791430);
?>

此输出

STEAM_0:0:84901
STEAM_0:1:15029002
STEAM_0:0:27262851

第一个是Valve员工和自2003年以来拥有Steam帐户的人(因此ID较低),第二个是我在VACBanned上找到的随机个人资料,其{{1} }} 范围。第三个是您在示例代码中提供的ID。