Reputation: 57
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 :
Upvotes: 0
Views: 2020
Reputation: 107237
Here's one approach (Arbitrary length binary strings):
^
).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');
Upvotes: 2
Reputation: 37347
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;
}
Upvotes: 1
Reputation: 270980
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
Upvotes: 1