【问题标题】:How do I convert this code to c++?如何将此代码转换为 C++?
【发布时间】:2010-09-14 07:46:38
【问题描述】:

我有这个代码:

    string get_md5sum(unsigned char* md) {
        char buf[MD5_DIGEST_LENGTH + MD5_DIGEST_LENGTH];
        char *bptr;
        bptr = buf;
        for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
                bptr += sprintf(bptr, "%02x", md[i]);
        }
        bptr += '\0';
        string x(buf);
        return x;
}

不幸的是,这是一些 C 与一些 C++ 的结合。它确实可以编译,但我不喜欢 printf 和 char*。我一直认为这在 C++ 中没有必要,并且还有其他函数和类来实现这一点。但是,我不完全理解这是怎么回事:

 bptr += sprintf(bptr, "%02x", md[i]);

因此我不知道如何将其转换为 C++。有人可以帮我解决这个问题吗?

【问题讨论】:

  • 这里潜伏着一个非常危险的“off-by-one”错误。 buf 的大小应为 MD5_DIGEST_LENGTH + MD5_DIGEST_LENGTH + 1 以说明 sprintf 插入的终止 NUL。我不知道这与 C++ 有何对应关系。
  • 请注意,*bptr += '\0'; 将插入相同的尾随 \0。当前语句bptr += '\0'; 也是无操作的。真的,这是一行中的两个错误。

标签: c++ c printf


【解决方案1】:

sprintf 返回写入的字节数。所以这个写入bptr 两个字节(md[i] 的值转换为%02x -> 这意味着十六进制,从左边用零填充 2 个字符),并将bptr 增加写入的字节数,所以它字符串 (buf) 结束处的点。

我没有收到 bptr += '\0'; 行,IMO 应该是 *bptr = '\0';

在 C++ 中应该这样写:

using namespace std;
stringstream buf;
for(int i = 0; i < MD5_DIGEST_LENGTH; i++)
{
    buf << hex << setfill('0') << setw(2) << static_cast<int>(static_cast<unsigned char>(md[i])); 
}
return buf.str();

编辑:更新了我的 C++ 答案

【讨论】:

  • 我同意。它将两个字节写入 bptr 并将 bptr 推进两个字节。下一行bptr += '\0'; 似乎没有意义。我认为它将 0 添加到 bptr,而不是附加一个 nul 字符。你怎么看?
  • 哦,那太愚蠢了。我记得以前的 C 和 C++ 书籍中的 \0。我几乎不需要使用它,因为我通常使用 Qt 和 .NET 等库。我想我在某个地方添加了它,希望我正在做一些事情来创建一个好的 char 数组。
  • 我真的需要每次写入两个字节还是可以一次将整个数组写入一个字符串? unsigned char* 由 openssl 填充: unsigned char* tmp = MD5((unsigned char*) buffer, length, result);
  • 通过尝试编译你的答案,我得到了这个:md5.cpp: In function 'std::string get_md5sum(unsigned char*)': md5.cpp:24:25: error: no调用 'fill(char)' md5.cpp:24:37 的匹配函数:错误:'width' 未在此范围内声明
  • md[i] 已经是一个无符号字符,冗余转换。我只想写int(md[i]); C++ 构造函数样式转换。
【解决方案2】:
bptr += sprintf(bptr, "%02x", md[i]);

这会将 md[i] 中的字符作为 2 个十六进制字符打印到缓冲区中,并将缓冲区指针推进 2。因此循环打印出 MD5 的十六进制形式。

bptr += '\0';

那条线可能没有做你想做的事……它给指针加了0,给你同样的指针……

我会像这样实现这个。

string get_md5sum(unsigned char* md) {
        static const char[] hexdigits="0123456789ABCDEF";
        char buf[ 2*MD5_DIGEST_LENGTH ];
        for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
                bptr[2*i+0] = hexdigits[ md[i] / 16 ];
                bptr[2*i+1] = hexdigits[ md[i] % 16 ];
        }
        return string(buf,2*MD5_DIGEST_LENGTH );
}

【讨论】:

    【解决方案3】:

    我不懂 C++,所以不使用指针和字符串之类的东西,这里有一个(几乎)伪代码给你 :)

        for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
                buf[i*2] = hexdigits[(md[i] & 0xF0) >> 4];
                buf[i*2 + 1] = hexdigits[md[i] & 0x0F];
        }
    

    【讨论】:

    • 为什么要发布与 Michael 几乎相同(但不太完整)的解决方案?为什么要以“我不知道 C++”来回答专门要求 C++ 解决方案的问题。你只是希望幸运吗?
    • 我在发布我的帖子时没有看到迈克尔的答案,并且在我发布我的帖子时没有其他没有指针的答案(这对原始海报来说似乎有问题)。不知道C++ 并不妨碍人们解释C 是如何工作的。
    • 不知道C++ 只会阻止您回答最初的问题,'如何将此代码转换为 c++?'。无论如何,很抱歉抱怨您的解决方案与迈克尔的解决方案几乎相同,我猜hexdigits[] 让它看起来像一个副本,因为它不是原始代码中的名称,但它存在于迈克尔的解决方案中。
    • 不用担心......现在我想得更好了,迈克尔已经提供了他的答案,而 hexdigit 的东西是他的副本;但他的代码中有指针算法而不是索引 (2*i+1)。
    猜你喜欢
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 2019-09-29
    • 2011-12-08
    • 2021-12-24
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多