public function hash() { $stamp = ''; $rounds = pow(2, $this->getBits()); $bytes = $this->getBits() / 8 + (8 - $this->getBits() % 8) / 8; $salt = $this->getSalt(); if (!$salt) { $salt = base64_encode(Rand::data(16)); } $baseStamp = $this->getVersion() . ':' . $this->getBits(); $baseStamp .= ':' . $this->getDate(); $baseStamp .= ':' . $this->getResource() . ':' . $this->getExtension() . ':'; $found = false; $round = 0; $testStamp = ''; $bits = 0; $attemptSalts = array(); $attempt = 0; for (; ($attempt < $this->getMintAttemptsMax() || !$this->getMintAttemptsMax()) && !$found; $attempt++) { $attemptSalts[] = $salt; $attemptStamp = $baseStamp . $salt . ':'; for ($round = 0; $round < $rounds; $round++) { $testStamp = $attemptStamp . $round; $found = $this->checkBitsFast(substr(hash('sha1', $testStamp, true), 0, $bytes), $bytes, $this->getBits()); if ($found) { break; } } if (!$found) { $salt = base64_encode(Rand::data(16)); } } if ($found) { $stamp = $testStamp; $this->setSuffix($round); $this->setSalt($salt); $this->setAttempts($attempt); $this->setHash(hash('sha1', $stamp)); } else { $msg = 'Could not mine after ' . $attempt . ' attempts, '; $msg .= 'each with ' . $rounds . ' rounds. '; $msg .= 'bits=' . $this->getBits() . ', '; $msg .= 'date=' . $this->getDate() . ', '; $msg .= 'resource=' . $this->getResource() . ', '; $msg .= 'salts=' . join(',', $attemptSalts); gio::log($msg, E_USER_ERROR); } $this->setStamp($stamp); return $stamp; }