【问题标题】:Need help encoding C++ strings by increasing ASCII value需要帮助通过增加 ASCII 值来编码 C++ 字符串
【发布时间】:2016-07-01 23:20:51
【问题描述】:

我到处寻找一个 C++ 代码,它接收来自用户的消息,并通过增加每个字符的 ASCII 值对其进行编码(显然不是很安全,但足够简单)。我已经设法组合了一个程序,该程序返回几个值更高的字符,但无法弄清楚如何使用包含空格的完整消息来做到这一点。我计划制作一个之后做相反的解码器。任何帮助将非常感激。提前致谢。

单值 C++ 程序 -

    #include <iostream>
using namespace std;
int main(){
 char ascii;
 cout << "Enter a character: ";
 cin >> ascii;
 cout << "Its ascii value is: " << (int) ascii << endl;
 return 0;
}

VBS 中的工作编码器示例 -

set x = WScript.CreateObject("WScript.Shell") 
entxtde = inputbox("Enter text to be encoded") 

entxtde = StrReverse(entxtde)
x.Run "%windir%\notepad" 
wscript.sleep 1000 
x.sendkeys encode(entxtde) 

function encode(s) 
For i = 1 To Len(s) 
newtxt = Mid(s, i, 1) 
newtxt = Chr(Asc(newtxt)+3) 
coded = coded & newtxt
 Next 
encode = coded 
End Function

【问题讨论】:

标签: c++ string encryption encoding ascii


【解决方案1】:
std::string originalString = "";
std::string newString = "";
int incrementValue = 1;
std::cout << "Input a string to encode: ";
std::cin >> originalString;
for(int i = 0; i < originalString.length(); i++) {
   newString += (originalString.at(i) + incrementValue);
}
std::cout >> "New string is " + newString

只需更改 incrementValue 即可更改其编码方式。 如果 incrementValue = 1,则 "Hello" = "Ifmmp"
要反转它,只需将其更改为减去 incrementValue 而不是添加相同类型的 for 循环。我觉得很简单

【讨论】:

  • 如果originalString.at(i) + incrementValue 大于 255,您的程序将通过异常。您应该将其修改为 255 :)
  • 1) *throw, not through 2) 如果 char 的值超过 255,它将环绕,虽然技术上是未定义的行为
  • 我知道这是未定义的行为;我不知道它通常会换行。不过,异常仍然是一个问题,是吗?
  • 不抛出异常
【解决方案2】:

这可以在一行中完成,如果您希望保持在 80 列以下,则可以在两行中完成。其中value 是您要加密的字符串,offset 是偏移值:

auto caesar = [offset](CharT c){return c + offset;};
std::transform(value.begin(), value.end(), value.begin(), caesar);

对于奖励积分,您可以通过对字符类型进行模板化来使其适用于任何类型的字符串:

template <typename CharT>
std::basic_string<CharT> caesarEncode(std::basic_string<CharT> value, CharT offset){
    auto caesar = [offset](CharT c){return c + offset;};
    std::transform(value.begin(), value.end(), value.begin(), caesar);
    return value;
}

由于您在实际获取带空格的字符串时可能遇到困难,您可以使用标准库的getline 函数来获取,该函数默认获取源流的一整行。

// narrow (CharT = char)
std::string value;
std::getline(std::cin, value);

// wide (CharT = wchar_t)
std::wstring wvalue;
std::getline(std::wcin, wvalue);

实际编码字符串的方式如下:

char offset = 12;
auto encoded = caesarEncode(value, offset);

wchar_t woffset = 12;
auto wencoded = caesarEncode(wvalue, woffset);

您可以在实践中查看示例here on coliru

【讨论】:

    【解决方案3】:

    真的很简单。首先,您将输入作为字符串。然后,按您想要的内容遍历每个添加的字符。为确保该值保持有效且易于反转,您可以将该值修改为 char 的最大值,即 255。

    int main () {
        std::string input; // to store the text
        std::getline(std::cin, input); // get the text
    
        const int _add = 12; // value added
        const int max_size = 255; // max value of a char
        for (int i = 0; i < input.size(); ++i)
            input[i] = (input[i] + _add) % max_size;
        /* now the input is properly modified */
    }
    

    注意:_add 是一个防止溢出错误的 int。

    【讨论】:

    • 在 Visual Studios 中,您可以强制所有字符串变宽。在这种情况下, input.size() 不会返回 char 的长度。
    • 虽然通常没有必要,但不会产生错误的结果。我认为我不应该投反对票:(
    • 老兄,cplusplus 一直是我的参考!它在size() 中说将返回以字节为单位的长度。 cppreference 说你在说什么。我被骗了
    • 好吧,从技术上讲,std::string::size 以字节和代码点为单位,因为它们是相同的。但是 cplusplus 甚至没有提到 wstring 和 basic_string。每个人都会避开那个网站。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    相关资源
    最近更新 更多