如何在C语言中对两个字符数组进行按位异或运算?

12

我感到很傻,因为我无法弄清楚这个问题,我迷失了方向。我正在尝试对两个C字符串进行异或操作。

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
int main()
{
    char plainone[16]; 
    char plaintwo[16];
    char xor[17];
    strcpy(plainone, "PlainOne");
    strcpy(plaintwo, "PlainTwo");
    int i=0;
    for(i=0; i<strlen(plainone);i++)
        xor[i] ^= (char)(plainone[i] ^ plaintwo[i]);
    printf("PlainText One: %s\nPlainText Two: %s\n\none^two: %s\n", plainone, plaintwo, xor);
    return 0;
}

我的输出是:

$ ./a.out 
PlainText One: PlainOne
PlainText Two: PlainTwo

one^two: 

为什么异或数组没有任何含义?


2
  1. xor 是垃圾,我确定你是想要直接赋值。
  2. P ^ P = 0 或 \0,表示字符串的结尾。
- Joe
2
不要在for循环中反复调用strlen。将长度存储在一个变量中并使用它。 - phuclv
2个回答

13

一旦你涉及到XOR操作,你就会涉及到可能不是可打印ASCII字符的二进制字节。

当你用相同的字符进行XOR运算时,你会得到一个0。所以'P' ^ 'P'将会是0。那是一个NUL字节,它终止了字符串。如果你尝试使用printf()打印, 你将什么也看不到;printf()认为这个字符串是一个长度为0的已终止字符串。

另外,你应该简单地使用=将XOR结果分配到目标缓冲区中,而不是像你的程序使用^=

以下是我改良版本的程序以及输出:

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#define LENGTH 16
int main()
{
    char const plainone[LENGTH] = "PlainOne";
    char const plaintwo[LENGTH] = "PlainTwo";
    char xor[LENGTH];
    int i;

    for(i=0; i<LENGTH; ++i)
        xor[i] = (char)(plainone[i] ^ plaintwo[i]);
    printf("PlainText One: %s\nPlainText Two: %s\n\none^two: ", plainone, plaintwo);
    for(i=0; i<LENGTH; ++i)
        printf("%02X ", xor[i]);
    printf("\n");
    return 0;
}

输出:

PlainText One: PlainOne
PlainText Two: PlainTwo

one^two: 00 00 00 00 00 1B 19 0A 00 00 00 00 00 00 00 00

请注意,前五个字节全部为00,因为PlainPlain进行了XOR操作。


为什么使用(char)(plainone[i] ^ plaintwo[i])比plainone[i] ^= plaintwo[i]更好? - bielu000
1
@bielu000 我将 plainone 声明为 const,并编写了程序以保留 plainoneplaintwo,将结果放入名为 xor 的单独数组中。如果您更改了 plainone 的声明使其不是 const,并且您不关心在执行 XOR 操作后能否打印未修改的原始值,则 plainone[i] ^= plaintwo[i] 将是可以的。 - steveha

2

当 "Plain" xor "Plain" == 00000 时,其中 0 是终止字符。C 字符串打印到终止字符为止,这意味着它不会打印任何内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接