function hash($pw,$salt=NULL,$cost=self::COST) {
		if ($cost<4 || $cost>31)
			user_error(self::E_CostArg,E_USER_ERROR);
		$len=22;
		if ($salt) {
			if (!preg_match('/^[[:alnum:]\.\/]{'.$len.',}$/',$salt))
				user_error(self::E_SaltArg,E_USER_ERROR);
		}
		else {
			$raw=16;
			$iv='';
			if (!$iv && extension_loaded('openssl'))
				$iv=openssl_random_pseudo_bytes($raw);
			if (!$iv)
				for ($i=0;$i<$raw;$i++)
					$iv.=chr(mt_rand(0,255));
			$salt=str_replace('+','.',base64_encode($iv));
		}
		$salt=substr($salt,0,$len);
		$hash=crypt($pw,sprintf('$2y$%02d$',$cost).$salt);
		return strlen($hash)>13?$hash:FALSE;
	}