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

时间:2016-11-19 21:26:46

标签: c# .net

我正在制作一个使用vegnier cypher加密消息的程序。 但我不确定它有什么问题,因为当我对两个变量进行xor时,它只会在一个框中输出一个问号,任何帮助都将受到赞赏。

    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;
    }

3 个答案:

答案 0 :(得分:1)

代码本身可能正常工作,您遇到的问题并非char的所有有效值都是可打印字符。当您对值进行异或时,最终会得到char,表示对于控制台而言无法打印的字符。

答案 1 :(得分:1)

由于结果字符很可能不可打印(例如评论中的'A' ^ 'A' == '\0' - L.B.示例)我建议编码输出时 控制台上的加密字符串。路由本身:

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();
}

要在控制台上显示文字,我们将每个字符表示为其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"))));

输出

  

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

请注意命令字符

答案 2 :(得分:1)

使用字节数组时,单个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());
}