如何理解代码

Joa*_*dro -8 c

我最近得到了这个代码,我很难理解.我对整体编程很新,我还在学习.任何有关这方面的信息将不胜感激.这是出现的代码:

void enc(char* plaintxt, unsigned char key) 
{ 
    while(*plaintxt)
    { 
        *plaintxt^ = (key=(key*13)+37);
        *(plaintxt++) +=3;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

0F A8 9F FE 7A D6 E2 08 AE 2B 5F 53 25 9A
Run Code Online (Sandbox Code Playgroud)

Joh*_*ode 6

了解您的具体问题会有所帮助.

简而言之,此代码使用字符串并使用键值对其进行加密/编码.这条线

*plaintxt^ = (key=(key*13)+37);
Run Code Online (Sandbox Code Playgroud)

是一种非常密集的写作方式

*plaintxt = *plaintxt ^ (key * 13 + 37);
key = key * 13 + 37;
Run Code Online (Sandbox Code Playgroud)

与在其中的确切顺序的警告key*plaintxt未指定被更新时(IOW,在原码key可被之前或之后更新*plaintxt被更新).

^操作者是按位XOR运算符; 每个位*plaintext都与每个位进行异或key.

这条线

 *(plaintxt++) +=3;
Run Code Online (Sandbox Code Playgroud)

是一种密集的写作方式

 *plaintxt = *plaintxt + 3;
 plaintxt = plaintxt + 1;
Run Code Online (Sandbox Code Playgroud)

同样需要注意的是,未指定更新*plaintxtplaintxt更新的确切顺序.这条线被添加3*plaintext,然后推进指针指向该串中的下一个字符.

在C中,字符串是由a终止的字符值序列0. plaintext是指向字符串第一个字符的指针.该while循环检查,看看我们有没有通过测试的值达到字符串的结束*plaintxt; while ( *plaintext )是一样的while ( *plaintext != 0 ).

所以,我们假设plaintext指向字符串"test"1:

           +---+              +----+
plaintext: |   | ----> "test" | 74 |    Assumes ASCII, all values in hex
           +---+              +----+
                              | 65 |
           +----+             +----+
      key: |  1 |             | 75 |
           +----+             +----+
                              | 74 |
                              +----+
                              |  0 |
                              +----+
Run Code Online (Sandbox Code Playgroud)

key最初是1.

在循环的开始,plaintext指向第一个t"test"(ASCII 0x74).我们使用key * 13 + 37十进制的50或十六进制的0x32 的结果对此进行异或运算:

  0x74 ^ 0x32 == 0x46
Run Code Online (Sandbox Code Playgroud)

我们将这个值写回*plaintext,然后向它添加3,给我们0x49.我们将0x32保存到key.然后我们前进plaintext到指向字符串中的下一个字符,给我们:

           +---+              +----+
plaintext: |   | --+   "Iest" | 49 |    
           +---+   |          +----+
                   +------->  | 65 |
           +----+             +----+
      key: | 32 |             | 75 |
           +----+             +----+
                              | 74 |
                              +----+
                              |  0 |
                              +----+
Run Code Online (Sandbox Code Playgroud)

现在我们做同样的事情e:

key = 50 * 13 + 37 == 687 % 255 == 177 == 0xb1
Run Code Online (Sandbox Code Playgroud)

unsigned char只能存储0到2 CHAR_BIT -1的值,大多数现代系统中的值为255; 687太大而无法存储key,所以它"回绕"回到177或0xb1 2.

0x65 ^ 0xb1 == 0xd4
0xd4 + 3    == 0xd7
Run Code Online (Sandbox Code Playgroud)

完成所有这些之后,我们有了

           +---+              +----+
plaintext: |   | --+   "I?st" | 49 |    
           +---+   |          +----+
                   |          | d7 |  
           +----+  |          +----+
      key: | b1 |  +--------> | 75 |
           +----+             +----+
                              | 74 |
                              +----+
                              |  0 |
                              +----+
Run Code Online (Sandbox Code Playgroud)

泡沫,冲洗,重复.这将持续到plaintext指向包含0的存储器单元.


  1. 从技术上讲,它指向一个包含字符串"test" 的数组,而不是字符串文字 `"test"`.字符串文字可能没有修改其内容; 尝试这样做会调用未定义的行为.
  2. 这仅适用于无符号整数类型; 有符号整数类型的溢出没有明确定义,并且可能无法按预期运行.