[C#] Домашно Strings and Text Processing - 7 задача


24

Условие: Write a program that encodes and decodes a string using given encryption key (cipher). The key consists of a sequence of characters. The encoding/decoding is done by performing XOR (exclusive or) operation over the first letter of the string with the first of the key, the second – with the second, etc. When the last key character is reached, the next is the first.

Решениеsource.

Обяснение: Интересното при тази задача е, че криптирането и декриптирането се осъществяват по един и същ начин.

С "%" си осигуряваме цикличността на шифъра. Примерно за key = "abc":

i = 0; i % key.Length = 0 % 3 = 0; key[0] = a
​i = 1; i % 
key.Length = 1 % 3 = 1; key[1] = b
​i = 2; i % key.Length = 2 % 3 = 2; key[2] = c
​i = 3; i % key.Length = 3 % 3 = 0; key[0] = a
​i = 4; i % key.Length = 4 % 3 = 1; key[1] = b
​i = 5; i % key.Length = 5 % 3 = 2; key[2] = c

Можете да погледнете и задача 59 от Проекта Ойлер за по-подробно обяснение и да се опитате да хакнете съобщението.




Отговори



7

Много елегантно решение Браво.

Но преди да погледна твоето ето какво сътворих. Не е най-гениалното, но става. Разбито на много стъпки и по дълго разбира се. Така ги разбирам нещатата така ги правя :)

Решение:

http://pastebin.com/NxsRV5P4

Обяснение:

1. Създавам променливи str и key. Присвоявам им някакъв текст. Като key ще ми е ключът с който ще шифровам и дешифровам.

2. Правя си метод за шифроване Encrypt(string str, string key) , който има дадените параметри и връща string. Създавам си 2-а char[ ], с дължината на текста str.Length съответно keyArr и strArr, като на единия му присвоявам текста, а на другия ключа. Също така си създавам и променливата encrypted със StringBuilder-a.

3. Тук се опитвам да направя еднакви по дължина текста и ключа, като ключът ако не е с дължината на текста, го правя с такава дължина като, самият ключ се повтаря докато не достигне желаната дължина. За целта пускам един for цикъл до strArr.Length. Самият for цикъл има две водещи променливи, като едната "i" работи върху индексите и съответно дължината, а другата "к" върху ключа. Когато "к" стигне дължината на оригиналният ключ тогава к=0; идеята е да започне записва ключът отначало и така докато новият ключ не стане с дължината на текста.

Пример:

str = "малко текст за шифроване"   str.Length = 24

key = "шифърключ" - оригинален ключ

key = "шифърключшифърключшифърк" - готов за използване с XOR

4.  Тук пускам втори for цикъл пак до strArr.Length. И долепям резултата в encrypted с метода .Append()
 

ВНИМАНИЕ това което е в синьо трябва да задължително в скоби, един вид резултат от XOR на двете стойности да бъде преобразувана след това в char(звездичка, нота, сърце какъвто се падне). Казвам го защото аз брах големи ядове като нямаше скоби :), защото първо се изпълняваше преобразуването на (char)(strArr[i] и резултата XOR с keyArr[i] . Което даваше някакви глупости като резултат.

ЕТО ЗАЩО ТРЯБВА ДА СЕ ЗНАЯТ ПРИОРИТЕТИ НА ОПЕРАТОРИТЕ :)

Пример:

encrypted.Append((char)(strArr[i] ^ keyArr[i]));

 

5. Накрая на метода return encrypted.ToString(); резултатa го присвоявам на нова променлива от тип string encrypted

6. Decrypt дешофроването става по същият начин като шифроването само че на мястото на текста подавам вече шифрованият текс

 

Асси


от Assi.NET (3050 точки)


0
Можеш да криптираш директно в първия цикъл for (int i = 0, k = 0; i < text.Length; i++, k++) { if (k == key.Length) k = 0; result.Append((char)(text[i]^key[k])); } без да увеличаваш key масива

от kalo_glb (5 точки)

0
Да мога, но така задачата е разбита на повече парченца и се вижда по хубаво къде какво се случва :) за това.... иначе Благодаря за препоръката

от Assi.NET (3050 точки)



0
Мойто решение:
http://pastebin.com/6qL2N41y

от hudsonvsm (25 точки)


-1
Колеги, обърках се като пате в калчища. Моля някой да ми обясни, защо се случва това:
char specual = '♥'; Console.WriteLine(specual);
int converted = Convert.ToInt32(specual); Console.WriteLine(converted);
int three = 3; char conth = Convert.ToChar(three); Console.WriteLine(conth);

По точно, защо 3 е равно на сърце, ама сърце не е равно на три , а на 9887 или нещо подобно беше?

от topsoft (420 точки)


0
Ако кастнеш 3 и 9829 към char може да видиш с дебъгера какво връща: var a = (char)3; -> връща 'Alt+L' var b = (char)9829; -> връща '♥'
Когато обръщаш '♥' в int ти връща 9829, защото не 3, а именно 9829 е сърце според ASCII таблицата.
А защо конзолата обръща 'Alt+L' също в сърце, потърси информация за контролните символи и по-точно "CP437". Виж също и трите линка по-долу дали няма да ти помогнат: https://en.wikipedia.org/wiki/Heart_%28symbol%29#Encoding http://www.ansi-bbs.org/ansi-bbs2/control_chars/ http://stackoverflow.com/questions/15836744/why-are-non-printable-ascii-characters-actually-printable

от Flystar (1171 точки)

0
Еми тая задача както я решавате няма особен смисъл тогава. Ако не можеш да ползваш шифъра за декодиране без да знаеш от къде си тръгнал, май май няма голяма логика...

от topsoft (420 точки)


0

Здравейте,
седях и си мислех, седях и мислех, мислех, мислсех, докато в един момент се усетих, че само си седя.
Но в крайна сметка разбрах за какво става въпрос.
Идеята е, че в UniCode всеки символ е представен с някакъв двоичен код.
В задачата се използва XOR защото:
примерно имате буква представена като : 1011 (В някаква таблица като UniCode примерно)
друг кодиращ символ : 1101
когато ги XOR-нете се получава : 1011 ^ 1101 = 0110 (някакъв символ, който когато го парснете към char изглежда малко като каракацил). 
За да получим оригиналния символ просто обръщаме процеса :
взимаме каракацила : 0110 
после взимаме кодиращия символ : 1101
и се получава : 0110 ^ 1101 = 1011 

Това е ! :)




0

Source

За кодирането създавам метод с параметри текста и ключа(шифъра). Завъртам цикъл от 0 до дължината на текста, в който записвам кодирания израз в StringBuilder. Преди края на цикъла ако не е достигната дължината на ключа , увеличавам индекса му , ако е достигната го занулявам.

Методът за декодиране е същия като кодиращия метод, зaради XOR-a. Ako a  ^  b = c , то оттук следва, че  а = c ^ a.


от nina75 (60 точки)


0
Интересно някой пробвал ли е какво става като въведеш за ключ думата "string" и съответно при иакарването на резултата в Console.Write() се описва по някакъв начин изхода(Пример: Console.WriteLine("The encoded text is: {0}", result);) ?
Ако може някой нека да обясни това на какво се дължи и как да се избегне ?
Поздрави Стефан!

от stefan86 (15 точки)