【发布时间】:2011-02-01 17:23:35
【问题描述】:
我在C# 中写了这段代码来用一个密钥加密一个字符串:
private static int Bin2Dec(string num)
{
int _num = 0;
for (int i = 0; i < num.Length; i++)
_num += (int)Math.Pow(2, num.Length - i - 1) * int.Parse(num[i].ToString());
return _num;
}
private static string Dec2Bin(int num)
{
if (num < 2) return num.ToString();
return Dec2Bin(num / 2) + (num % 2).ToString();
}
public static string StrXor(string str, string key)
{
string _str = "";
string _key = "";
string _xorStr = "";
string _temp = "";
for (int i = 0; i < str.Length; i++)
{
_temp = Dec2Bin(str[i]);
for (int j = 0; j < 8 - _temp.Length + 1; j++)
_temp = '0' + _temp;
_str += _temp;
}
for (int i = 0; i < key.Length; i++)
{
_temp = Dec2Bin(key[i]);
for (int j = 0; j < 8 - _temp.Length + 1; j++)
_temp = '0' + _temp;
_key += _temp;
}
while (_key.Length < _str.Length) _key += _key;
if (_key.Length > _str.Length) _key = _key.Substring(0, _str.Length);
for (int i = 0; i < _str.Length; i++)
if (_str[i] == _key[i]) { _xorStr += '0'; } else { _xorStr += '1'; }
_str = "";
for (int i = 0; i < _xorStr.Length; i += 8)
{
char _chr = (char)0;
_chr = (char)Bin2Dec(_xorStr.Substring(i, 8)); //ERROR : (Index and length must refer to a location within the string. Parameter name: length)
_str += _chr;
}
return _str;
}
问题是当我想用这段代码解密加密文本时总是出错:
string enc_text = ENCRYPT.XORENC("abc","a"); // enc_text = " ♥☻"
string dec_text = ENCRYPT.XORENC(enc_text,"a"); // ArgumentOutOfRangeException
有什么线索吗?
【问题讨论】:
-
我只能说是吧? :) 也许这是一个教育练习,但您不需要将字符转换为字符串,手动对它们进行异或然后将它们转换回字符串。正如您的 Dec2Bin 和 Bin2Dec 函数所证明的那样,char 可以通过强制转换与 int 相互转换,因此只需从两个字符串中获取 char,应用 '^' xor 运算符并放入新字符串。
-
如果您指定遇到的错误会有所帮助:)
-
另外,您可能希望使用 StringBuilders 而不是 Strings。字符串是不可变的(不能更改),所以像 _str += _temp;每次都会生成一个新字符串,这使得这种方法不必要地繁重/昂贵。使用 StringBuilder 和 .Append(temp)。
-
@Michael Stum:事实证明,StringBuilder 实际上可以更慢,或者与使用串联差不多。 StringBuilder 仅适用于大字符串。
-
@siride 它可能会更慢,但这主要是为了琐碎的连接(我认为是 3-4 个字符串)。在他的情况下,循环是不确定的,因为它取决于输入字符串的长度,所以使用 SB 是一个更安全的选择(当然,如果使用像 str.Length 这样的合理缓冲区大小来初始化它)
标签: c# encryption encryption-symmetric