Я хочу сравнить два хэша sha1 для равенства. Что может быть самым эффективным способом сделать это? В настоящее время я пытаюсь использовать memcmp. Благодарю.Лучший способ сравнения хэшей sha1 для равенства
ответ
Ну, так как вы уже знаете, во время компиляции, как большие блоки, вы можете сделать это:
#include <cstdint>
bool is_same_sha1(const char* p, const char* q)
{
const std::uint32_t* a = (const std::uint32_t*)p;
const std::uint32_t* b = (const std::uint32_t*)q;
return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]
&& a[3] == b[3] && a[4] == b[4];
}
Но не принимайте мои советы вслепую, вы должны меру любое пользовательское решение против решение memcmp
и использовать его только в том случае, если оно дает вам значительное преимущество в производительности. Я даже не удивился бы, если бы memcmp
был еще быстрее, потому что он делал что-то очень умное и грязное.
Это похоже на хорошее решение. Это быстрее, чем memcmp для моего использования. Благодарю. Хотя я должен видеть, имеет ли значение std :: equal разницу. – polapts
Это может быть неудачно, если буферы не выровнены правильно.(Это также формально неопределенное поведение, но ясно, что намерение заключается в том, чтобы оно работало с такими внешними ограничениями, как выравнивание, и было бы очень плохой реализацией там, где это не было.) –
Также, конечно, uint32_t' может быть недоступен. (В конце концов, это зависит от ваших ограничений переносимости. 'Uint32_t' _will_ будет доступен под Windows и под совместимыми с Posix системами. И есть очень много приложений, где это достаточно переносимо.) –
Что случилось с memcmp()
? Вы должны сравнивать каждый байт обоих хэшей; memcmp()
быстро потерпит неудачу при первой разнице, которую он находит; и memcmp()
могут быть написаны авторами библиотеки для работы в размерах блоков, которые являются хорошим выбором для платформы.
Я ожидал бы, что 'std :: equal' будет быстрее, чем' memcpy'; компилятор генерирует его для конкретного типа, и может даже принимать во внимание такие вещи, как выравнивание. (Конечно, 'memcpy', скорее всего, просто' # define' для чего-то вроде '__builtin_memcpy', так что компилятор может делать аналогичные оптимизации.) –
Правда, но ваш совет по выравниванию границ определенно стоит; если они выровнены по 32-байтным блокам, это может быть одна инструкция SSE-something, чтобы проверить их ... – sarnold
@sarnold Есть ли инструкция SSE, которая сравнивает ровно 160 бит? :) Вам, вероятно, придется перехитрить из памяти (опасно?), А затем замаскировать лишние биты. – fredoverflow
std::equal
будет казаться лучшим, но memcmp
также будет работать. Что касается эффективности, это будет зависеть от реализации, но также (возможно), как данные определены и представлены.
Реальный вопрос: зачем беспокоиться? Вам действительно нужно * что-то быстрее, чем ваше текущее решение? Я сомневаюсь, что сравнение SHA1 - это горло бутылки в вашем приложении. –
@FerdinandBeyer отличная точка – fredoverflow
Я полностью согласен с Фердинандом, и то, что вы пытаетесь сделать, называется «преждевременной оптимизацией», которого следует избегать ... – Malkocoglu