Я был на ярмарке карьеры, и меня задал вопрос "что делает этот запрос и на каком языке он".
Я сказал, что это в.NET LINQ, но не смог предсказать, что он делает.
Может кто-нибудь мне помочь
Я написал в.NET и попробовал.
var youShould = from c
in "3%.$@9/52@2%35-%@4/@./3,!#+%23 !2#526%N#/-"
select (char)(c ^ 3 << 5);
Label1.Text = youShould.ToString();
И получил этот результат:
System.Linq.Enumerable+WhereSelectEnumerableIterator'2[System.Char,System.Char]
Прежде всего, не чувствуйте себя плохо, что вы не получили ответа. Я точно знаю, что здесь происходит, и я бы, наверное, просто рассмеялся и ушел, если кто-то спросил меня, что это сделал.
Здесь происходит несколько вещей, но начинайте с вывода:
var youShould = from c in "3%.$@9/52@2%35-%@4/@./3,!#+%23 !2#526%N#/-"
select (char)(c ^ 3 << 5);
Label1.Text = youShould.ToString();
>>> System.Linq.Enumerable+WhereSelectEnumerableIterator'2[System.Char,System.Char]
Когда вы запускаете запрос LINQ или используете любой из эквивалентных методов, таких как Select()
которые возвращают набор, то, что вы получаете, является особым внутренним типом объекта, называемым "итератором", в частности, объектом, реализующим интерфейс IEnumerable
. .NET использует эти объекты повсюду; например, целью цикла foreach
является итерация по итераторам.
Одна из самых важных вещей, которые нужно знать об этих объектах, состоит в том, что просто создание одного на самом деле ничего не делает. Итератор фактически не содержит множество вещей; скорее, он содержит инструкции, необходимые для создания множества вещей. Если вы попытаетесь сделать что-то вроде, например ToString
, результат, который вы получите, не будет очень полезен.
Однако он говорит нам одно: он говорит нам, что этот конкретный итератор принимает исходный список типа char
и возвращает новый набор, также типа char
. (Я знаю это, потому что я знаю, что делают два общих параметра "select iterator".) Чтобы получить фактические результаты из этого итератора, вам просто нужно как-то перекрыть его, например:
foreach (var c in youShould)
{
myLabel.Text += c;
}
или, немного легче,
myLabel.Text = new string(youShould.ToArray());
Чтобы на самом деле выяснить, что он делает, вы также должны признать второй факт: LINQ обрабатывает строку как "набор символов". Он будет обрабатывать каждый символ в этой строке, по одному за раз, и выполнять побитовые операции над значением.
Долгосрочный эквивалент этого запроса выглядит примерно так:
var input= "3%.$@9/52@2%35-%@4/@./3,!#+%23 !2#526%N#/-";
var output = string.Empty;
foreach (var c in input)
{
var i = (int)c;
var i2 = i ^ (3 << 5);
var c2= (char)i2;
output += c2;
}
Если вы сделали математику вручную, вы получите правильное выходное сообщение. Чтобы сэкономить вам упражнение на ошеломление мозга, я просто скажу вам: он переключает биты 5 и 6 значения ASCII, меняя каждый символ на один дальше по таблице ASCII. Полученная строка:
ОТПРАВИТЬ СВОЙ РЕЗЮМЕ [адрес электронной почты]
Демостративный.NET скрипт: https://dotnetfiddle.net/x7UvYA
Для каждого символа в строке проецируйте символ, поместив его (3 слева сдвинутым на 5), затем верните числовое значение обратно на символ.
Вы можете создать свои собственные строки кода, снова выполнив запрос по некодированной строке, потому что, если вы XOR число дважды по тому же значению, вы останетесь с тем же номером, с которого вы начали. (например, x ^ y ^ y = x
)
Я оставлю это упражнением для читателя, чтобы выяснить, что это такое:
4()3@)3@!@$5-"@4%34
Я полагаю, он тестирует:
IEnumerable<T>
и того, как оно относится к строкамЛично я считаю, что это бесполезный тест, который на самом деле не отражает проблемы реального мира.