Adi*_*Aji 2 c# encryption caesar-cipher
我正在尝试在C#中加密字符串:
static public string Encrypt(char[] a)
{
for (int i = 0; i < a.Length; i++)
{
a[i] -= (char)(i + 1);
if (a[i] < '!')
{
a[i] += (char)(i + 20);
}
}
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
现在,当我输入这个字符串时:
"Qui habite dans un ananas sous la mer?".
Run Code Online (Sandbox Code Playgroud)
加密结果如下:
`Psf3c[[ak[3XT`d3d\3MYKWIZ3XSXU3L@?JAMR`
Run Code Online (Sandbox Code Playgroud)
在@之后,那里有一个无法辨认的角色.我不知道它是怎么到达的,我不知道为什么.
如果我尝试解密它(使用这种方法:)
static public string Decrypt(char[] a)
{
for (int i = 0; i < a.Length; i++)
{
a[i] += (char)(i + 1);
if ((a[i] - 20) - i <= '!')
{
a[i] -= (char)(i + 20);
}
}
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
这是(不正确的)输出:
Qui habite dans un ananas sous laamerx.
如何允许加密例程访问unicode字符?
你获得一个不可打印的角色的原因是这一行:
a[i] -= (char)(i + 1);
Run Code Online (Sandbox Code Playgroud)
发生的事情是你的内部空间la mer是字符串的第34个位置,空格的等效整数值是0x20 = 32.这意味着当你减去(i+1)你得到-2时.但是你将结果存储在a中char,这是一个无符号类型,所以这实际上变成0xFFFE = 65534.然后当你测试时a[i] < '!'你得到假,因为a[i]现在是一个大的正数.
相反,你应该做什么(如果你真的想要实现这个算法)是将结果存储在有符号的类型中,并在你做的时候操纵它,然后在最后将它转换为char.
int value = (int)a[i] - (i + 1);
if (value < (int)'!')
{
value += i + 20;
}
a[i] = (char)value;
Run Code Online (Sandbox Code Playgroud)
(强调额外的类型演员.)
它可能没有必要,但我建议在Decrypt方法中使用相同的模式.通常更容易推理出适用于临时变量的代码,而不是编辑适当的东西.