2010-03-28 15 views
9

Napisałem ten kod w C# zaszyfrować ciąg z kluczem:Pomóż mi z szyfrowania 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; 
} 

Problemem jest to, że zawsze się błąd, gdy chcę, aby odszyfrować się encryted tekst z tym kodem:

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

Jakieś wskazówki?

+1

Wszystko, co mogę powiedzieć, to co? :) Być może jest to ćwiczenie edukacyjne, ale nie musisz konwertować znaków na ciągi, ręcznie je zamieniać, a następnie konwertować z powrotem na ciąg znaków. Jak udowodniono dzięki funkcjom Dec2Bin i Bin2Dec, char można konwertować do iz ints z rzutami, więc po prostu weź char z obu ciągów, zastosuj operator xor i wstaw nowy łańcuch. – tyranid

+0

Byłoby pomocne, jeśli określisz, jaki błąd otrzymujesz :) –

+0

Ponadto, możesz użyć StringBuilders zamiast ciągów. Ciągi są niezmienne (nie można ich zmienić), więc takie rzeczy jak _str + = _temp; generuje nowy ciąg za każdym razem, co powoduje, że ta metoda jest niepotrzebnie ciężka/droga. Użyj StringBuilder i .Append (temp). –

Odpowiedz

44

Jeśli masz postać, char, możesz przekonwertować ją na liczbę całkowitą, int.

A następnie można użyć operatora ^ do wykonywania XOR na nim. Wygląda na to, że nie używasz tego operatora, co może być źródłem Twojego problemu.

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

Tego rodzaju rzeczy. Oto już wersja z komentarzami, że robi to samo w krokach, aby łatwiej się uczyć od:

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

Krótka wersja jest taka sama, ale ze zmiennych pośrednich usunięto, zastępując wyraz bezpośrednio w którym są one używany.

1

Oto prosty kod do szyfrowania i deszyfrowania

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

Funkcja odszyfrowywania kończy się niepowodzeniem na ciąg znaków z wielką literą. wszelkie aktualizacje tej funkcji? – pithhelmet

Powiązane problemy