You are on page 1of 35

Київський політехнічний інститут імені Ігоря Сікорського

Теплоенергетичний факультет
Кафедра АПЕПС

КУРСОВА РОБОТА
з дисципліни «Алгоритмізація та програмування – 2: Процедурне
програмування»

На тему:
«Програмна система для шифрування даних методом бітового зсуву

Виконав: студент 1 курсу


гр. ТР-з01
Крупський Андрій Максимович

Оцінка «_________» Перевірив:


Крячок Олександр Степанович
Дата «20» Квітня 2021 р. _____________
(підпис)

Київ - 2021
Анотація

Звіт до курсової роботи: 25 с., 10 рис., 1 додаток, 11 джерел.


Об’єкт дослідження – шифратор.
Мета роботи – розробити програмний продукт, який буде виконувати
шифрування та дешифрування вхідних даних методом бітового зсуву,
використовуючи ключ.
Метод дослідження – розробка програмного забезпечення.
Ключові слова: ПРОГРАМУВАННЯ, С, БІТОВІ ОПЕРАЦІЇ,
ШИФРУВАННЯ, ДЕШИФРУВАННЯ, ЦИКЛІЧНИЙ ЗСУВ,.

Annotation

Report to the course work: 25 pages, 10 figures, 1 appendix, 11 sources.


The object of study is a coder.
The purpose of the work is to develop a software product that will encrypt and
decrypt the input data by bit shift using a key.
Research method - software development.
Keywords: PROGRAMMING, C, BITTLE OPERATIONS, ENCRYPTION,
DECRIPHING, CYCLIC SHIFT ,.

2
Київський політехнічний інститут імені Ігоря Сікорського

Теплоенергетичний факультет

ЗАТВЕРДЖУЮ
В.о. зав. кафедри АПЕПС

____________ (Коваль О.В.)

«___» ____________ 2021 р.

ЗАВДАННЯ
на курсову роботу студента

групи ТР-з01, Крупського Андрія Максимовича

1. Тема роботи:
Програмна система для шифрування даних методом Бітового Зсуву.

2. Термін здачі студентом закінченого роботи: 23 квітня 2021 року.

3. Вихідні дані до роботи:


● Проаналізувати предметну область, виконати опис проектованої системи і
правил її функціонування.
● Розробити довідник та написати інформацію про програму, розробити
шифрування та дешифрування методом бітового зсуву.
3
4. Зміст пояснювальної записки (перелік питань, які розробляються):
вступ; постановка задачі; опис предметної області; опис програмної реалізації;
опис отриманих результатів; висновки; перелік умовних позначень; список
використаних джерел; додатки.

5. Перелік графічного матеріалу (з точним зазначенням обов’язкових рисунків):


Малюнок 1 – Схема роботи перших шифрів ; Малюнок 2 –
Сучасна система симетричного ключа; Малюнок 3 – Таблиця бітових операцій
; Малюнок 4 – Таблиця істинності; Малюнок 5 – Таблиця бітового зсуву

; Малюнок 6 – Таблиця бітової доповнюваності; Малюнок 7 – Таблиця зсуву;


Малюнок 8 – Таблиця Шифрування
6. Консультанти по роботі, з вказівкою розділів роботи, які до них відносяться

Розділ Консультант Підпис, дата


Завдання
Завдання видав
прийняв

7. Дата видачі завдання: 10 лютого 2021 року.


Керівник ________
(підпис)
Завдання прийняв до виконання ________
(підпис)

КАЛЕНДАРНИЙ ПЛАН

Найменування етапів Строк виконання


п/п Примітки
курсової роботи етапів роботи
1 Отримання завдання до КР 01.02.2021 - 12.02.2021
4
2 Вивчення предметної області 15.02.2021 - 28.02.2021
3 Презентація КР 01.03.2021 - 10.03.2021
4 Опис програмної реалізації 15.03.2021 - 18.03.2021
5 Розробка програмного 18.03.2021 - 27.03.2021
продукту
6 Здача програмного продукту 01.04.2021 - 03.04.2021
7 Написання розділу 1 у звіті з 04.04.2021 - 07.04.2021
КР
8 Написання розділу 2 у звіті з 08.04.2021 - 11.04.2021
КР
9 Перевірка КР на дотримання 12.04.2021 - 13.04.2021
норм
10 Перевірка КР на плагіат 14.04.2021 - 16.04.2021
11 Передача КР в архів КПІ 17.04.2021 - 18.04.2021
12 Захист курсової роботи 19.04.2021 - 21.04.2021

Студент: ____________
(підпис)

Керівник роботи: ____________


(підпис)

ЗМІСТ

ВСТУП 6

Для чого необхідна дешифрація 6

Наступний етап криптографії 8

1. Бітові операції 11

1.1 Основні бітові операції 11

1.2 Оператори зсуву 13

1.3 Оператори доповнення 14

5
2. Опис проектного рішення шифрування методом бітового зсуву 15

2.1 Алгоритм шифрування 15

2.2 Циклічний зсув 16

2.3 Обрана мова програмування 18

3. Налагодження та тестування системи, огляд результатів 19

3.1 Правила використання програми 19

3.2 Тестування ПЗ 19

3.3 Результати роботи програми 20

Висновки 22

Перелік використаних джерел 23

Додаток А 24

6
ВСТУП

Мета розробки та призначення ПЗ


Мета розробки ПЗ: Розробити програмний застосунок для швидкої та
автоматичної шифрації та дешифрації даних за допомогою методу бітового зсуву
Призначення ПЗ: Створення програми для використання у цілях безпеки
фішінгу особистих даних за допомогою шифрації

Вхідні та вихідні дані, очікувані результати


Вхідними даними є повідомлення яке необхідно зашифрувати та ключ за
допомогою якого це буде здійснюватись, а також ключ для дешифрації
Вихідними даними зашифроване повідомлення та шифроване повідомлення
з новим ключем (при задані однакових ключей буде коректно відновлено)
Після введення даних буде створено та закодована фраза яку ввів
користувач і наступним кроком буде її дешифрація

Для чого необхідна дешифрація

У нашому повсякденному житті криптографія використовується всюди.


Наприклад, ми використовуємо його для безпечної відправки паролів по великих
мереж для покупок в Інтернеті. Банківські сервери і поштові клієнти також
зберігають ваші паролі за допомогою криптографії. Криптографія
використовується для захисту всієї інформації, що передається в нашому світі,
підключеному до Інтернету речей, для аутентифікації людей і пристроїв, а також
пристроїв на інших пристроях.

Якби все криптографічні механізми / функції перестали працювати на один


день, сучасне життя, якою ми її знаємо, зупинилася б. Банківські транзакції не
будуть проходити, інтернет-трафік зупиниться, а стільникові телефони більше не
будуть працювати. У цей момент вся наша важлива інформація буде розкрита, і

7
потім її можна буде використовувати для нанесення неймовірного шкоди всім
нам.

Криптографія - важливий спосіб запобігти цьому. Він захищає інформацію і


комунікації за допомогою набору правил, які дозволяють тільки тим, кому це
призначено - і нікому іншому - отримувати інформацію для доступу до неї і її
обробки.

У минулі часи
Класично криптографія використовувала «безпеку за допомогою
невідомості» як спосіб зберегти передану інформацію в безпеці. У цих випадках
застосовується метод тримався в секреті від усіх, крім небагатьох, звідси і термін
«невідомість» .Це зробило спілкування безпечним, але реалізувати його в
широкому масштабі було непросто. Класичні криптографічні методи безпечні
тільки тоді, коли дві сторони можуть спілкуватися в безпечної екосистемі.

Малюнок 1.
На малюнку 1 ми показуємо класичну криптографічний систему.
Відправник і одержувач спочатку узгоджують набір загальних ключів

8
шифрування / дешифрування. Ці ключі потім використовуються послідовно для
шифрування і розшифровки кожного наступного повідомлення.

Одноразовий блокнот - це метод шифрування, який вимагає використання


попередньо виданого ключа, який можна використовувати тільки один раз. Для
шифрування і дешифрування необхідно використовувати один і той же ключ.
Термін «одноразовий блокнот» означає наявність кожної клавіші на сторінці
блокнота, який був використаний, а потім знищений. Після того, як загальні
ключі вичерпані, відправнику і одержувачу необхідно зустрітися в безпечному
місці, щоб безпечно обмінятися новим набором ключів, а потім зберегти їх в
безпечному місці на час наступного обміну повідомленнями.

Але ...

Ясно, що застарілі класичні методи більше не працюють. Необхідно


забезпечити безпеку великої системи електронного зв'язку, торгівлі та
інтелектуальної власності в океанах і на континентах, які в іншому випадку були
б перехоплені людьми з ворожими намірами.

Наступний етап криптографії


Отже, як реалізувати чудовий рівень безпеки в такій масивної системі, яка
може виконувати мільярди транзакцій за короткий період? Ось тут-то і
з'являється сучасна криптографія. Це важлива частина безпечного, але
доступного спілкування, критично важливого для нашого повсякденного життя.

Далі ми дізнаємося, як це досягається день у день всюди навколо нас. Ми


покладаємося на широко відомі алгоритми для захисту величезної кількості
інформації, якою обмінюються цілодобово. Ці алгоритми засновані на
стандартах і перевірені у відкритому середовищі, тому будь-які уразливості
можуть бути швидко виявлені і усунені.

9
Малюнок 2

На малюнку 2 показана спрощена сучасна криптографічна система. Давайте


розглянемо ці системи і алгоритми більш докладно.

Основний принцип сучасної криптографічної системи полягає в тому, що ми


більше не залежимо від секретності використовуваного алгоритму, а
покладаємося на секретність ключів. Сучасна криптографічний система
відповідає чотирьом основним цілям:

Конфіденційність: інформація ніколи не може бути розкрита кому-небудь, хто не


має права її бачити.

10
Ідентифікація та аутентифікація: перед обміном будь-якою інформацією
необхідно ідентифікувати і потім авторизувати відправника і одержувача.
Цілісність: інформація не повинна змінюватися при зберіганні або
транспортуванні. Будь-яка модифікація повинна бути виявленої.
Фіксація авторства: неможливо відмовитися від створення / передачі
повідомлення. Це забезпечує «цифрову» легітимність і відстеження транзакції.
Сучасні криптографічні системи надають все вищеперелічене або їх комбінацію
в різних формах для передбачуваного додатку. Давайте докладніше розглянемо
кожну з цих цілей, щоб отримати загальне уявлення про те, як вони досягаються.

11
1. Бітові Операції

1.1 Основні бітові операції

На противагу більшості мов, С підтримує всі існуючі бітові оператори.


Оскільки С створювався, щоб замінити асемблер, то була необхідність
підтримки всіх (або принаймні більшості) операції, які може виконати асемблер.
Бітові операції - це тестування, установка або зсув бітів в байті або слові, які
відповідають стандартним типам мови С char і int. Бітові оператори не можуть
використовуватися з float, double, long double, void і іншими складними типами.
Таблиця містить наявні оператори.

Малюнок 3
Бітові оператори І, АБО, НЕ використовують ту ж таблицю істинності, що і
їх логічні еквіваленти, за тим винятком, що вони працюють побитно. Що
виключає Або має наступну таблицю істинності:

Малюнок 4

Як випливає з таблиці, що виключає АБО видає істину, якщо тільки один з


операндів правдивий. В іншому випадку виходить брехня.
12
Бітові оператори найбільш часто застосовуються при розробці драйверів
пристроїв, наприклад програм для модемів, дисків і принтерів, оскільки бітові
оператори можуть використовуватися для виключення деяких бітів, наприклад
парності. (Біт парності використовується для підтвердження того, що інші біти в
байті не змінювалися. Він, як правило, є старшим бітом в байті.)

Бітове І найчастіше використовується для виключення бітів Тобто будь-який


біт, встановлений в 0, викликає установку відповідного біта в Другом операнде
також в 0. Наприклад, наступна функція читає символи з порту модему,
використовуючи функцію read_modem (), і скидає біт парності в 0 .

char get_char_from_modem (void)

char ch;

ch = read_modem (); / * Отримання символу з порту модему * /

return (ch & 127);

Парність відображається восьмим бітом, який встановлюється в 0 за


допомогою бітового І, оскільки біти з номерами від 1 до 7 встановлені в 1, а біт з
номером 8 - в 0. Вираз ch & 127 означає, що виконується бітова операція І між
бітами змінної ch і битами числа 127. У результаті отримаємо ch зі скинутим
старшим бітом. У наступному прикладі передбачається, що ch має символ 'А' і
має біт парності:

1.2 Оператори зсуву

13
Оператори зсуву >> і << зрушують біти в змінної вправо і вліво на вказане
число. Загальний вигляд оператора зсуву вправо:

змінна >> число зрушень

а загальний вигляд оператора зсуву вліво:

змінна << число зрушень

Пам'ятайте, що зрушення - це не те ж саме, що і обертання, тобто біти, що


зрушуються на один кінець, чи не з'являються з іншого. Зсунуті біти
втрачаються, а з іншого кінця з'являються нулі. У тому випадку, якщо вправо
зсувається негативне число, зліва з'являються одиниці (підтримується знаковий
біт).

Операції бітового зсуву можуть бути корисні при декодуванні інформації від
зовнішніх пристроїв і для читання інформації про статус. Оператори бітового
зсуву можуть також використовуватися для виконання швидкого множення і
ділення цілих чисел. Зрушення вліво рівносильний множенню на 2, а зрушення
вправо - поділу на 2, як показано в таблиці.

Малюнок 5

1.3 Оператор доповнення

14
Оператор доповнення, ~, інвертує стан кожного біта зазначеної змінної, тобто
1 встановлюється в 0, а 0 - в 1.

Бітові оператори часто використовуються в процедурах шифрування. Якщо є


бажання зробити дисковий файл нечитабельним, можна виконати над ним бітову
операцію. Одним з найпростіших методів є використання бітового доповнення
для інверсії кожного біта в байті, як показано нижче:

Малюнок 6

Треба звернути увагу, що в результаті виконання двох бітових доповнень


отримуємо вихідне число. Отже, перше доповнення створюватиме кодовану
версію байта, а друге буде декодувати.

Можна використовувати показану нижче функцію encode () для кодування


символу:

/ * Найпростіша шифрующая функція * /

char encode (code ch)

return (~ ch); / * Доповнення * /

15
2. Опис проектного рішення шифрування методом бітового зсуву

2.1 Алгоритм шифрування

Шиврування бітовим зсувом являє собою простий алгоритм шифрування


кожного байта інформації через зсув бітів на значення ключа, він дуже схожий
на шифр Цезара - коли кожна буква зсувається на декілька позицій, в
оригінальному вигляді - 3 символа вправо. Крок шифрування, що виконується
шифром Цезаря, часто включається як частина більш складних схем, таких як
шифр Віженера , і все ще має сучасне додаток в системі ROT13 . Як і всі
моноалфавітні шифри , шифр Цезаря легко зламуються і не має майже ніякого
застосування на практиці.

Але як було зазначено у матеріалу вище, простого зсуву буде недостатньо,


так як біти які будуть виходити за межі видимості будуть втрачені і відновити
інформацію стане неможливо, тому для цієї програми необхідно буде
реалізувати алгоритм циклічного зсуву

2.2 Циклічний зсув

Зсув може бути вліво або вправо. Кругова операція лівого зсуву зрушує
кожен біт в n -бітовом слові на k позиції вліво; крайні ліві k -біти видаляються
зліва і стають самими правими битами. Кругова операція правого зсуву зрушує
кожен біт в n -бітовом слові на k позицій вправо; найправіші k -біти справа
видаляються і стають крайніми лівими битами. Малюнок 7 показує і ліві і праві
операції в разі, де n = 8 і k = 3 .

16
циклічна операція зсуву змішує біти в слові і допомагає приховати зразки в
первісному слові. Хоча число позицій, на які біти будуть зрушені, може
використовуватися як ключ, циклічнаоперація зсуву зазвичай - без ключа;
значення k встановлюється і задається заздалегідь.

Оборотність . Циклічна операція лівого зсуву - інверсія операції правого зсуву.


Якщо одна з них використовується для шифрування, інша може застосовуватися
для дешифрування.

Властивості .Операція циклічного зсуву має дві властивості, які нам треба
знати.

Перша - це зміщення по модулю n . Іншими словами, якщо k = 0 або k = n ,


ніякого зсуву не відбувається. Якщо k є більшим, ніж n , тоді вхідна інформація
зрушена на k mod n біт. Друге властивість, операція циклічного зсуву над
з'єднанням операцій - є група. Це означає, що якщо зміщення робиться
неодноразово, то одне і те ж значення може з'явитися кілька разів ..

Малюнок 7
Заміна

Операція заміни - спеціальний випадок операції циклічного зсуву, де k = n / 2


означає, що ця операція можлива, тільки якщо n - парний номер. Оскільки зсув
вліво n / 2 - те ж саме, що зрушення n / 2 вправо, ця операція є оборотною.
Операція заміни для шифрування може бути повністю розкрита операцією
заміни для дешифрування. Малюнок 8 ілюструє операцію заміни для слова на 8
бітів.

17
Малюнок 8

Саме цю властивість ми і будемо використовувати для реалізації нашого


застосунку

2.2 Обрана мова програмування

C — універсальна, процедурна, імперативна мова програмування


загального призначення, розроблена у 1972 році Деннісом Рітчі у Bell Telephone
Laboratories з метою написання нею операційної системи UNIX.

Хоча С і було розроблено для написання системного програмного забезпечення,


наразі вона досить часто використовується для написання прикладного
програмного забезпечення.

С імовірно, є найпопулярнішою у світі мовою програмування за кількістю


вже написаного нею програмного забезпечення, доступного під вільними
ліцензіями коду та кількості програмістів, котрі її знають. Версії компіляторів
для мови С існують для багатьох операційних систем та апаратних архітектур. C
здійснила великий вплив на інші мови програмування, особливо на C++, яку
спочатку проектували як розширення для С, а також на Java та C#, які
запозичили у С синтаксис.

18
Мова програмування С використовує бібліотеки, як основний засіб свого
розширення. У С, бібліотека — набір функцій, котрі містяться в одному файлі.
Кожна бібліотека зазвичай має заголовний файл, в якому містяться прототипи
функцій, присутніх у бібліотеці, а також декларації спеціальних типів даних і
макро-символів, що використовують ці функції. Для того, щоб програма
використовувала бібліотеку, заголовний файл цієї бібліотеки має бути
оголошений вгорі файлу із сирцевим кодом, і бібліотека має бути злінкованою з
програмою, що у багатьох випадках вимагає спеціальної опції для компілятора
(наприклад, -lmath).

Загальною бібліотекою С є стандартна бібліотека С stdlib.h, що вказана у ISO та


ANSI C стандартах, і розповсюджується з кожним сучасним компілятором мови
С.

Іншим загальним набором функцій стандартної бібліотеки С є той, що


використовується застосунками. Проектувалися вони для UNIX-подібних
систем, у першу чергу, для забезпечення інтерфейсу до ядра. Ці функції
деталізуються у різноманітних стандартах, на кшталт POSIX та Single UNIX
Specification.

Відтоді, як С набула великої популярності, для неї було написано чимало інших
бібліотек. Бібліотеки часто пишуться на С, оскільки компілятори C генерують
ефективний об'єктний код; пізніше програмісти створюють інтерфейси до
бібліотек таким чином, що ті можуть використовуватися високорівневими
мовами, на кшталт Java, Perl та Python.

19
3. Налагоджування та тестування системи, огляд результатів

3.1 Правила використання програми

Для коректної роботи ПЗ необхідно дотримуватись певних норм та


обмежень заданими розробником.
Правила вводу повідомлення для шифрування:
● повідомлення має бути англійською мовою та/або цифри;
● забороняється використовувати відступи та інші символи.
● у ключі можно використовувати лише числа від 0 до 255

3.2 Тестування ПЗ

Тестування програмного забезпечення — процес перевірки


відповідності заявлених до продукту вимог і реально реалізованої
функціональності, здійснюваний шляхом спостереження за його роботою в
штучно створених ситуаціях і на обмеженому наборі тестів, обраних певним
чином.

Оскільки число можливих тестів навіть для нескладних програмних


компонентів практично нескінченне, тому стратегія тестування полягає в тому,
щоб провести всі можливі тести з урахуванням наявного часу та ресурсів. Як
результат програмне забезпечення (ПЗ) тестується стандартним виконанням
програми з метою виявлення багів (помилок або інших дефектів).

Тестування ПЗ може надавати об'єктивну, незалежну інформацію про


якість ПЗ, ризики відмови, як для користувачів, так і для замовників

Тестування може проводитись, як тільки створено виконуваний код (навіть


частково завершений). Процес розробки зазвичай передбачає, коли та як буде
відбуватися тестування. Наприклад, при поетапному процесі, більшість тестів
20
відбувається після визначення системних вимог і тоді вони реалізуються в
тестових програмах. На противагу цьому, відповідно до вимог гнучкої розробки
ПЗ, програмування і тестування часто відбувається одночасно.

3.3 Результати роботи програми

Як приклад було написано просте повідомлення “HelloWorld” і заданий


ключ 133

Малюнок 9

Далі йде процес розшифрування повідомлення та його виведення на екран.


Так як повідомлення шифрується на бітовому рівні, зазвичай це “сміття” яке
неможливо відтворити на екрані, проте воно містить корисну інформацію якщо
знати як його розшифрувати
Наступним кроком задаєм ключ за допомогою якого відновимо наше
повідомлення і після чого воно виведе його на екран

Малюнок 10

21
Висновки

Шифрування бітовим зсувом є одним з найпростіших шифрувань яке доволі


слабке для того щоб використовувалось у шифруванні важливих даних, проте
навіть таке шифрування вже надає деякий захист інформації щоб унеможливити
її дешифрування для простих користувачів. Проте бітові операції активно
використовуються у шифруванні складних крипто-алгоритмах завдяки своїй
швидкості, швидкість виконання бітових операцій в рази перевищує звичайних
арифметичних дій у коді, також використання мови програмування Сі дозволяє
використовувати цю швидкість максимально эффективно, так як біль сучасні
мови хоч і є більш розвиненими, проте їм бракує швидкості у настільки низько-
операційних діях. Сучасні алгоритми шифрування які використовують прямо
зараз є потужними застосунками або плагінами без яких існування сучасного
світу було б неможливе. Вивчення криптографії є одним з дуже перспективним
напрямком на даний момент у світі.

22
Перелік використаних джерел

1.  Stewart, Bill (2000-01-07). History of the C Programming Language. Living


Internet. Архів оригіналу за 2013-06-22. Процитовано 2006-10-31.
2. Alfred J. Menezes, Paul C. van Oorschot, Scott A. Vanstone. Handbook of
applied cryptography. — CRC-Press, 1996. — С. 32. — ISBN 0849385237.
3. Brian W. Kernighan and Dennis M. Ritchie: The C Programming Language,
2nd ed., Prentice Hall, 1988, c. 3.
4. Фомічов В. М. Дискретна математика і криптология : Курс лекцій / під ред.
Н. Д. Подуфалов - М. : Діалог-МІФІ , 2013. - 397 с. - ISBN 978-5-86404-185-7
5. Dennis Ritchie. The Development of the C Language. Архів оригіналу за
2013-06-22. Процитовано 2006-07-26.
6. Гатченко Н.А., Исаев А.С., Яковлев А.Д. Криптографическая защита
информации. — СПб : НИУ ИТМО, 2012. — 142 с.
7. Lester S. Hill. Concerning Certain Linear Transformation Apparatus of
Cryptography// "The American Mathematical Monthly", 1931, С. 135-154.
8. Стів Макконнелл "Досконалий код". БХВ-Петербург, 2004, 896 с.
9. Томас Кормен, Чарльз Лейзерсон, Рональд Ривест і Кліффорд Штайн
"Алгоритми: побудова й аналіз". Диалектика, 2020, 648 с.
10. Хант Ендрю, Томас Девід "Програміст-прагматик. Шлях від підмайстри до
майстра". Лори, 2020, 288 с.

11. Саймон Сінгх "Книга шифрів". ISBN 59459928, 1999, 416 с.

23
Додаток А

Весь програмний код розміщений за посиланням:


https://replit.com/join/upfbswkz-krypastork
Програмний код:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
/*#

int main(void)
{
char *men[] = {"1. New", "2. Find", "3. To Head", "4. To Tail", "5.
Next", "6. Previous", "7. Show", "8. List", "9. Insert", "10. Delete",
"11. Count", "12. Exit"};
int i = 0;
struct list *current = NULL;
while(1) //while of we not select "exit" button
{
if(!current)
printf("You not have any element, create one!\n");
else
printf("Now you on element #%d\n", current->number);
i = menu(men);
switch (i) // switch to menu row if is has or do nothing if is missed
{
case 1:
current = menuNew(current);
break;

case 2:
current = menuFind(current);
break;

case 3:
current = menuToHead(current);
24
break;

case 4:
current = menuToTail(current);
break;

case 5:
current = menuNext(current);
break;

case 6:
current = menuPrevious(current);
break;

case 7:
menuShow(current);
break;

case 8:
menuList(current);
break;

case 9:
current = menuInsert(current);
break;

case 10:
current = menuDelete(current);
break;

case 11:
menuCount(current);
break;

case 12:
menuExit();
break;

default:
break;
}
}
}

*/

25
struct list* menuToHead(struct list *arr);

struct data
{
char lastName[32];
char firstName[32];
char midleName[32];
char group[32];
char mobile[32];
unsigned short math;
unsigned short physic;
unsigned short english;
unsigned short literature;
};

struct list
{
struct data *d;
int number;
struct list *next;
struct list *prev;
};

// draw menu on console and wait for input


int menu(char **men)
{
int n;
int i;
printf("\n");
for(i = 0; men[i]; i++)
{
printf("%s\n", men[i]);
}
scanf("%d", &n);
if (n > i)
n = -1;
return n;
}

struct list* menuNew(struct list *arr)


{
struct data *data;
data = (struct data*)malloc(sizeof(struct data));

26
printf("Input Last Name:");
scanf("%31s", data->lastName);
printf("Input First Name:");
scanf("%31s", data->firstName);
printf("Input Father Name:");
scanf("%31s", data->midleName);
printf("Input Group:");
scanf("%31s", data->group);
printf("Input Mobile:");
scanf("%31s", data->mobile);
printf("Input Math:");
scanf("%hu", &data->math);
printf("Input Physic:");
scanf("%hu", &data->physic);
printf("Input Englis:");
scanf("%hu", &data->english);
printf("Input Literature:");
scanf("%hu", &data->literature);
if (!arr)
{
arr = (struct list *)malloc(sizeof(struct list));
arr->next = NULL;
arr->prev = NULL;
arr->d = data;
arr->number = 0;
return arr;
}
else
{
struct list *buf = menuToHead(arr);
int k = 0;
for (;buf->next; buf->next = buf->next->next){k++;}
buf->next = (struct list *)malloc(sizeof(struct list));
buf->next->next = NULL;
buf->next->number = k;
buf->next->prev = buf;
buf->next->d = data;

return buf->next;
}
}

void printFindMenu()
{

27
printf("insert number find key\n");
printf("1. LastName\n");
printf("2. FirstName\n");
printf("3. MidleName\n");
printf("4. Group\n");
printf("5. Mobile\n");
printf("6. Math\n");
printf("7. Physic\n");
printf("8. English\n");
printf("9. Literature\n");
}

struct list* menuFind(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
struct list* buf = arr;
int key;
printFindMenu();
scanf("%d", &key);
if (key <= 0 || key > 9)
{
printf("Invalid key\n");
return buf;
}
else if (key >= 6)
{
int num;
printf("Input key: ");
scanf("%d", &num);
arr = menuToHead(arr);
struct data* data;
for(;arr;arr = arr->next)
{
data = (struct data*)arr->d;
switch (key)
{
case 6 :
if (data->math == num)
{
printf("Search success element %d\n", arr->number);
return arr;

28
}
break;

case 7 :
if (data->physic == num)
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;

case 8 :
if (data->english == num)
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;

case 9 :
if (data->literature == num)
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;
}
}
}
else
{
char word[32];
printf("Input key: ");
scanf("%31s", word);
arr = menuToHead(arr);
struct data* data;
for(;arr;arr = arr->next)
{
data = (struct data*)arr->d;
switch (key)
{
case 1 :
if (!strcmp(word, data->lastName))
{
printf("Search success element %d\n", arr->number);

29
return arr;
}
break;

case 2 :
if (!strcmp(word, data->firstName))
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;

case 3 :
if (!strcmp(word, data->midleName))
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;

case 4 :
if (!strcmp(word, data->group))
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;

case 5 :
if (!strcmp(word, data->mobile))
{
printf("Search success element %d\n", arr->number);
return arr;
}
break;
}
}
}
printf("Not Found\n");
return buf;
}

struct list* menuToHead(struct list *arr)


{
if(!arr)

30
{
printf("Error list not found 404\n");
return NULL;
}
for (;arr->prev; arr = arr->prev){}
return arr;
}

struct list* menuToTail(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
for (;arr->next; arr = arr->next){}
return arr;
}

struct list* menuNext(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
return arr->next ? arr->next : arr;
}

struct list* menuPrevious(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
return arr->prev ? arr->prev : arr;
}

void menuShow(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return ;

31
}
struct data *data = (struct data*)arr->d;
printf("\nElement number %d:\n", arr->number);
printf("Last name: %s\n",data->lastName);
printf("First name: %s\n",data->firstName);
printf("Midle name: %s\n",data->midleName);
printf("Group: %s\n",data->group);
printf("Mobile: %s\n",data->mobile);
printf("Math: %d\n",data->math);
printf("Physic: %d\n",data->physic);
printf("English: %d\n",data->english);
printf("Literature: %d\n",data->literature);
}

void menuExit()
{
exit(0);
}

void menuList(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return ;
}
arr = menuToHead(arr);
for (;arr;arr = arr->next)
{
menuShow(arr);
}
}

struct list* menuInsert(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
if(arr->next)
{
struct list* buf = arr->next;

32
arr->next = NULL;
arr = menuNew(arr);
arr->next = buf;
for(;buf; buf = buf->next)
{
buf->number--;
}
}
else
{
arr = menuNew(arr);
}
return arr;
}

struct list* menuDelete(struct list *arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return NULL;
}
struct list* next;
struct list* prev;
struct list* buf;

next = arr->next;
prev= arr->prev;
buf = arr;

if(prev)
{
prev->next = next;
arr = prev;
}
if(next)
{
next->prev = prev;
arr = next;
}
free(buf->d);
free(buf);
for(;next; next = next->next)
{
next->number--;

33
}
return arr;
}

int menuCount(struct list* arr)


{
if(!arr)
{
printf("Error list not found 404\n");
return -1;
}
arr = menuToTail(arr);
printf("Number of element %d", arr->number + 1);
return arr->number + 1;
}

unsigned char encryptBite (unsigned char a, int offset)


{
return a >> offset | a << (8 - offset);
}

void encrypt(char *a, int key)


{
unsigned char *k = (unsigned char*)a;
key %= 8;
for (int i = 0; k[i]; i++)
{
k[i] = encryptBite(k[i], key);
}
}

unsigned char cryptBite (unsigned char a, int offset)


{
return a << offset | a >> (8 - offset);
}

void crypt(char *a, int key)


{
unsigned char *k = (unsigned char*)a;
key %= 8;
for (int i = 0; k[i]; i++)
{
k[i] = cryptBite(k[i], key);
}
}

34
int main(void)
{
char *a;
int key;

a = (char*)malloc(sizeof(char) * 64);
printf("Input your text:");
scanf("%s",a);
printf("Input your number key to crypt: ");
scanf("%d",&key);
crypt(a, key);
printf("crypted text :%s\n",a);
printf("Input your number key to encrypt: ");
scanf("%d",&key);
encrypt(a, key);
printf("encrypted text:%s\n",a);
}

35

You might also like