Help me with XOR encryption
28,599
Solution 1
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.
Solution 2
// Code
public static byte[] EncryptOrDecrypt(byte[] text, byte[] key)
{
byte[] xor = new byte[text.Length];
for (int i = 0; i < text.Length; i++)
{
xor[i] = (byte)(text[i] ^ key[i % key.Length]);
}
return xor;
}
// Test
static void Main(string[] args){
string input;
byte[] inputBytes;
string inputKey;
byte[] key;
do
{
input = System.Console.ReadLine();
inputBytes = Encoding.Unicode.GetBytes(input);
inputKey = System.Console.ReadLine();
key = Encoding.Unicode.GetBytes(inputKey);
//byte[] key = { 0, 0 }; if key is 0, encryption will not happen
byte[] encryptedBytes = EncryptOrDecrypt(inputBytes, key);
string encryptedStr = Encoding.Unicode.GetString(encryptedBytes);
byte[] decryptedBytes = EncryptOrDecrypt(encryptedBytes, key);
string decryptedStr = Encoding.Unicode.GetString(decryptedBytes);
System.Console.WriteLine("Encrypted string:");
System.Console.WriteLine(encryptedStr);
System.Console.WriteLine("Decrypted string:");
System.Console.WriteLine(decryptedStr);
} while (input != "-1" && inputKey != "-1");
//test:
//pavle
//23
//Encrypted string:
//BRD_W
//Decrypted string:
//pavle
}
Author by
fardjad
Updated on July 08, 2022Comments
-
fardjad almost 2 years
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?
-
pithhelmet over 11 yearsThe decrypt function fails on a string with a capital letter in it. any updates to this function?
-
Dbloom over 3 yearsIs it possible to make this method only return alpha numeric values? It works but produces weird characters. And I need them to be human readable for my use case.
-
Daniel Earwicker over 3 years@Dbloom to narrow the range of characters used without losing information, you need to perform a second conversion to an encoding such as hex or base64. Note that these won’t be at all “human readable” but they will be safe to send in text formats, clipboard operations etc.