2010-03-28 33 views
9

C#寫了這個代碼加密與密鑰字符串:幫我XOR加密

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

問題是,當我想解密使用此代碼encryted的文字,我總是得到錯誤:

string enc_text = ENCRYPT.XORENC("abc","a"); // enc_text = " ♥☻" 
string dec_text = ENCRYPT.XORENC(enc_text,"a"); // ArgumentOutOfRangeException 

任何線索?

+1

所有我能說的是吧? :)也許這是一個教育練習,但你不需要將字符轉換爲字符串,手動異或然後將它們轉換回字符串。正如你的Dec2Bin和Bin2Dec函數所證明的那樣,char可以通過強制類型轉換爲int,所以只需從兩個字符串中取出char,應用'^'異或運算符並將其放入新字符串中。 – tyranid 2010-03-28 11:25:20

+0

如果你指定了你所得到的錯誤,它會有所幫助:) – 2010-03-28 11:25:32

+0

另外,你可能想用StringBuilders而不是Strings。字符串是不可變的(它們不能被改變),所以像_str + = _temp;每次都會產生一個新的字符串,這使得這種方法不必要的繁重/昂貴。使用StringBuilder和.Append(temp)。 – 2010-03-28 11:28:18

回答

44

如果您有一個字符char,可以將其轉換爲一個整數int

然後您可以使用^運算符對它執行XOR。您目前似乎沒有使用該操作員,這可能是您問題的根源。

string EncryptOrDecrypt(string text, string key) 
{ 
    var result = new StringBuilder(); 

    for (int c = 0; c < text.Length; c++) 
     result.Append((char)((uint)text[c]^(uint)key[c % key.Length])); 

    return result.ToString(); 
} 

那樣的事情。下面是與評論較長的版本,那麼在步驟同樣的事情,以使其更容易借鑑:

string EncryptOrDecrypt(string text, string key) 
{ 
    var result = new StringBuilder(); 

    for (int c = 0; c < text.Length; c++) 
    { 
     // take next character from string 
     char character = text[c]; 

     // cast to a uint 
     uint charCode = (uint)character; 

     // figure out which character to take from the key 
     int keyPosition = c % key.Length; // use modulo to "wrap round" 

     // take the key character 
     char keyChar = key[keyPosition]; 

     // cast it to a uint also 
     uint keyCode = (uint)keyChar; 

     // perform XOR on the two character codes 
     uint combinedCode = charCode^keyCode; 

     // cast back to a char 
     char combinedChar = (char)combinedCode; 

     // add to the result 
     result.Append(combineChar); 
    } 

    return result.ToString(); 
} 

簡短的版本是一樣的,但是去除了中間變量,直接替換表達式到他們那裏用過的。

1

下面是一些簡單的代碼來加密和解密

class CEncryption 
{ 
    public static string Encrypt(string strIn, string strKey) 
    { 
     string sbOut = String.Empty; 
     for (int i = 0; i < strIn.Length; i++) 
     { 
      sbOut += String.Format("{0:00}", strIn[i]^strKey[i % strKey.Length]); 
     } 

     return sbOut; 
    } 

    public static string Decrypt(string strIn, string strKey) 
    { 
     string sbOut = String.Empty; 
     for (int i = 0; i < strIn.Length; i += 2) 
     { 
      byte code = Convert.ToByte(strIn.Substring(i, 2)); 
      sbOut += (char)(code^strKey[(i/2) % strKey.Length]); 
     } 

     return sbOut; 
    } 
} 
+1

解密函數在帶有大寫字母的字符串。此功能的任何更新? – pithhelmet 2012-08-20 23:38:42