在Crypto ++中获取Unicode字符串的SHA1

Dmi*_*okk 5 c++ unicode sha1 digest crypto++

我独立学习C++,我有一个问题,我不能解决超过一周的问题.我希望你能帮助我.

我需要获取Unicode字符串的SHA1摘要(如??????),但我不知道如何做到这一点.

我尝试这样做,但它返回错误的摘要!

因为wstring('?') 它返回 - A469A61DF29A7568A6CC63318EA8741FA1CF2A7
我需要 -8dbe718ab1e0c4d75f7ab50fc9a53ec4f0528373

关心并抱歉我的英语:).

CryptoPP 5.6.2 MVC++ 2013

#include <iostream>
#include "cryptopp562\cryptlib.h"
#include "cryptopp562\sha.h"
#include "cryptopp562\hex.h"

int main() {

    std::wstring string(L"?");
    int bs_size = (int)string.length() * sizeof(wchar_t);

    byte* bytes_string = new byte[bs_size];

    int n = 0; //real bytes count
    for (int i = 0; i < string.length(); i++) {
        wchar_t wcharacter = string[i];

        int high_byte = wcharacter & 0xFF00;

        high_byte = high_byte >> 8;

        int low_byte = wcharacter & 0xFF;

        if (high_byte != 0) {
            bytes_string[n++] = (byte)high_byte;
        }

        bytes_string[n++] = (byte)low_byte;
    }

    CryptoPP::SHA1 sha1;
    std::string hash;

    CryptoPP::StringSource ss(bytes_string, n, true,
        new CryptoPP::HashFilter(sha1,
            new CryptoPP::HexEncoder(
                new CryptoPP::StringSink(hash)
            ) 
        ) 
    );

    std::cout << hash << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

jww*_*jww 3

\n

我需要获取 Unicode 字符串的 SHA1 摘要(例如 \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82),但我不知道该怎么做。

\n
\n\n

这里的技巧是您需要知道如何对 Unicode 字符串进行编码。在 Windows 上,awchar_t是 2 个八位字节;而在 Linux 上 awchar_t是 4 个八位字节。在字符集注意事项上有一个 Crypto++ wiki 页面,但它不是那么好。

\n\n

为了最有效地进行互操作,请始终使用 UTF-8。这意味着您将 UTF-16 或 UTF-32 转换为 UTF-8。因为您使用的是 Windows,所以您需要调用WideCharToMultiByte 函数来使用CP_UTF8. 如果您使用的是 Linux,那么您会使用libiconv.

\n\n

StringNarrowCrypto++ 有一个名为使用 C++ 的内置函数。它在文件中misc.hsetlocale使用前请务必先致电。

\n\n

Stack Overflow 有一些关于使用 Windows 函数的问题。例如,请参阅如何正确使用 WideCharToMultiByte

\n\n
\n\n
\n

我需要 - 8dbe718ab1e0c4d75f7ab50fc9a53ec4f0528373

\n
\n\n

哈希值是什么(SHA-1、SHA-256,...)?它是 HMAC(密钥哈希)吗?信息是否加盐(如存储中的密码)?它是如何编码的?我必须问,因为我无法重现您想要的结果:

\n\n
SHA-1:   2805AE8E7E12F182135F92FB90843BB1080D3BE8\nSHA-224: 891CFB544EB6F3C212190705F7229D91DB6CECD4718EA65E0FA1B112\nSHA-256: DD679C0B9FD408A04148AA7D30C9DF393F67B7227F65693FFFE0ED6D0F0ADE59\nSHA-384: 0D83489095F455E4EF5186F2B071AB28E0D06132ABC9050B683DA28A463697AD\n         1195FF77F050F20AFBD3D5101DF18C0D\nSHA-512: 0F9F88EE4FA40D2135F98B839F601F227B4710F00C8BC48FDE78FF3333BD17E4\n         1D80AF9FE6FD68515A5F5F91E83E87DE3C33F899661066B638DB505C9CC0153D\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

这是我使用的程序。请务必指定宽字符串的长度。如果不这样做(并使用-1长度),则将WideCharToMultiByte在计算中包括终止 ASCII-Z。由于我们使用的是std::string,因此我们不需要该函数包含 ASCII-Z 终止符。

\n\n
int main(int argc, char* argv[])\n{\n    wstring m1 = L"\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82"; string m2;\n\n    int req = WideCharToMultiByte(CP_UTF8, 0, m1.c_str(), (int)m1.length(), NULL, 0, NULL, NULL);\n    if(req < 0 || req == 0)\n        throw runtime_error("Failed to convert string");\n\n    m2.resize((size_t)req);\n\n    int cch = WideCharToMultiByte(CP_UTF8, 0, m1.c_str(), (int)m1.length(), &m2[0], (int)m2.length(), NULL, NULL);\n    if(cch < 0 || cch == 0)\n        throw runtime_error("Failed to convert string");\n\n    // Should not be required\n    m2.resize((size_t)cch);\n\n    string s1, s2, s3, s4, s5;\n    SHA1 sha1; SHA224 sha224; SHA256 sha256; SHA384 sha384; SHA512 sha512;\n\n    HashFilter f1(sha1, new HexEncoder(new StringSink(s1)));\n    HashFilter f2(sha224, new HexEncoder(new StringSink(s2)));\n    HashFilter f3(sha256, new HexEncoder(new StringSink(s3)));\n    HashFilter f4(sha384, new HexEncoder(new StringSink(s4)));\n    HashFilter f5(sha512, new HexEncoder(new StringSink(s5)));\n\n    ChannelSwitch cs;\n    cs.AddDefaultRoute(f1);\n    cs.AddDefaultRoute(f2);\n    cs.AddDefaultRoute(f3);\n    cs.AddDefaultRoute(f4);\n    cs.AddDefaultRoute(f5);\n\n    StringSource ss(m2, true /*pumpAll*/, new Redirector(cs));\n\n    cout << "SHA-1:   " << s1 << endl;\n    cout << "SHA-224: " << s2 << endl;\n    cout << "SHA-256: " << s3 << endl;\n    cout << "SHA-384: " << s4 << endl;\n    cout << "SHA-512: " << s5 << endl;\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n