Table of Contents

Tema 2 - ACS Cat Invasion

Enunț

Patru pisici au invadat Facultatea de Automatică și Calculatoare. Țelul lor este să acapareze toate clădirile facultății fără a fi descoperite. Rolul vostru e de a le ajuta să se plimbe prin campus neobservate. Pentru a considera o clădire cucerită, trebuie să le ajutați să rezolve câte o problemă întrucât ele nu știu să scrie cod în limbaj de asamblare.

Structură și detalii de implementare

Tema este formată din 4 exerciții independente. Fiecare task constă în implementarea unei sau mai multor funcții în limbaj de asamblare. Implementarea se realizează în fișierele puse la dispoziție pentru fiecare exercițiu.

Parametrii funcţiilor sunt plasaţi în registre, în cadrul scheletului.

Scheletul include şi macro-ul PRINTF32, folosit în laborator, pentru a vă ajuta la depanarea problemelor. Tema finală nu trebuie să facă afişări folosind PRINTF32, funcții externe sau apeluri de sistem.

În tema finală este interzisă apelarea funcţiilor externe.

IOCLA RULZ!


1. Simple cipher - 10p

Sursee dorește să ajungă pe catedra din PR001 așa că trebuie să trimită mesaje criptate studenților că să afle cine o poate ajuta. Ea vrea să folosească simple cipher pentru a transmite mesajele.

Acest algoritm de criptare presupune shiftarea la dreapta în cadrul alfabetului a fiecărui caracter de un anumit număr de ori. De exemplu, textul ANABANANA se transformă în BOBCBOBOB când pasul este 1. Astfel, o criptare cu pasul 26 nu modifică litera, întrucât alfabetul englez are 26 de caractere.

Pentru acest task va trebui să implementați în fișierul simple.asm funcția simple(), care criptează un string folosind metoda descrisă mai sus.

Antetul funcției este:

 void simple(int n, char* plain, char* enc_string, int step) 

Semnificația argumentelor este:

Pentru ușurință se vor folosi doar majusculele alfabetului englez (A-Z), iar shiftarea se realizează strict în cadrul alfabetului englez cu o limită de 26 pentru step.

Here is Sursee


2. Points - 25p

Diablo, mâncăciosul, vrea să ajungă la cantina din EC pentru a-și pune lăbuțele pe un meniu de mâncare proaspătă. Ajutați-l să găsească cel mai scurt drum de la intrarea în facultate până la cantină.

Prin intermediul acestui task se dorește aprofundarea lucrului cu structuri.

Se dă structura unui punct în coordonate carteziene:

struct point{
    short x;
    short y; 
};

Înainte de rezolvarea acestui task, recomandăm parcurgerea laboratorului 7

https://ocw.cs.pub.ro/courses/iocla/laboratoare/laborator-07

  • Pentru obținerea punctalului maxim pe acest task trebuie realizate toate exercițiile.
  • Punctajul pentru ex 2 nu se acordă fără rezolvarea exercițiului 1, iar pentru exercițiul 3 trebuie rezolvate și exercițiile 1 și 2

a) Points distance - 5p

Pentru această parte a task-ului aveți de implementat funcția points_distance() din fișierul points-distance.asm, care va calcula distanța dintre două puncte aflate pe o dreapta paralelă cu axele OX sau OY.

Antetul funcției este:

void points_distance(struct point *p, int *rez);

Semnificația argumentelor este:

b) Road - 7.5p

În continuarea exercițiului 1, acum trebuie să implementati funcția road() din fișierul road.asm, care va calcula distanța dintre punctele dintr-un vector. Astfel, pentru un vector de 4 puncte (A,B,C,D), se vor calcula 3 distanțe: *A-B* , *B-C*, *C-D*. Perechile de puncte se află pe drepte paralele cu axele.

Antetul funcției este:

void road(struct point* points, int len, int* distances);

Semnificația argumentelor este:

Lungimea vectorului de distanțe este cu 1 mai mică decât lungimea vectoului de puncte.

Este permisă utilizarea funcției implementate la punctul a pentru realizarea acestui exercițiu.

c) Is square - 12.5p

Ultima parte a task-ului presupune analizarea fiecărei distanțe calculate anterior pentru a determina dacă este pătrat perfect. Trebuie să implementati funcția is_square() din fișierul is_square.asm.

Antetul funcției este:

void is_square(int *dist, int n, int *rez);

Semnificația argumentelor este:

Un pătrat perfect va fi notat cu 1, iar restul numerelor cu 0.

Have a look at Diablo


3. Beaufort Encryption - 25p

Swaro a aflat că cifrul folosit de Sursee a fost spart, așa că vă roagă să îi trimiteți mesaje cifrate folosind criptarea Beaufort, pentru a nu îi fi descoperit planul de a se infiltra în corpul ED.

Algoritmul de criptare Beaufort pleacă de la un string în clar (numit și plain text) și un string secundar (numit cheie) și obține un text criptat, de lungime identică cu string-ul în clar, prin înlocuirea caracter cu caracter a literelor din textul inițial.

De exemplu, să zicem că vrem să criptăm textul DEFENDTHEEASTWALLOFTHECASTLE, utilizând cheia FORTIFICATION.

Regula după care se face înlocuirea folosește o matrice de caractere, numită tabula recta, în care fiecare linie și fiecare coloană au asociate câte o literă a alfabetului limbii engleze. Aceasta are formatul de mai jos:

Criptarea fiecărui caracter se realizează aplicând următorii pași:

    DEFENDTHEEASTWALLOFTHECASTLE
    FORTIFICATIONFORTIFICATIONFO

Pentru caracterul D:

Criptând fiecare caracter folosind pașii de mai sus, obținem string-ul criptat. Pe exemplul nostru:

 CKMPVCPVWPIWUJOGIUAPVWRIWUUK 

Pentru acest task, va trebui să implementați în fișierul beaufort.asm funcția beaufort() care criptează un string în clar, folosind metoda descrisă mai sus.

Antetul funcției este:

void beaufort(int len_plain, char *plain, int len_key, char *key, char tabula_recta[26][26], char *enc)

Semnificația argumentelor este:

În funcție de cum considerați că vă e mai ușor, puteți evita utilizarea argumentului *char tabula_recta[26][26]*, utilizând anumite corelări logice între linia și coloana matricii și conținutul ei. Ambele metode de rezolvare vor fi considerate la fel de corecte.

Swaro sais HI


4. Spiral Encryption - 30p

Îngeraș, care este capul răutăților, vrea să cucerească toate laboratoarele din EG. Știe că are nevoie de o modalitate sigură de a transmite mesaje celorlalte pisici. Ajutați-o să trimită mesaje folosind spiral encryption.

O criptare prin substituție (în care înlocuim caracter cu caracter literele din textul în clar) e cu atât mai eficientă cu cât unui atacator îi e mai greu să decodifice mesajul inițial, chiar dacă are acces la cheie și la mesajul criptat. Pentru asta, putem alege moduri cât mai “ezoterice” de utilizare a cheii, iar spiral encryption e un algoritm care face tocmai acest lucru.

Vom pleca de la un text în clar de dimensiune N ^ 2. Cheia în acest caz va fi o matrice de întregi de dimensiune N * N. Un caracter din textul în clar va fi criptat adunând la codul său ASCII valoarea întreagă din cheie care îi corespunde. Spre exemplu, dacă pentru caracterul `A` avem asociată în cheie valoarea 2, caracterul criptat va fi `C`. De asemenea, dacă avem caracterul `Z` cu cheia asociată 1, caracterul criptat va fi `[`.

Partea specială la acest algoritm este modul în care asociem caracterelor din textul plain valori din cheie. Pentru asta, vom parcurge textul în clar secvențial (de la primul la ultimul caracter), iar în același timp vom parcurge cheia în spirală, similar cu figura de mai jos:

Astfel, ținând cont de dimensiunea matricii care reprezintă cheia și de dimensiunea textului (mereu vor fi corelate astfel încât numărul de elemente din matrice să fie egal cu numărul de litere din text) obținem întregul text criptat.

Pe exemplul de mai sus, rezultatul va fi:

MUeVSVWb\i^KU^DYbbLYXRH_D

Sarcina voastră este să completați funcția spiral() din fișierul spiral.asm, astfel încât aceasta să cripteze un text în clar cu ajutorul unei chei date, folosind algoritmul prezentat mai sus. Antetul funcției este:

void spiral(int N, char *plain, int key[N][N], char *enc_string)

Semnificația argumentelor este:

Ingeras is happy

Precizări suplimentare

În schelet este inclus şi checker-ul, împreună cu testele folosite de acesta. Pentru a executa toate testele, se poate executa direct scriptul `checker.sh` din rădăcina temei:

./checker.sh

Pentru a testa task-uri individual, folosiți:

./checker.sh <număr_task>

Pentru a scrie rezolvarea unui task, intrați în directorul asociat task-ului respectiv și scrieți cod în fișierele în limbaj de asamblare indicate în enunț. NU modificați alte fișiere C, script-uri etc!

Formatul fişierelor de intrare pentru Simple Cipher este:

len_plaintext 
step
plaintext

Formatul fişierelor de intrare pentru Points este:

nr_points
points

Formatul fişierelor de intrare pentru Beaufort Encryption este:

len_plaintext len_key
plaintext
key

Formatul fişierelor de intrare pentru Spiral Encryption este:

N
plain
key

În cadrul unora din cele 4 task-uri, va trebui să accesați valori de pe o anumită linie și coloană dintr-o matrice. Știți deja de la laborator cum să accesați date dintr-un vector. Accesarea valorilor din matricea alocată static este similară, deoarece chiar dacă noi o gândim ca fiind reprezentată pe linii și coloane, în realitate ea este reprezentată în memorie continuu. Tot ce trebuie să facem e să găsim un mod de a transforma linia și coloana într-un singur index.

Pentru matricea alocată static:
1 2 3
4 5 6
7 8 9
Avem de fapt în memorie un șir continuu de forma:
1 2 3 4 5 6 7 8 9

Trimitere și notare

Temele vor trebui încărcate pe platforma vmchecker (în secțiunea IOCLA) și vor fi testate automat.

Arhiva încărcată va fi o arhivă .zip care trebuie să conțină:

Punctajul final acordat pe o temă este compus din:

Coding style-ul constă în:

  • prezența comentariilor în cod
  • scrierea unui cod lizibil
  • indentarea consecventă
  • utilizarea unor nume sugestive pentru label-uri
  • scrierea unor linii de cod/README de maxim 80-100 de caractere

Pentru detalii despre coding style parcurgeti acest document: http://www.sourceformat.com/pdf/asm-coding-standard-brown.pdf

Temele care nu trec de procesul de asamblare (build) nu vor fi luate în considerare.

Mașina virtuală folosită pentru testarea temelor de casă pe vmchecker este descrisă în secțiunea Mașini virtuale din pagina de resurse.

Vă reamintim să parcurgeți atât secțiunea de depunctări cât și regulamentul de realizare a temelor.

FAQ

Resurse

Scheletul şi checker-ul sunt disponibile pe repository-ul de IOCLA.