gpt4 book ai didi

c++ - 最快的 SHA1 实现是什么?

转载 作者:行者123 更新时间:2023-12-01 14:51:32 25 4
gpt4 key购买 nike

我正在寻找最快的 SHA1 实现,因为我必须计算数百万次。我试过boost::uuids::detail::sha1OpenSSL SHA1我发现 OpenSSL 比 boost 快 2.5 倍.我还检查了Crypto++这比其他两个慢得多。这是我检查他们的表现的方法:
OpenSSL SHA1:

#include "openssl/sha.h"

void sha1_ossl (const unsigned char* data) {
unsigned char hash[20];
for (long i=0; i<100000000; ++i) {
SHA1(data, 64, hash);

if ((unsigned int)hash[0]==0 && (unsigned int)hash[1]==0 && (unsigned int)hash[2]==0 && (unsigned int)hash[3]==0)
break;
}
}
boost::SHA1:
#include <boost/uuid/detail/sha1.hpp>

void sha1_boost (const unsigned char* data) {
boost::uuids::detail::sha1 sha1;
unsigned hash[5];
for (long i=0; i<100000000; ++i) {
sha1.process_bytes(data, 64);
sha1.get_digest(hash);
sha1.reset();
if (hash[0]==0) break;
}
}
加密PP::SHA1:
#include <cryptopp/sha.h>
#include <cryptopp/hex.h>

void sha1_cryptoPP (const unsigned char* data) {
std::string data_s (reinterpret_cast<char const*>(data));
std::string hash_hex;
CryptoPP::SHA1 sha1;
for (long i=0; i<100000000; ++i) {
CryptoPP::StringSource ss(data_s, true, new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hash_hex))));
if (hash_hex.starts_with("00000000")) break;
}
}
然后我用随机数据测试这些函数:
int main() {
const unsigned char data[65] = "tJQVfvcjGMNIvJfowXBjmSRcKtSjCcyQvaAdakfEJtgSNZHnOHCjkzGFwngiLFPm";
sha1_boost (data);
sha1_ossl (data);
sha1_cryptoPP (data);
}
性能结果
我用 g++ -O3 -std=c++2a 编译了所有代码得到以下结果。我发现 OpenSSL 比其他实现更快,而 Crypto++ 最慢:
Performance of various SHA1 algorithms
问题
  • 最快的 SHA1 实现是什么?
  • 如何改进我的 Crypto++ 功能?

  • 任何改进性能的反馈表示赞赏。

    最佳答案

    我最近的实验证实了 openssl 是几个中最快的(包括 Crypto++ 和一些丢失的单源 C 实现,我忘记了哪些)
    回复:问题的代码审查类型部分:

  • boost“实现”来自详细 namespace ,不应依赖。
  • CryptoPP take 可能受益于使用过程接口(interface)而不是每次都动态组合管道。具体来说,您不应该转换为字符串来检查摘要的前 n 个字节。由于重复分配,这可能是运行时的主要部分。
    遵守程序界面也可能允许您使用重置/清除成员(引用内存)
  •     if ((unsigned int)hash[0] == 0 && (unsigned int)hash[1] == 0 &&
    (unsigned int)hash[2] == 0 && (unsigned int)hash[3] == 0)
    break;
    应该是一个简单的
        if (!(hash[0] || hash[1] || hash[2] || hash[3]))
    break;
    甚至
        if (!std::any_of(hash+0, hash+4, std::identity{}))
    break;

    改进的基准代码
    结合上面的一些和更多(主要是围绕良好的风格,避免指针错误,显示有效的迭代并允许 dump 检查摘要的准确性):
    Live On Compiler Explorer
    #include "openssl/sha.h"
    #include <boost/uuid/detail/sha1.hpp>
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    using byte = unsigned char;

    #ifndef ONLINE_DEMO
    auto constexpr iterations = 100'000'000;
    #else
    auto constexpr iterations = 10000;
    #endif

    static void dump(byte const (&a)[20]) {
    for (unsigned b : a) {
    std::cout << std::setw(2) << std::setfill('0') << std::hex << b;
    }
    std::cout << std::dec << std::endl;
    }

    static void dump(uint32_t const (&a)[5]) {
    for (auto b : a) {
    std::cout << std::setw(8) << std::setfill('0') << std::hex << b;
    }
    std::cout << std::dec << std::endl;
    }

    long sha1_ossl(std::string_view data) {
    byte hash[20];
    for (long i = 0; i < iterations; ++i) {
    SHA1(reinterpret_cast<byte const*>(data.data()), data.size(), hash);

    //dump(hash);
    if (!std::any_of(hash+0, hash+4, std::identity{}))
    return i;
    }
    return iterations;
    }

    long sha1_boost(std::string_view data) {
    boost::uuids::detail::sha1 sha1;
    uint32_t hash[5];
    for (long i = 0; i < iterations; ++i) {
    sha1.process_bytes(reinterpret_cast<byte const*>(data.data()), data.size());
    sha1.get_digest(hash);
    sha1.reset();
    //dump(hash);
    if (hash[0] == 0)
    return i;
    }
    return iterations;
    }

    #ifndef ONLINE_DEMO
    #include <cryptopp/hex.h>
    #include <cryptopp/sha.h>
    long sha1_cryptoPP(std::string_view data) {
    byte digest[20];

    CryptoPP::SHA1 sha1;
    for (long i = 0; i < iterations; ++i) {
    sha1.Restart();
    sha1.Update(reinterpret_cast<byte const*>(data.data()), data.size());
    sha1.Final(digest);

    //dump(digest);
    if (!std::any_of(digest+0, digest+4, std::identity{}))
    return i;
    }
    return iterations;
    }
    #endif

    #include <chrono>
    using namespace std::chrono_literals;

    int main() {
    static auto now = std::chrono::high_resolution_clock::now;
    constexpr static std::string_view data =
    "tJQVfvcjGMNIvJfowXBjmSRcKtSjCcyQvaAdakfEJtgSNZHnOHCjkzGFwngiLFPm";

    auto timed = [](auto caption, auto f) {
    auto const start = now();
    auto n = f(data);
    std::cout << caption << ": " << n << " in " << (now()-start)/1.0ms << "ms\n";
    };

    timed("sha1_boost", sha1_boost);
    timed("sha1_ossl", sha1_ossl);
    #ifndef ONLINE_DEMO
    timed("sha1_cryptoPP", sha1_cryptoPP);
    #endif
    }
    打印:
    sha1_boost: 100000000 in 85660.5ms
    sha1_ossl: 100000000 in 24652.6ms
    sha1_cryptoPP: 100000000 in 34921.3ms
    或在线(那里没有 Crypto++):
    sha1_boost: 10000 in 8.71938ms
    sha1_ossl: 10000 in 2.32025ms
    这是一个显着的改进,但同样是赢家。

    关于c++ - 最快的 SHA1 实现是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63502237/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com