c++ 将带有“:”的十六进制字符串转换为原始"binary"字符串
c++ convert hexadecimal string with ":" to original "binary" string
我有以下代码可以将加密的密文转换为可读的十六进制格式:
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
?
感谢您的帮助
在进一步调试之前,您应该解决以下问题:
cipherStream
应该是 ostringstream
,而不是 istringstream
for
循环应该在结束前停止两个字符。否则你的 substr
将会失败。使循环条件i+2 < text.size()
- 当您从输入中读取两个字符时,您需要将
i
提前两个,即在 std::string str = text.substr(i, 2);
行之后添加 i++
。
- 因为要字符输出,所以在写数据到
cipherStream
的时候加一个cast到char
,即cipherStream << (char)value
很好,您的代码可以正常工作了。只是想我会说明一种使用流的稍微简单、更直接的方法,而无需繁琐的索引跟踪和子字符串提取:
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...
测试将评估 false
,while (iss >> ...
测试也会评估,一直到 return。
我有以下代码可以将加密的密文转换为可读的十六进制格式:
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
?
感谢您的帮助
在进一步调试之前,您应该解决以下问题:
cipherStream
应该是ostringstream
,而不是istringstream
for
循环应该在结束前停止两个字符。否则你的substr
将会失败。使循环条件i+2 < text.size()
- 当您从输入中读取两个字符时,您需要将
i
提前两个,即在std::string str = text.substr(i, 2);
行之后添加i++
。 - 因为要字符输出,所以在写数据到
cipherStream
的时候加一个cast到char
,即cipherStream << (char)value
很好,您的代码可以正常工作了。只是想我会说明一种使用流的稍微简单、更直接的方法,而无需繁琐的索引跟踪和子字符串提取:
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...
测试将评估 false
,while (iss >> ...
测试也会评估,一直到 return。