1

I have a function in a small application that I'm writing to break a recycled one-time pad cypher. Having used VB.NET for most of my career I thought it would be interesting to implement the app in C#. However, I have encountered a problem due to my present unfamiliarity with C#.

The function takes in two strings (of binary digits), converts these strings to char arrays, and then performs an XOR on them and places the result in a third char array.

This is fine until I try to convert the third char array to a string. Instead of the string looking like "11001101" etc, I get the following result: " \0\0 \0 " i.e. the "1"s are being represented by spaces and the "0"s by "\0".

My code is as follows:

    public string calcXor(string a, string b)
    {
        char[] charAArray = a.ToCharArray();
        char[] charBArray = b.ToCharArray();

        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;

        char[] result = new char[len];

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

        return new string(result);
    }
2
  • 2
    Should you not be XORing the binary data representing the characters, rather than the binary data representing the characters '1' and '0'? Tis a bit of a step back from what you're asking, but.. Commented Jan 28, 2014 at 13:45
  • I'm just waiting for my reputation to get to 15 and then I can up-vote the answers. Commented Jan 28, 2014 at 14:05

4 Answers 4

2

Your problem is in the line

  result[i] = (char)(charAArray[i] ^ charBArray[i]);

that should be

  // (Char) 1 is not '1'!
  result[i] = (char)((charAArray[i] ^ charBArray[i]) + '0');

More compact solution is to use StringBuilder, not arrays:

public string calcXor(String a, String b) {
  int len = (a.Length < b.Length) ? a.Length : b.Length;

  StringBuilder Sb = new StringBuilder();

  for (int i = 0; i < len; ++i) 
    // Sb.Append(CharToBinary(a[i] ^ b[i])); // <- If you want 0's and 1's  
    Sb.Append(a[i] ^ b[i]); // <- Just int, not in binary format as in your solution

  return Sb.ToString();
}

public static String CharToBinary(int value, Boolean useUnicode = false) {
  int size = useUnicode ? 16 : 8;

  StringBuilder Sb = new StringBuilder(size);

  Sb.Length = size;

  for (int i = size - 1; i >= 0; --i) {
    Sb[i] = value % 2 == 0 ? '0' : '1';
    value /= 2;
  }

  return Sb.ToString();
}

Your solution just computes xor's (e.g. "65") and put them into line (e.g. 65728...); if you want 0's and 1's representation, you should use formatting

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks you. That's it. +1 for the more compact solution.
Do you realize (in your "should be" section) that charAArray[i] ^ charBArray[i] + '0' means charAArray[i] ^ (charBArray[i] + '0'), so addition comes before (has higher priority or precedence) than bitwise XOR?
@Jeppe Stig Nielsen: Thank you! The subtle detail that priority of '^' is less than '+' slept from my mind.
0

Have a look at the ASCII Table. 0 is the Null character \0. You could try ToString()

Comments

0

Have you tried using binary / byte[]? It seems like the fastest way to me.

public string calcXor(string a, string b)
{
  //String to binary
  byte[] ab = ConvertToBinary(a);
  byte[] bb = ConvertToBinary(b);
  //(XOR)
  byte[] cb = a^b  

  return cb.ToString();
}

public static byte[] ConvertToBinary(string str)
{
  System.Text.ASCIIEncoding  encoding = new System.Text.ASCIIEncoding();
  return encoding.GetBytes(str);
}

Comments

0

I just wanted to add that the solution I eventually chose is as follows:

//Parameter binary is a bit string
public void someroutine(String binary) 
{
 var data = GetBytesFromBinaryString(binary);
 var text = Encoding.ASCII.GetString(data);
}

public Byte[] GetBytesFromBinaryString(String binary)
{
 var list = new List<Byte>();

 for (int i = 0; i < binary.Length; i += 8)
     {
     String t = binary.Substring(i, 8);
     list.Add(Convert.ToByte(t, 2));
     }

 return list.ToArray();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.