Adds the md5 hash for one or multiple files

@param  string|array $options
@param  string       $algorithm (Deprecated) Algorithm to use, fixed to md5
@return Zend_Validate_File_Hash Provides a fluent interface
166707
public function addHash($options)
    {
        if (!is_array($options)) {
            $options = (array) $options;
        }

        $options['algorithm'] = 'md5';
        parent::addHash($options);
        return $this;
    }
136121
protected static function mcryptKey($key, $options)
	{
		$debug = \bdk\Debug::getInstance();
		if (Str::isBase64Encoded($key) && ( strlen($key) >= $options['key_size'] * 1.333 && strlen($key) <= $options['key_size'] * 1.5)) {
			$debug->log('base64 decoding key');
			$key = base64_decode($key);
		}
		$ascii = true;
		for ($i=0; $i<strlen($key); $i++) {
			if (0x80 & ord($key{$i})) {
				$ascii = false;
				break;
			}
		}
		if ($ascii) {
			$debug->log('hashing ascii key');
			$new_key	= '';
			$num_segs	= ceil($options['key_size']/20);		// 20 is length of raw sha1 output
			$seg_length	= ceil(strlen($key)/$num_segs);
			for ($i=0; $i<$num_segs; $i++) {
				$substr = substr($key, $i*$seg_length, $seg_length);
				$new_key .= sha1($substr, true);
			}
			$key = $new_key;
		}
		if (strlen($key) > $options['key_size']) {
			$debug->log('sizing key');
			$key = substr($key, 0, $options['key_size']);
		}
		return $key;
	}
314851
public function addHash($options)
    {
        if (is_string($options)) {
            $options = array($options);
        } else if (!is_array($options)) {

            throw new Zend_Validate_Exception("False parameter given");
        }

        $known = hash_algos();
        if (!isset($options['algorithm'])) {
            $algorithm = 'crc32';
        } else {
            $algorithm = $options['algorithm'];
            unset($options['algorithm']);
        }

        if (!in_array($algorithm, $known)) {

            throw new Zend_Validate_Exception("Unknown algorithm '{$algorithm}'");
        }

        foreach ($options as $value) {
            $this->_hash[$value] = $algorithm;
        }

        return $this;
    }
408589
public function generateKey(array $options = array())
	{
		// Create the new encryption key object.
		$key = new Key($this->keyType);

		// Generate an initialisation vector based on the algorithm.
		$key->public = mcrypt_create_iv(mcrypt_get_iv_size($this->type, $this->mode));

		// Get the salt and password setup.
		$salt = (isset($options['salt'])) ? $options['salt'] : substr(pack("h*", md5(mt_rand())), 0, 16);
		$password = (isset($options['password'])) ? $options['password'] : 'J00ml4R0ck$!';

		// Generate the derived key.
		$key->private = $this->pbkdf2($password, $salt, mcrypt_get_key_size($this->type, $this->mode));

		return $key;
	}
210303
protected static function mcryptDecrypt($key, $string, $options)
	{
		$debug = \bdk\Debug::getInstance();
		if (Str::isBase64Encoded($string)) {
			$debug->log('base64 decoding crypt text');
			$string = base64_decode($string);
		}
		$iv		= substr($string, 0, $options['iv_size']);
		$string	= substr($string, $options['iv_size']);
		if ($string && strlen($iv) == $options['iv_size']) {
			$string	= mcrypt_decrypt($options['cipher'], $key, $string, $options['mode'], $iv);
		}
		// now remove any padding
		$last_chr = ord(substr($string, -1));
		#$debug->log('last_chr', $last_chr);
		$method_used = 0;
		if ($last_chr > 0 && $last_chr <= $options['block_size']) {
			$remove = substr($string, -$last_chr);
			if ($remove == str_repeat(chr($last_chr), $last_chr)) {
				$method_used = 1;
			} elseif ($remove == str_repeat(chr(0), $last_chr-1).chr($last_chr)) {
				$method_used = 3;
			}
			if ($method_used) {
				$string = substr($string, 0, -$last_chr);
			}
		} elseif ($last_chr == 0 && preg_match('/\x00{1,'.$options['block_size'].'}$/', $string, $matches)) {
			$remove = $matches[0];
			$length = strlen($remove);
			$string = substr($string, 0, -$length);
			$method_used = 4;
			if ($length < $options['block_size'] && ord(substr($string, -1)) == 0x80) {
				$method_used = 2;
				$remove = chr(0x80).$remove;
				$string = substr($string, 0, -1);
			}
		}
		if ($method_used) {
			$debug->log('padding removed ('.trim(chunk_split(bin2hex($remove), 2, ' ')).'), method', $method_used);
		}
		return $string;
	}
657840
private function add(Algorithm $algorithm): self
    {
        $name = $algorithm->name();
        $this->algorithms[$name] = $algorithm;

        return $this;
    }
843851
public static function DecryptByteStream ($byte, $key, $options = []) {
		$options['module'] = \MCRYPT_MODE_CFB;
		return static::Decrypt($byte, $key, $options);
	}
1136719
public function addJsFile($asset, array $options = [], $key = null)
    {
        if (!isset($options['position'])) {
            $options['position'] = self::POS_END;
        }

        return $this->loggingFileAsset($asset, self::ASSET_JS_FILE, $options, $key);
    }
1321764
private function getOpenSslAlgorithm(string $algorithm) : int
    {
        switch ($algorithm) {
            case Algorithms::RSA_SHA256:
                return OPENSSL_ALGO_SHA256;
            case Algorithms::RSA_SHA384:
                return OPENSSL_ALGO_SHA384;
            case Algorithms::RSA_SHA512:
                return OPENSSL_ALGO_SHA512;
            default:
                throw new InvalidArgumentException("Algorithm \"$algorithm\" is not an OpenSSL algorithm");
        }
    }
729780
public function putFile($path, $file, $options = [], $defaults = 'hashName')
    {
        return $this->putFileAs($path, $file, $file->$defaults(), $options);
    }
183106
public static function EncryptByteStream ($byte, $key, $options = []) {
		$options['module'] = static::DEFAULT_BYTE_STREAM_CIPHER_METHODS;
		$options = static::_AdjustOptions($options);
		return openssl_encrypt($byte, $options['method'], $key, $options['openssl_options'], $options['iv']);
	}
959674
public function getHash(string $algorithm = 'sha256', bool $raw = false): string
	{
		return hash_file($algorithm, $this->getPathname(), $raw);
	}
1215910
public byte[] digest(String algorithm, byte[] bytes) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            return md.digest(bytes);
        }
        catch (NoSuchAlgorithmException exception) {
            throw new IllegalStateException(
                "unable to access MD5 algorithm", exception
            );
        }
    }
935609
public function hash($value, $algorithm = 'md5')
    {
        try {
            return hash($algorithm, $value);
        } catch (\Exception $e) {
            error_log('Please check that the '.$algorithm.' does exists because it failed when trying to run. We are expecting a valid algorithm such as md5 or sha512 etc. ['.$e->getMessage().']');

            return $value;
        }
    }
446398
public function carDetect($image, $options=array()){

        $data = array();
        
        $data['image'] = base64_encode($image);

        $data = array_merge($data, $options);

        return $this->request($this->carDetectUrl, $data);
    }
98773
private function getCollectionOptionsHash(array $options)
    {
        ksort($options);
        $str = '';
        foreach ($options as $option) {
            if (!$option instanceof  Serializable) {
                // All valid Collection options are BSON serializable
                continue;
            }
            $str .= serialize($option->bsonSerialize());
        }

        return md5($str);
    }
632202
public static function init($options = []) {
		// initialize mbstring
		mb_internal_encoding('UTF-8');
		mb_regex_encoding('UTF-8');
		// if we are from command line we exit here
		if (!empty($options['__run_only_bootstrap'])) {
			// format
			\Format::init();
			return;
		}
		// enforcing https
		$enforce_https = \Application::get('application.https.enforce');
		if (!empty($enforce_https)) {
			if (!\Request::isSSL()) {
				$url = \Request::host(['protocol' => 'https', 'request' => true]);
				\Request::redirect($url);
			}
		}
		// get flags & backend
		$flags = \Application::get('flag');
		$backend = \Application::get('Numbers.Backend', ['backend_exists' => true]);
		// alive
		if (!empty($flags['alive']['autoconnect'])) {
			\Alive::start();
		}
		// initialize cryptography
		$crypt = \Application::get('crypt');
		if (!empty($crypt) && $backend) {
			foreach ($crypt as $crypt_link => $crypt_settings) {
				if (!empty($crypt_settings['submodule']) && !empty($crypt_settings['autoconnect'])) {
					$crypt_object = new \Crypt($crypt_link, $crypt_settings['submodule'], $crypt_settings);
				}
			}
		}
		// including libraries that we need to auto include
		if (!empty($flags['global']['library'])) {
			foreach ($flags['global']['library'] as $k => $v) {
				// we need to skip certain keys
				if ($k == 'submodule' || $k == 'options') continue;
				// we only include if autoconnect is on
				if (!empty($v['autoconnect'])) {
					\Factory::submodule('flag.global.library.' . $k . '.submodule')->add();
				}
			}
		}
		// check if we need to include system files from frontend
		if (\Application::get('dep.submodule.Numbers.Frontend.System')) {
			\Numbers\Frontend\System\Model\Base::start();
		}
		// application structure
		$application_structure_model = \Application::get('application.structure.model');
		if (!empty($application_structure_model)) {
			\Factory::model($application_structure_model, true)->settings();
		}
		$application_structure = \Application::get('application.structure');
		// create database connections
		$db = Application::get('db');
		if (!empty($db) && $backend) {
			foreach ($db as $db_link => $db_settings) {
				if (empty($db_settings['autoconnect']) || empty($db_settings['servers']) || empty($db_settings['submodule'])) continue;
				// establish connection
				$db_result = \Db::connectToServers($db_link, $db_settings);
				// checking if not connected
				if (!$db_result['success']) {
					// if wrong database name is provided we redirect to special url
					if (!empty($application_structure['db_not_found_url']) && isset($application_structure['settings']['db'][$db_link])) {
						\Request::redirect($application_structure['db_not_found_url']);
					} else {
						Throw new \Exception('Unable to open database connection!');
					}
				}
			}
		}
		// initialize caches
		$cache = Application::get('cache');
		if (!empty($cache) && $backend) {
			foreach ($cache as $cache_link => $cache_settings) {
				if (empty($cache_settings['submodule']) || empty($cache_settings['autoconnect'])) continue;
				$cache_result = \Cache::connectToServers($cache_link, $cache_settings);
				if (!$cache_result['success']) {
					Throw new \Exception(implode(', ', $cache_result['error']));
				}
			}
		}
		// initialize session
		$session = \Application::get('flag.global.session');
		if (!empty($session['start']) && $backend && !\Application::get('flag.global.__skip_session')) {
			\Session::start($session['options'] ?? []);
		}
		// load tenant
		if (!empty($application_structure_model) && !empty($application_structure['tenant_multiple'])) {
			\Factory::model($application_structure_model, true)->tenant();
		}
		// we need to get overrides from session and put them back to flag array
		$flags = array_merge_hard($flags, \Session::get('numbers.flag'));
		\Application::set('flag', $flags);
		// custom destroy methods
		$temp = \Object\ACL\Resources::getStatic('initialize');
		if (!empty($temp)) {
			foreach ($temp as $v) {
				$method = \Factory::method($v['method'], null, true);
				call_user_func_array($method, []);
			}
		}
		// initialize i18n
		if ($backend) {
			$temp_result = \I18n::init();
			if (!$temp_result['success']) {
				Throw new \Exception('Could not initialize i18n.');
			}
		}
		// format
		\Format::init();
		// default actions
		\Layout::addAction('refresh', ['value' => 'Refresh', 'icon' => 'fas fa-sync', 'onclick' => 'location.reload();', 'order' => -32000]);
		\Layout::addAction('print', ['value' => 'Print', 'icon' => 'fas fa-print', 'onclick' => 'window.print();', 'order' => -31000]);
		// include constants
		require('Constants.php');
	}