0

My question is that i have a list of binary string like below :

list=<"1111","1010","1010","0011">

and an input string of binary value st1=1010. I want to Xor between :

st3=st1 Xor list<0>

then :

st3=st3 Xor list<1>

st3=st3Xor list <2>;

st3=st3 Xor list <3>;

where the operation will be st1 Xor with first key in keys list and the result Xor with the second key in keys list and the result Xor with the third key in keys list and so on . Can any one help me please? i have tried this code but it does not work as i expected :

foreach (string k in keys)
        {
            string st1 = textBox1.text;
            string st2 = k;
            string st3;
            st3 = "";
        //i wanted to make the length of both strings st1 and st2 equal
        //here if the length of st1 greater than st2 
        if (st1.Length > st2.Length)
        {
            int n = st1.Length - st2.Length;
            string pad = "";
            for (int j = 1; j <= n; j++)
            { pad += 0; }
            string recover = pad.ToString() + st2;
           //this is my Xor operation that i made for string values  
            for (int counter = 0; counter < st1.Length; counter++)
            {
                if (st1[counter] != recover[counter])
                {
                    st3 = st3 + '1';
                }
                else
                { st3 = st3 + '0'; }


            }
            listBox4.Items.Add("Xor :" + st3.ToString());
        }
        //here if st1 is less than st2
        else if (st1.Length < st2.Length)
        {
            int nn = st2.Length - st1.Length;

            string ppad = "";
            for (int j = 1; j <= nn; j++)
            {
                ppad += 0;
            }

            string recover = ppad.ToString() + st1;

            for (int counter = 0; counter < st2.Length; counter++)
            {
                if (st2[counter] != recover[counter])
                {
                    st3 = st3 + '1';

                }
                else
                { st3 = st3 + '0'; }

                }
            listBox4.Items.Add("Xor :" + st3.ToString());}
        //here if st1 equal st2
         else
        {
            for (int counter = 0; counter < st1.Length; counter++)
            {
                if (st1[counter] != st2[counter])
                {
                    st3 = st3 + '1';

                }
                else
                { st3 = st3 + '0'; }

            }
            listBox4.Items.Add("Xor :" + st3.ToString()); 
        }
            }

the result that i do not expected is : enter image description here

safaa
  • 57
  • 7

3 Answers3

2

Here's one approach (Arbitrary length binary strings):

  • Convert the strings back to integers BigIntegers, so that we can actually get the utility of existing bitwise Xor operator (^).
  • Use LINQ's Aggregate to consecutively left-fold the seed value (st1) with the converted list with Xor.
  • Since you seem interested only in the lowest 4 bits, I've applied a mask, although if all your numbers are strictly 4 bits, this isn't actually necessary (since 0 Xor 0 stays 0)
  • You can convert the int back to a binary string with Convert.ToString(x, 2) and then PadLeft to replace any missing leading zeroes.

Edit - OP has changed the question from an example 4 bit number and the requirement is now to work with arbitrary length binary strings. This approach still works, but we'll need to use BigInteger (which still has an XOR ^ operator), but we need helpers to parse and format binary strings, as these aren't built into BigInteger. The BitMask and padding have also been removed, since the strings aren't fixed length - the result will have at most 1 leading zero:

var list = new List<string>{"10101010101010101101","1101010101010101011",
  "1110111111010101101","11111111111111111111111111","10101010110101010101"};
var listNum = list.Select(l =>  BinaryStringToBigInteger(l));

var st1 = "000000001";
var seedNumber = BinaryStringToBigInteger(st1);

var chainedXors = listNum.Aggregate(seedNumber, (prev, next) => prev ^ next);
// Back to binary representation of the string
var resultString = chainedXors.ToBinaryString();

And because there's no native support for converting BigIntegers to / from binary strings, you'll need a conversion helper such as Douglas's one here:

BigInteger BinaryStringToBigInteger(string binString)
{
    return binString.Aggregate(BigInteger.Zero, (prev, next) => prev * 2 + next - '0');
}

And for the reverse operation, ToBinaryString is from this helper.

32 Bit Integer answer

If the Binary strings are 32 bits or less, then a much simpler solution exists, since there are out of the box conversions to / from binary strings. The same approach should apply for 64 bit longs.

var list = new List<string>{"1111","1010","1010","0011","0011"};
var listNum = list.Select(l =>  Convert.ToInt32(l, 2));
// If you only want the last 4 bits. Change this to include as many bits as needed.
var bitMask = Convert.ToInt32("00000000000000000000000000001111", 2);

var st1 = "1010";
var someNum = Convert.ToInt32(st1, 2);

var chainedXors = listNum.Aggregate(someNum, (prev, next) => prev ^ next);
// If you need the result back as a 4 bit binary-string, zero padded
var resultString = Convert.ToString(chainedXors & bitMask, 2)
                          .PadLeft(4, '0');
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • it does not help me , i have the binary values of long length size and also i want the result in binary can you see the edit i now made !! – safaa Jun 07 '18 at 06:22
  • Are your strings of fixed size? If so, how many bits? We can adapt the above to any arbitrary length of bits, since even [BigInteger](https://stackoverflow.com/a/32150510/314291) has a Bitwise xor operator. – StuartLC Jun 07 '18 at 06:30
  • no my string is not of a fixed size it is of very long size of binary value that is resulted from converting ASCII to binary – safaa Jun 07 '18 at 06:33
1

Here is an Xor method for you:

public static string Xor(string s1, string s2) {
    // find the length of the longest of the two strings
    int longest = Math.Max(s1.Length, s2.Length);

    // pad both strings to that length. You don't need to write the padding
    // logic yourself! There is already a method that does that!
    string first = s1.PadLeft(longest, '0');
    string second = s2.PadLeft(longest, '0');

    // Enumerable.Zip takes two sequences (in this case sequences of char, aka strings)
    // and lets you transform each element in the sequences. Here what 
    // I did was check if the two chars are not equal, in which case
    // I transform the two elements to a 1, 0 otherwise
    return string.Join("", Enumerable.Zip(first, second, (x, y) => x != y ? '1' : '0'));
}

You can use it like this:

Xor("1111", "1010") // 0101
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Off-topic, the name of `Enumerable.Zip` always throws me, since its name does not accurately reflect its operation. [A zipper **alternates** between left and right](https://media.giphy.com/media/FS2GiqcNGT292/giphy.gif), which leads me to expect that `Enumerable.Zip(listofletters, listofnumbers)` should return `A,1,B,2,C,3,D,4,...`, not `A1,B2,C3,D4,...` – Flater Jun 07 '18 at 06:13
  • @Flater Yeah I think so too... I thought it would give me an `IEnumerable>`. – Sweeper Jun 07 '18 at 06:15
  • That would still be different from interleaving the two lists, your expectation still puts the items together :) Part of my expectation may be linguistic habit: in Dutch, merging in traffic is called "to zip up" (ritsen), exactly because [cars are supposed to alternate between (source) lanes when merging into a (target) lane](https://i.imgur.com/033NJcu.gif). But I do feel that even without the added traffic context; a zipper, after which the `Zip` method is named, still conflicts with the actual `Zip` method. – Flater Jun 07 '18 at 06:17
  • 1
    @Flater although your point is taken that zip is pairing, rather than actually interleaving, data, the term `zip` is widely used across [many FP languages](https://stackoverflow.com/a/1115570/314291) - including Haskell, Scala and F#. LINQ's `.Zip` has the same meaning. – StuartLC Jun 07 '18 at 10:59
  • @StuartLC Good point. Other languages hadn't crossed my mind yet. – Flater Jun 07 '18 at 11:11
1

Try this code:

static void Main(string[] args)
{
    List<string> list = new List<string> { "1111", "1010", "1010", "0011" };
    string st1 = "1010";

    foreach (string item in list)
    {
        st1 = XorBins(st1, item);
        Console.WriteLine(st1);
    }
    Console.ReadKey();
}

private static string XorBins(string bin1, string bin2)
{
    int len = Math.Max(bin1.Length, bin2.Length);
    string res = "";
    bin1 = bin1.PadLeft(len, '0');
    bin2 = bin2.PadLeft(len, '0');

    for (int i = 0; i < len; i++)
        res += bin1[i] == bin2[i] ? '0' : '1';

    return res;
}
Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • no that not what i mean , i wanted to : 1010 Xor 1111 Xor 1010 Xor 1010 Xor 0011 – safaa Jun 07 '18 at 06:56
  • thank you so much you solved my problem wish to you all the good luck – safaa Jun 07 '18 at 07:30
  • can you reverse the operation that when i xor the same keys in the list with the result it give me back the string1 , i have problems with pad left when i reverse the operation @Michal Turczyn – safaa Jun 11 '18 at 10:06
  • @safaa Can't understand what you are trying to do, could you be more clearer? – Michał Turczyn Jun 11 '18 at 10:20
  • the code you gave me XOR between the key list and st1 where (result =st1 XOR key list), can you give me the reverse process so i get st1 a gain where (st1=result XOR key list) ,because when i try it ,i am having problems with zero pad and i could not get st1 correct again @Michal Turczyn – safaa Jun 12 '18 at 06:59
  • `result =st1 XOR key list` ? In code it is `st1 = st1 XOR key list`... I still don't understand. – Michał Turczyn Jun 12 '18 at 07:02
  • that is right but i want also to reverse the code so that i can get st1 can you help me @Michal Turczyn – safaa Jun 12 '18 at 07:09
  • in the code (result =st1=st1 XOR key list) ,i mean how can i get back st1 from (st1=result XOR key list ) @Michal Turczyn – safaa Jun 12 '18 at 07:11
  • Google "How to reverse XOR operation", you could find that applying it again reverses operation. – Michał Turczyn Jun 12 '18 at 07:12