我正在制作一个使用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;
}
答案 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());
}