c ++将带有“:”的十六进制字符串转换为原始的“二进制”字符串

时间:2015-06-04 01:42:01

标签: c++ encryption

我有以下代码将加密的密文转换为可读的十六进制格式:

std::string convertToReadable(std::string ciphertext)
{
    std::stringstream outText;

    for(unsigned int i = 0; i < ciphertext.size(); i++ )
        outText << std::hex << std::setw(2) << std::setfill('0') << (0xFF & static_cast<byte>(ciphertext[i])) << ":";

    return outText.str();
}

此功能的可读结果如下:

56:5e:8b:a8:04:93:e2:f1:5c:20:8b:fd:f5:b7:22:0b:82:42:46:58:9b:d4:c1:8e:ac:62:85:04:ff:7f:c6:d3:

现在我需要回过头来,将可读格式转换为原始ciphertext以便解密它:

std::string convertFromReadable(std::string text)
{
    std::istringstream cipherStream;

    for(unsigned int i = 0; i < text.size(); i++ )
    {
        if (text.substr(i, 1) == ":")
            continue;

        std::string str = text.substr(i, 2);
        std::istringstream buffer(str);
        int value;
        buffer >> std::hex >> value;
        cipherStream << value;
    }

    return cipherStream.str();
}

这不是绝对有效的,因为我收到了错误的字符串。

如何修复convertFromReadable()以便我可以恢复原来的ciphertext

感谢您的帮助

2 个答案:

答案 0 :(得分:5)

以下是在进一步调试之前应该修复的问题:

  • Device.BeginInvokeOnMainThread( () => { label.Text = i.ToString(); }); 应该是cipherStream,而不是ostringstream
  • istringstream循环应在结束前停止两个字符。否则你的for将会失败。制作循环条件substr
  • 当您从输入中读取两个字符时,您需要将i+2 < text.size()提前两位,即在i行之后添加i++
  • 由于您需要字符输出,因此在将数据写入std::string str = text.substr(i, 2);时向char添加强制转换,即cipherStream

答案 1 :(得分:1)

您的代码正常运行。刚想我会用一个稍微简单,更直接的方法来说明没有繁琐的索引跟踪和子提取的流:

std::string convertFromReadable(const std::string& text)
{
    std::istringstream iss(text);
    std::ostringstream cipherStream;
    int n;
    while (iss >> std::hex >> n)
    {
        cipherStream << (char)n;
        // if there's another character it better be ':'
        char c;
        if (iss >> c && c != ':')
            throw std::runtime_error("invalid character in cipher");
    }
    return cipherStream.str();
}

请注意,在最后一个十六进制值之后,如果没有冒号,if (iss >> c...测试将评估falsewhile (iss >> ...测试将会评估,然后返回。