简体   繁体   English

如何在C#中对两个字符串进行XOR?

[英]How to XOR two strings in C#?

I am making a programme to encrypt a message using a vegnier cypher. 我正在制作一个使用植物密码对邮件进行加密的程序。 But i am not sure what is wrong with it as when I xor the two variables it just outputs a question mark in a box any help will be appreciated. 但是我不确定这是什么问题,因为当我对两个变量进行异或运算时,它只会在一个方框中输出一个问号,将不胜感激。

    static string xor(string plaintext, string pad)
    {
        string cyphertext = "";
        for (int i = 0; i < (plaintext.Length); i++)
        {
            char p1 = Convert.ToChar(plaintext.Substring(i, 1));
            char c1 = Convert.ToChar(pad.Substring(i, 1));
            char ct1 = (char)(p1 ^ c1);
            cyphertext = cyphertext + (Convert.ToString(ct1));

        }
        return cyphertext;
    }

The code itself is likely working, the problem you are having is not all valid values for a char are printable characters. 代码本身很可能起作用,您遇到的问题不是char所有有效值都是可打印的字符。 When you XOR the values you end up with a char that represents character that is unprintable for the console. 对值进行XOR运算时,最终会得到一个char ,该char表示控制台无法打印的字符。

Since resultant characters can well be unprintable (eg 'A' ^ 'A' == '\\0' - LB example in the comments) I suggest encoding when outputing the encrypted string on the console. 由于结果字符很可能是无法打印的 (例如'A' ^ 'A' == '\\0' 0'-注释中的LB示例),我建议在控制台上输出加密字符串时进行编码 The routing itself: 路由本身:

static string xor(string plaintext, string pad) {
  // check for null, empty strings etc.
  if (String.IsNullOrEmpty(plaintext) || String.IsNullOrEmpty(pad))
    return plaintext;

  // Do not append string in the loop; use StringBuilder for this
  StringBuilder cyphertext = new StringBuilder(plaintext.Length);

  // You have no need in SubString and other stuff: just char xor char
  // i % pad.Length - if pad is shorter than plaintext
  for (int i = 0; i < plaintext.Length; ++i) 
    cyphertext.Append((char) (plaintext[i] ^ pad[i % pad.Length]));

  return cyphertext.ToString();
}

To show the text on the console let's represent each character as its unicode value c => ((int) c).ToString("x4") : 为了在控制台上显示文本,让我们将每个字符表示为其unicode值c => ((int) c).ToString("x4")

string test = "Quick brown fox";
string pad = "Pad";

Console.Write(string.Join(" ", xor(test, pad).Select(c => ((int) c).ToString("x4"))));

The output is 输出是

0001 0014 000d 0033 000a 0044 0032 0013 000b 0027 000f 0001 0014 000d 0033 000a 0044 0032 0013 000b 0027 000f

Please, notice command characters 请注意命令字符

A single xor function would be enough when working with byte arrays, but if you want get a printable result you can use more intelligent codes.... 使用字节数组时,单个xor函数就足够了,但是如果您想获得可打印的结果,则可以使用更智能的代码。

var encstr = Enc("MyTextToHide", "MyKey");
var decstr = Dec(encstr, "MyKey");

static string Enc(string plaintext, string pad)
{
    var data = Encoding.UTF8.GetBytes(plaintext);
    var key = Encoding.UTF8.GetBytes(pad);

    return Convert.ToBase64String(data.Select((b, i) => (byte)(b ^ key[i % key.Length])).ToArray());
}

static string Dec(string enctext, string pad)
{
    var data = Convert.FromBase64String(enctext);
    var key = Encoding.UTF8.GetBytes(pad);

    return Encoding.UTF8.GetString(data.Select((b, i) => (byte)(b ^ key[i % key.Length])).ToArray());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM