2010-03-28 29 views
9

escribí este código en C# para cifrar una cadena con una clave:Ayúdame con el cifrado 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; 
} 

El problema es que siempre me sale error cuando quiero descifrar un texto encryted con este código:

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

¿Alguna pista?

+1

Todo lo que puedo decir es eh? :) Tal vez es un ejercicio educativo, pero no es necesario convertir los caracteres en cadenas, x o manualmente, y luego convertirlos a una cadena. Como lo demuestran las funciones de Dec2Bin y Bin2Dec, char se puede convertir ay desde ints con moldes, así que solo tome char de ambas cuerdas, aplique el operador '^' xor y ponga en una nueva cadena. – tyranid

+0

Ayudaría si especifica qué error está recibiendo :) –

+0

Además, es posible que desee utilizar StringBuilders en lugar de Strings. Las cadenas son inmutables (no se pueden cambiar), por lo que cosas como _str + = _temp; genera una nueva cadena cada vez, lo que hace que este método sea innecesariamente pesado/costoso. Use un StringBuilder y .Append (temp). –

Respuesta

44

Si tiene un carácter, un char, puede convertirlo en un número entero, int.

Y luego puede usar el operador ^ para realizar XOR en él. No parece estar usando ese operador en este momento, que podría ser el origen de su problema.

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

Ese tipo de cosas. Aquí hay una versión más larga con los comentarios que hace lo mismo que en los pasos, para que sea más fácil de aprender a partir de:

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

La versión corta es lo mismo pero con las variables intermedias eliminadas, sustituyendo las expresiones directamente en donde están usado.

1

Aquí hay un código sencillo para cifrar y descifrar

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

La función de descifrado falla cadena con una letra mayúscula en ella. cualquier actualización de esta función? – pithhelmet

Cuestiones relacionadas