2010-03-28 37 views
9

ho scritto questo codice in C# per crittografare una stringa con una chiave:Aiutami con la crittografia 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; 
} 

Il problema è che ottengo sempre l'errore quando voglio decifrare un testo encryted con questo codice:

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

Eventuali indizi?

+1

Tutto quello che posso dire è eh? :) Forse è un esercizio educativo, ma non è necessario convertire i caratteri in stringhe, xorli manualmente e poi riconvertirli in una stringa. Come dimostrato dalle funzioni Dec2Bin e Bin2Dec, il char può essere convertito da e verso gli init con cast, quindi prendi char da entrambe le stringhe, applica l'operatore '^' xor e metti in una nuova stringa. – tyranid

+0

Sarebbe utile se si specifica quale errore si sta ottenendo :) –

+0

Inoltre, è possibile utilizzare StringBuilders anziché Stringhe. Le stringhe sono immutabili (non possono essere modificate), quindi cose come _str + = _temp; genera una nuova stringa ogni volta, il che rende questo metodo inutilmente pesante/costoso. Utilizzare un StringBuilder e .Append (temp). –

risposta

44

Se si dispone di un carattere, uno char, è possibile convertirlo in un numero intero, uno int.

E quindi è possibile utilizzare l'operatore ^ per eseguire XOR su di esso. Al momento non sembra che tu stia usando quell'operatore, che potrebbe essere la fonte del tuo 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(); 
} 

Questo genere di cose. Ecco una versione più lunga con i commenti che fa la stessa cosa in fasi, per rendere più facile da imparare da:

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 versione corta è lo stesso, ma con le variabili intermedie rimossi, sostituendo le espressioni direttamente dove sono Usato.

1

Ecco il codice semplice per cifrare e decifrare

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 funzione decrypt non riesce su un stringa con una lettera maiuscola. eventuali aggiornamenti a questa funzione? – pithhelmet

Problemi correlati