2010-03-28 3 views
9

Ich schrieb diesen Code in C# einen String mit einem Schlüssel zu verschlüsseln:Helfen Sie mir mit XOR-Verschlüsselung

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

Das Problem ist, dass ich Fehler immer, wenn ich einen verschlüsselten Text mit diesem Code entschlüsseln mag:

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

Irgendwelche Hinweise?

+1

Alle entschlüsseln ich sagen kann, ist, nicht wahr? :) Vielleicht ist es eine lehrreiche Übung, aber Sie müssen die Zeichen nicht in Zeichenketten umwandeln, oder sie manuell konvertieren und sie dann wieder in eine Zeichenkette konvertieren. Wie durch Ihre Dec2Bin- und Bin2Dec-Funktionen bewiesen, kann char in und von ints mit Umwandlungen konvertiert werden, also nehmen Sie einfach Zeichen aus beiden Zeichenfolgen, wenden Sie den '^' xor-Operator an und fügen Sie eine neue Zeichenfolge ein. – tyranid

+0

Es wäre hilfreich, wenn Sie angeben, welcher Fehler Sie bekommen :) –

+0

Sie können auch StringBuilders anstelle von Strings verwenden. Strings sind unveränderlich (sie können nicht geändert werden), also Dinge wie _str + = _temp; erzeugt jedes Mal eine neue Zeichenfolge, was diese Methode unnötig schwer/teuer macht. Verwenden Sie einen StringBuilder und .Append (temp). –

Antwort

44

Wenn Sie ein Zeichen haben, char, können Sie es in eine ganze Zahl umwandeln, eine int.

Und dann können Sie den Operator ^ verwenden, um XOR darauf durchzuführen. Sie scheinen diesen Operator im Moment nicht zu verwenden, was die Ursache Ihres Problems sein könnte.

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

Diese Art von Sache. Hier ist eine längere Version mit Kommentaren, die die gleiche Sache in den Schritten tun, um es einfacher zu lernen:

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

Die kurze Version ist die gleiche, aber mit den Zwischenvariablen entfernt, Ausdrücke ersetzt direkt in wo sie sind benutzt. Hier

1

ist einige einfachen Code zu verschlüsseln und

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

Die Entschlüsselungsfunktion scheitert an a String mit einem Großbuchstaben drin. irgendwelche Updates für diese Funktion? – pithhelmet