了解您的具体问题会有所帮助。
简而言之,此代码采用一个字符串并使用键值对其进行加密/编码。线
*plaintxt^ = (key=(key*13)+37);
是一种非常密集的书写方式
*plaintxt = *plaintxt ^ (key * 13 + 37);
key = key * 13 + 37;
需要注意的是,未指定更新 key 和 *plaintxt 的确切顺序(IOW,在原始代码中 key 可能在 *plaintxt 更新之前或之后更新)。
^ 运算符是按位异或运算符; *plaintext 中的每一位都与 key 中的每一位进行异或运算。
线
*(plaintxt++) +=3;
是一种密集的书写方式
*plaintxt = *plaintxt + 3;
plaintxt = plaintxt + 1;
同样需要注意的是,未指定更新 *plaintxt 和 plaintxt 的确切顺序。此行将3 添加到*plaintext,然后将指针推进以指向字符串中的下一个字符。
在 C 中,字符串是由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 |
+----+
key 最初是 1。
在循环的开始,plaintext 指向"test" 中的第一个t(ASCII 0x74)。我们将其与key * 13 + 37 的结果进行异或,即十进制的 50 或十六进制的 0x32:
0x74 ^ 0x32 == 0x46
我们把这个值写回*plaintext,然后加上3,得到0x49。我们将 0x32 保存到 key。然后我们推进plaintext 指向字符串中的下一个字符,给我们:
+---+ +----+
plaintext: | | --+ "Iest" | 49 |
+---+ | +----+
+-------> | 65 |
+----+ +----+
key: | 32 | | 75 |
+----+ +----+
| 74 |
+----+
| 0 |
+----+
现在我们对 e 做同样的事情:
key = 50 * 13 + 37 == 687 % 255 == 177 == 0xb1
unsigned char 只能存储从 0 到 2CHAR_BIT-1 的值,在大多数现代系统上是 255; 687 太大而无法存储在 key 中,因此它“环绕”回 177 或 0xb12。
0x65 ^ 0xb1 == 0xd4
0xd4 + 3 == 0xd7
所有这些都完成后,我们有
+---+ +----+
plaintext: | | --+ "I?st" | 49 |
+---+ | +----+
| | d7 |
+----+ | +----+
key: | b1 | +--------> | 75 |
+----+ +----+
| 74 |
+----+
| 0 |
+----+
起泡、冲洗、重复。这将一直持续到plaintext 指向包含 0 的内存单元。
- 从技术上讲,它指向一个包含字符串 `"test"` 的 array,而不是 字符串文字 `"test"`。字符串文字可能不会修改其内容;试图这样做会调用未定义的行为。
- 这仅适用于 unsigned 整数类型;有符号整数类型的溢出没有明确定义,并且可能无法按预期运行。