C#

时间:2018-06-07 05:50:26

标签: c# xor

我的问题是我有一个二进制字符串列表,如下所示:

  

列表= LT; “1111”, “1010”, “1010”, “0011” >

和二进制值st1 = 1010的输入字符串。我想在Xor之间:

  

st3 = st1 Xor list< 0>

然后:

  

st3 = st3 Xor list< 1>

     

st3 = st3Xor list< 2&gt ;;

     

st3 = st3 Xor list< 3&gt ;;

其中操作将是st1 Xor,其中第一个键位于键列表中,结果Xor使用第二个键位于键列表中,结果Xor中的第三个键位于键列表中,依此类推。有人能帮帮我吗? 我已经尝试过这段代码,但它不能像我预期的那样工作:

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()); 
        }
            }

我不期望的结果是: enter image description here

3 个答案:

答案 0 :(得分:2)

这是一种方法(任意长度的二进制字符串):

  • 将字符串转换回整数 BigIntegers,这样我们就可以实际获得现有的按位Xor运算符(^)的实用程序。
  • 使用LINQ&#39; Aggregate将种子值(st1)连续左折叠,并将转换后的列表与Xor一起使用。
  • 由于您似乎只对最低的4位感兴趣,我已经应用了一个掩码,但如果您的所有数字都是严格的4位,那么实际上并不是必需的(因为0 Xor 0保持不变0)
  • 您可以将int转换回带有Convert.ToString(x, 2)的二进制字符串,然后将PadLeft转换为替换任何缺少的前导零。

编辑 - OP已从示例4位数更改了问题,现在要求使用任意长度的二进制字符串。这种方法仍然有效,但我们需要使用BigInteger(仍然有XOR ^运算符),但我们需要帮助程序来解析和格式化二进制字符串,因为它们不是'#1}}。内置于BigInteger。 BitMask和padding也被删除了,因为字符串不是固定长度 - 结果最多只有1个前导零:

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();

由于没有原生支持将BigIntegers转换为二进制字符串/从二进制字符串转换,因此您需要转换帮助程序,例如Douglas's one here

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

对于相反的操作,ToBinaryString来自此helper

32位整数答案

如果二进制字符串是32位或更少,则存在一个更简单的解决方案,因为存在与二进制字符串的开箱即用转换。同样的方法应该适用于64位长。

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');

答案 1 :(得分:1)

以下是<?php session_start(); ?> <html> <head> <title>Result</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> </head> <body> <?php if (isset($_POST)) { $username = $_POST['username']; echo 'Welcome! ' .$username. '<br>'; } $gender = $_POST['gender']; if ($gender == "others") echo "<font size='5'>You are not normal</font><br><br>"; else echo "<font size='5'>You are normal</font><br><br>"; $age = $_POST['age']; if (($age == "60years") || ($age == "75years")) echo "<font size='5'>You are old man</font><br><br>"; else echo "<font size='5'>You are young man</font><br><br>"; $race = $_POST['race']; if ($race == "others") echo "<font size='5'>You are from other race</font><br><br>"; else echo "<font size='5'>You are from one of three races</font><br><br>"; ?> </body> </html> <?php session_destroy(); ?>方法:

Xor

你可以像这样使用它:

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'));
}

答案 2 :(得分:1)

试试这段代码:

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;
}