11

I recently started playing around with C#, and I'm trying to understand why the following code doesn't compile. On the line with the error comment, I get:

Cannot implicitly convert type 'int' to 'char'. An explicit conversion exits (are you missing a cast?)

I'm trying to do a simple XOR operation with two strings.

public string calcXor (string a, string b)
{
    char[] charAArray = a.ToCharArray();
    char[] charBArray = b.ToCharArray();
    char[] result = new char[6];
    int len = 0;

    // Set length to be the length of the shorter string
    if (a.Length > b.Length)
        len = b.Length - 1;
    else
        len = a.Length - 1;

    for (int i = 0; i < len; i++) {
        result[i] = charAArray[i] ^ charBArray[i]; // Error here
    }

    return new string (result);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    If your string is ASCII, try this `result[i] =(char)((short) charAArray[i] ^ (short)charBArray[i]);` – ebattulga Feb 20 '13 at 03:37
  • 3
    Bitwise operators only take numbers as operands. Is your string a series of numeric digits? Or are you trying to do this operation based on the ASCII Values? – JohnFx Feb 20 '13 at 03:38
  • 1
    Thanks, i forgot that xor is bitwise operator so it takes 1 and 0 which is why its complaining about int conversion. –  Feb 20 '13 at 03:41
  • 1
    To clarify for future readers, a `bitwise operator` does NOT `take 1 and 0`. That would be a `boolean operator`, which only has two values. A `bitwise operator` acts on ALL the bits of two integers, resulting in an integer. As seen in the accepted answer. – ToolmakerSteve Jun 03 '15 at 19:06

3 Answers3

21

If you use XOR-ing to hide data, take a look at the code below. The key will be repeated as long as necessary. It is maybe a shorter/better approach:

public static string xorIt(string key, string input)
{
    StringBuilder sb = new StringBuilder();
    for(int i=0; i < input.Length; i++)
        sb.Append((char)(input[i] ^ key[(i % key.Length)]));
    String result = sb.ToString ();

    return result;
}
Community
  • 1
  • 1
Ton Snoei
  • 2,637
  • 22
  • 23
  • +1 for the code. But using any Stream Cipher without a proper PRG (Pseudo Random Generator) breaks the principle of semantic security. And I'm sorry to say this but in your code the PRG used is extremely far from random looking and is completely predictable. In fact this could be broken with a ciphertext only attack in a very short interval. So in short never EVER USE this kind of encryption unless you used it together with a secure PRP (Pseudo Random Permutation) or any other type of a reliable secure cipher. – Samuel Allan Mar 18 '14 at 16:21
  • I fully agree. If you want a secure solution use the tools and frameworks available. They will do the job in the right way for you with the mentioned PRG and all other nice bells and whistles. – Ton Snoei Oct 29 '14 at 18:02
  • 4
    IMHO, the point of XOR-ing strings isn't strong security, but rather a step in `obfuscation` - making it more work for someone reverse-engineering your code to understand what work your app is doing where. Specifically, they can't simply search your strings. They have to trace the logic, find the XOR method, and feed all the strings through that method, with appropriate keys. – ToolmakerSteve Jun 03 '15 at 19:12
6

You are doing an xor on 2 characters. This will do an implicit type conversion to int for you since there is no data loss. However, converting back from int to char will need you to provide an explicit cast.

You need to explicitly convert your int to a char for result[i]:

result[i] = (char) (charAArray[i] ^ charBArray[i]);
ataravati
  • 8,891
  • 9
  • 57
  • 89
allen
  • 4,627
  • 1
  • 22
  • 33
0

If the value of the result is important then Allan is correct (accepted answer). If you are just looking for a match and are not worried about performance, use strcmp() or memcmp() as an alternative.

In assembler is it common to initialize things by an XOR against themselves as the T-cycles are fewer. If I was brute-forcing (hash compare), then this would be an improvement over strcmp or memcmp as I really don't sort order, just match/nomatch.

Readers should also be aware of this which can be tweaked.

Community
  • 1
  • 1
mckenzm
  • 1,545
  • 1
  • 12
  • 19
  • IMHO, this answer is not relevant to this question, which says nothing about looking for a match. – ToolmakerSteve Jun 03 '15 at 19:25
  • I'll pay that. I read too much into the code. When xor-ing strings I would normally expect to pad the shorter string with leading x'00'. Progressing instead from the LHS led me to believe a match is being sought or a transformation is occurring to obscure data. – mckenzm Jun 13 '15 at 17:23