Ternick
@Ternick

Почему не получается переписать функцию под С++?

КОД C#:

using System;
using System.Security.Cryptography;
using System.Text;


namespace Test___
{
    class Program
    {
        static void Main()
        {
            string s = "876c0e09-70f7-4190-ab3a-254b6e5f461e";
            byte[] hash = new MD5CryptoServiceProvider().ComputeHash(Encoding.Unicode.GetBytes(s));
            StringBuilder sb = new StringBuilder();
            foreach (var b in hash)
            {
                sb.Append(b);
            }
            string outVAR = sb.ToString();
            Console.WriteLine(outVAR);

        }
    }
}

РЕЗУЛЬТАТ C#:
2093211110720710915549134413018604013480

КОД C++:

#include <iostream>
#include <Windows.h>
#include <cstdint>
#include <string>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include "MD5.h"

using namespace std;

string ToBytes(string str) {
	string result;
	for (int i = 0; i < str.size(); i++) {
		result += to_string((int)str[i]) + "0";
	}
	return result;
}

string stringToHex(const string& in) {
	stringstream ss;
	ss << hex << setfill('0');
	for (size_t i = 0; in.length() > i; ++i) {
		ss << setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(in[i]));
	}
	return ss.str();
}

int main() {
	string hash = md5(ToBytes("876c0e09-70f7-4190-ab3a-254b6e5f461e"));
	cout << stringToHex(hash) << endl;
	system("pause");
}

РЕЗУЛЬТАТ C++:
6365643235323261643366386639366333363963353765626135633736366565


БЫЛ ТУТ:
ТЫК
Написано что вроде всё должно работать, но у меня ничего не получается :)
  • Вопрос задан
  • 199 просмотров
Решения вопроса 1
SerJook
@SerJook
кодер
По-моему оба варианта функции какие-то странные.
Если вам нужно шестнадцатеричное представление, то на C# это будет примерно так:

string s = "876c0e09-70f7-4190-ab3a-254b6e5f461e";
byte[] data = Encoding.Unicode.GetBytes(s);
byte[] hash = new MD5CryptoServiceProvider().ComputeHash(data);
StringBuilder sb = new StringBuilder();
foreach (var b in hash)
{
   sb.Append(b.ToString("x2"));
}
string outVAR = sb.ToString();
Console.WriteLine(outVAR);


а на c++ так:
string ToBytes(const wstring& str) {
    const char* d = reinterpret_cast<const char*>(&str[0]);
    string result(d, d+str.size()*2);
    return result;
}

int main() {
    wstring data = L"876c0e09-70f7-4190-ab3a-254b6e5f461e"; // на винде это будет UTF-16 строка, как и в C#
    cout << md5(ToBytes(data)) << endl;
    system("pause");
}


результат будет одинаков (по крайней мере на винде)

d1206f6bcf6d9b31860482123c288650

Но если вам прям так нужен результат точь-в-точь как в C#, то попробуйте этот код:

spoiler
std::string WinMD5(const void * data, const size_t data_size)
{
    HCRYPTPROV hProv = NULL;

    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        return std::string();
    }

    HCRYPTPROV hHash = NULL;
    BOOL hash_ok = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
   

    if (!hash_ok) {
        CryptReleaseContext(hProv, 0);
        return std::string();
    }

    if (!CryptHashData(hHash, static_cast<const BYTE *>(data), static_cast<DWORD>(data_size), 0)) {
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        return std::string();
    }

    DWORD cbHashSize = 0, dwCount = sizeof(DWORD);
    if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize, &dwCount, 0)) {
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        return std::string();
    }

    std::vector<BYTE> buffer(cbHashSize);
    if (!CryptGetHashParam(hHash, HP_HASHVAL, reinterpret_cast<BYTE*>(&buffer[0]), &cbHashSize, 0)) {
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        return std::string();
    }

    std::ostringstream oss;

    for (auto item: buffer) {
        oss << static_cast<unsigned int>(item);
    }

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    return oss.str();
}

string ToBytes(const wstring& str) {
    const char* d = reinterpret_cast<const char*>(&str[0]);
    string result(d, d+str.size()*2);
    return result;
}


int main() {
    wstring data = L"876c0e09-70f7-4190-ab3a-254b6e5f461e";
    cout << WinMD5(data.data(), data.size()* sizeof(wchar_t));
    system("pause");
}



результат:
2093211110720710915549134413018604013480
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
ToBytes делает что-то не то.
Оба ответа не похожи на правду. Попробуйте воспользоваться любым онлайн калькулятором md5 для проверки.
www.zedwood.com/article/cpp-md5-function этой штукой можно сразу получить ответ.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы