<commit_before>#include <thread>

#include "plugin.h"
#include "natives.h"

using namespace native;

// native bcrypt_hash(key[], cost, callback_name[], callback_format[], {Float, _}:...);
DECLARE_NATIVE(native::bcrypt_hash)
{
	if (params[0] < 3 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_hash: Too few parameters (3 required)");
		return 0;
	}

	unsigned short cost = (unsigned short)params[2];

	if (cost < 4 || cost > 31)
	{
		plugin::printf("plugin.bcrypt: bcrypt_hash: Invalid work factor (expected 4-31)");
		return 0;
	}

	char
		*key = NULL,
		*callback_name = NULL,
		*callback_format = NULL;

	amx_StrParam(amx, params[1], key);
	amx_StrParam(amx, params[3], callback_name);
	amx_StrParam(amx, params[4], callback_format);

	if (key == NULL || callback_name == NULL)
		return 0;

	callback *cb = new callback();

	cb->setName(callback_name);
	cb->addFromFormat(amx, callback_format, params, 4);

	plugin::get()->queue_task(E_QUEUE_HASH, key, cost, cb);
	return 1;
}

// native bcrypt_check(thread_idx, thread_id, const password[], const hash[]);
DECLARE_NATIVE(native::bcrypt_check)
{
	if (params[0] < 3 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_check: Too few parameters (3 required)");
		return 0;
	}

	char
		*key = NULL,
		*hash = NULL,
		*callback_name = NULL,
		*callback_format = NULL;

	amx_StrParam(amx, params[1], key);
	amx_StrParam(amx, params[2], hash);
	amx_StrParam(amx, params[3], callback_name);
	amx_StrParam(amx, params[4], callback_format);

	if (key == NULL || hash == NULL || callback_name == NULL)
		return 0;

	callback *cb = new callback();

	cb->setName(callback_name);
	cb->addFromFormat(amx, callback_format, params, 4);

	plugin::get()->queue_task(E_QUEUE_CHECK, key, hash, cb);
	return 1;
}

// native bcrypt_get_hash(destination[]);
DECLARE_NATIVE(native::bcrypt_get_hash)
{
	if (params[0] != sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_get_hash: Invalid number of parameters (1 expected)");
		return 0;
	}

	cell *amx_dest_addr = NULL;
	amx_GetAddr(amx, params[1], &amx_dest_addr);
	amx_SetString(amx_dest_addr, plugin::get_active_hash().c_str(), 0, 0, 61);
	return 1;
}

// native bool:bcrypt_is_equal(destination[]);
DECLARE_NATIVE(native::bcrypt_is_equal)
{
	return (int)plugin::get()->get_active_match();
}

// native bcrypt_set_thread_limit(value);
DECLARE_NATIVE(native::bcrypt_set_thread_limit)
{
	if (params[0] != 1 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: The thread limit must be at least 1.");
		return 0;
	}

	unsigned thread_limit = (int)params[1];
	unsigned supported_threads = std::thread::hardware_concurrency();

	if (thread_limit >= 1)
	{
		plugin::get()->set_thread_limit(thread_limit);

		plugin::printf("plugin.bcrypt: Thread limit set to %d (CPU cores: %d)", thread_limit, supported_threads);
	}
	else
	{
		plugin::printf("plugin.bcrypt: The thread limit must be at least 1.");
		return 0;
	}

	return 1;
}
<commit_msg>Allow hashing and checking an empty string<commit_after>#include <thread>

#include "plugin.h"
#include "natives.h"

using namespace native;

// native bcrypt_hash(key[], cost, callback_name[], callback_format[], {Float, _}:...);
DECLARE_NATIVE(native::bcrypt_hash)
{
	if (params[0] < 3 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_hash: Too few parameters (3 required)");
		return 0;
	}

	unsigned short cost = (unsigned short)params[2];

	if (cost < 4 || cost > 31)
	{
		plugin::printf("plugin.bcrypt: bcrypt_hash: Invalid work factor (expected 4-31)");
		return 0;
	}

	char
		*key = NULL,
		*callback_name = NULL,
		*callback_format = NULL;

	amx_StrParam(amx, params[1], key);
	amx_StrParam(amx, params[3], callback_name);
	amx_StrParam(amx, params[4], callback_format);

	if (callback_name == NULL)
		return 0;

	callback *cb = new callback();

	cb->setName(callback_name);
	cb->addFromFormat(amx, callback_format, params, 4);

	plugin::get()->queue_task(E_QUEUE_HASH, (key != NULL ? key : std::string()), cost, cb);
	return 1;
}

// native bcrypt_check(thread_idx, thread_id, const password[], const hash[]);
DECLARE_NATIVE(native::bcrypt_check)
{
	if (params[0] < 3 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_check: Too few parameters (3 required)");
		return 0;
	}

	char
		*key = NULL,
		*hash = NULL,
		*callback_name = NULL,
		*callback_format = NULL;

	amx_StrParam(amx, params[1], key);
	amx_StrParam(amx, params[2], hash);
	amx_StrParam(amx, params[3], callback_name);
	amx_StrParam(amx, params[4], callback_format);

	if (callback_name == NULL)
		return 0;

	callback *cb = new callback();

	cb->setName(callback_name);
	cb->addFromFormat(amx, callback_format, params, 4);

	plugin::get()->queue_task(E_QUEUE_CHECK, (key != NULL ? key : std::string()), (hash != NULL ? hash : std::string()), cb);
	return 1;
}

// native bcrypt_get_hash(destination[]);
DECLARE_NATIVE(native::bcrypt_get_hash)
{
	if (params[0] != sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: bcrypt_get_hash: Invalid number of parameters (1 expected)");
		return 0;
	}

	cell *amx_dest_addr = NULL;
	amx_GetAddr(amx, params[1], &amx_dest_addr);
	amx_SetString(amx_dest_addr, plugin::get_active_hash().c_str(), 0, 0, 61);
	return 1;
}

// native bool:bcrypt_is_equal(destination[]);
DECLARE_NATIVE(native::bcrypt_is_equal)
{
	return (int)plugin::get()->get_active_match();
}

// native bcrypt_set_thread_limit(value);
DECLARE_NATIVE(native::bcrypt_set_thread_limit)
{
	if (params[0] != 1 * sizeof(cell))
	{
		plugin::printf("plugin.bcrypt: The thread limit must be at least 1.");
		return 0;
	}

	unsigned thread_limit = (int)params[1];
	unsigned supported_threads = std::thread::hardware_concurrency();

	if (thread_limit >= 1)
	{
		plugin::get()->set_thread_limit(thread_limit);

		plugin::printf("plugin.bcrypt: Thread limit set to %d (CPU cores: %d)", thread_limit, supported_threads);
	}
	else
	{
		plugin::printf("plugin.bcrypt: The thread limit must be at least 1.");
		return 0;
	}

	return 1;
}

{'fraction_non_alphanumeric': 0.16006711409395974, 'fraction_numerical': 0.015771812080536914, 'mean_word_length': 5.416576964477933, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2681903', 'n_tokens_mistral': 2337, 'n_tokens_neox': 2188, 'n_words': 487}