2012-03-14 3 views
0

Я хочу сравнить два хэша sha1 для равенства. Что может быть самым эффективным способом сделать это? В настоящее время я пытаюсь использовать memcmp. Благодарю.Лучший способ сравнения хэшей sha1 для равенства

+3

Реальный вопрос: зачем беспокоиться? Вам действительно нужно * что-то быстрее, чем ваше текущее решение? Я сомневаюсь, что сравнение SHA1 - это горло бутылки в вашем приложении. –

+0

@FerdinandBeyer отличная точка – fredoverflow

+0

Я полностью согласен с Фердинандом, и то, что вы пытаетесь сделать, называется «преждевременной оптимизацией», которого следует избегать ... – Malkocoglu

ответ

3

Ну, так как вы уже знаете, во время компиляции, как большие блоки, вы можете сделать это:

#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 был еще быстрее, потому что он делал что-то очень умное и грязное.

+0

Это похоже на хорошее решение. Это быстрее, чем memcmp для моего использования. Благодарю. Хотя я должен видеть, имеет ли значение std :: equal разницу. – polapts

+0

Это может быть неудачно, если буферы не выровнены правильно.(Это также формально неопределенное поведение, но ясно, что намерение заключается в том, чтобы оно работало с такими внешними ограничениями, как выравнивание, и было бы очень плохой реализацией там, где это не было.) –

+0

Также, конечно, uint32_t' может быть недоступен. (В конце концов, это зависит от ваших ограничений переносимости. 'Uint32_t' _will_ будет доступен под Windows и под совместимыми с Posix системами. И есть очень много приложений, где это достаточно переносимо.) –

2

Что случилось с memcmp()? Вы должны сравнивать каждый байт обоих хэшей; memcmp() быстро потерпит неудачу при первой разнице, которую он находит; и memcmp() могут быть написаны авторами библиотеки для работы в размерах блоков, которые являются хорошим выбором для платформы.

+0

Я ожидал бы, что 'std :: equal' будет быстрее, чем' memcpy'; компилятор генерирует его для конкретного типа, и может даже принимать во внимание такие вещи, как выравнивание. (Конечно, 'memcpy', скорее всего, просто' # define' для чего-то вроде '__builtin_memcpy', так что компилятор может делать аналогичные оптимизации.) –

+0

Правда, но ваш совет по выравниванию границ определенно стоит; если они выровнены по 32-байтным блокам, это может быть одна инструкция SSE-something, чтобы проверить их ... – sarnold

+0

@sarnold Есть ли инструкция SSE, которая сравнивает ровно 160 бит? :) Вам, вероятно, придется перехитрить из памяти (опасно?), А затем замаскировать лишние биты. – fredoverflow

2

std::equal будет казаться лучшим, но memcmp также будет работать. Что касается эффективности, это будет зависеть от реализации, но также (возможно), как данные определены и представлены.