Search code examples
c#encryptionencryption-symmetric

Help me with XOR encryption


I wrote this code in C# to encrypt a string with a key:

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

The problem is that I always get error when I want to decrypt an encryted text with this code:

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

Any clues?


Solution

  • If you have a character, a char, you can convert it to an integer, an int.

    And then you can use the ^ operator to perform XOR on it. You don't appear to be using that operator at the moment, which might be the source of your problem.

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

    That kind of thing. Here's a longer version with comments that does the same thing in steps, to make it easier to learn from:

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

    The short version is the same but with the intermediate variables removed, substituting expressions directly into where they're used.