0

最近我试图使用此代码从字符串生成 MD5。

string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
    unsigned char result[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)data.c_str(), data.size(), result);

    std::ostringstream sout;
    sout<<std::hex<<std::setfill('0');
    for(long long c: result)
    {
        sout<<std::setw(2)<<(long long)c;
    }
    return sout.str();
}

但是,我使用的编译器不支持基于范围的 for 循环,我尝试for(...;...;...)使用下面提供的代码将此代码转换为传统循环。

string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
    unsigned char result[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)data.c_str(), data.size(), result);

    std::ostringstream sout;
    sout<<std::hex<<std::setfill('0');
    for(long long c; c<sizeof(result); c++) // long long c: result
    {
        sout<<std::setw(2)<<(long long)c;
    }
    return sout.str();
}

什么时候,我测试它不起作用,因为我得到一个空字符串。我很难找到错误所在。我应该如何用传统的 for 循环重新实现第一个代码?

4

4 回答 4

3

在这里,您使用c未初始化并开始单步执行。这会导致未定义的行为:

for(long long c; c<sizeof(result); c++) 

这应该这样做:

for(size_t i = 0; i < MD5_DIGEST_LENGTH; ++i) {
    sout << std::setw(2) << (unsigned) result[i];
}
于 2019-10-28T19:45:10.663 回答
3

当你有

for(long long c: result)
{
    sout<<std::setw(2)<<(long long)c;
}

for(long long c: result)说:对于每个元素,将其result分配给long long名为的类型的变量c。然后循环体使用c. 要在常规 for 循环中获得相同的行为,您需要做同样的事情。告诉编译器循环遍历您需要的所有元素

for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)

您可以直接在循环中使用元素,而不是创建变量。那看起来像

sout<<std::setw(2)<<(long long)result[index_of_element];

并将它们结合在一起你得到

for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
{
    sout<<std::setw(2)<<(long long)result[i];
}
于 2019-10-28T19:45:10.970 回答
0

问题是您没有初始化 c 并且您没有在任何地方引用结果数组

for(long long c = 0; /*Initialize*/ c<sizeof(result); c++) // long long c: result
{
  //use result[c]
}
于 2019-10-28T19:46:44.683 回答
0

使用MD5_DIGEST_LENGTH而不是sizeof(result). 我认为“c”没有初始值0。

于 2019-10-28T19:48:13.923 回答