Tastatura defectă (9/10)
Autor: Alexandra Diaconu
Contextul dezastrului
În sediul nostru de maximă securitate, folosim o tastatură specială, proiectată să fie imposibil de hackuit. Din fabrică, ea este Ultra-Secure: de fiecare dată când apeși o tastă, sistemul alege la întâmplare un font complet diferit pentru a genera o imagine de 28 ✕ 28 pixeli a caracterului.
Totul mergea conform planului până într-o seară de marți, când administratorul de sistem a vărsat un cocktail de energizant și cafea direct în circuitele acestui hardware de mii de euro. Rezultatul? Tastatura a suferit un accident și acum mai are doar 12 taste funcționale, restul fiind stricate:
Litere: A, B, E, F, O, I
Cifre: 0, 1, 2, 4, 7, 8

Problema e că fiecare apăsare a acestor taste nu mai trimite un semnal curat (o imagine de 28✕28 pixeli) ci una alterată de un model de un zgomot fix și o rotație, unice pentru fiecare caracter.
Mai mult, sistemul are un mecanism de protecție la supratensiune: dacă un pixel încearcă să aibă o valoare mai mică de 0 sau mai mare de 255 din cauza zgomotului, hardware-ul îl forțează la 0, respectiv 255. Rezultatul? O pierdere iremediabilă de informație, de parcă tastatura ar încerca să ascundă dovezile accidentului.
Setul de date
1. Arhiva de calibrare (amprente_digitale)
Sunt „analizele de sânge” ale tastaturii imediat după incident. Fișierul conține 50 de perechi (în total 600 de imagini cu numele 0_01.png, 0_02.png etc.) pentru fiecare din cele 12 taste.
Acestea sunt imagini de 42 ✕ 84 pixeli reprezentând o pereche [original | transformat].
Exemple de calibrare
| Caracter | Tip | Exemplu |
|---|---|---|
| E | Literă | ![]() |
| 0 | Cifră | ![]() |
| 1 | Cifră | ![]() |
| 7 | Cifră | ![]() |
Imaginea alterată a fost obținută prin:
- adăugarea unui zgomot cu valori în intervalul
[-25, +25]doar în zona centrală - fiecare imagine de
28×28 pixelia fost plasată centrat într-un canvas negru de42×42 pixeli - canvas-ul a fost rotit cu un unghi fix per caracter din intervalul
[-30, 30]
2. Arhiva de referință (imagini_antrenare)
Acestea sunt mostre de caractere „sănătoase”:
- 500 de imagini pentru fiecare literă și cifră
- dimensiune:
28 ✕ 28 pixeli - salvate dintr-un backup vechi
Exemple de referință
| Caracter | Tip | Exemplu |
|---|---|---|
| B | Literă | ![]() |
| 0 | Cifră | ![]() |
3. Setul de imagini suspecte (imagini_suspecte)
Acesta este un set de imagini brute extrase din sistem după incident.
Folderul imagini_suspecte conține:
- imagini individuale grayscale;
- fiecare imagine reprezintă un singur caracter;
- imaginile sunt deja afectate de transformările tastaturii defecte (rotație, zgomot, clipping).
Nu toate imaginile provin din tastatura avariată.
Sistemul a fost expus și la alte surse externe, astfel încât în acest set pot apărea:
- caractere valide (generate de cele 12 taste funcționale);
- caractere invalide (orice altă literă sau cifră).
4. Registrul de acces (parole)
Acesta este fluxul de date brute capturat în timp real de la terminalul defect.
Conține:
- 300 de încercări de autentificare
Realitatea din teren:
- parolele au 3, 5 sau 7 caractere
- imaginile sunt deja alterate de zgomot și rotație

Protocolul de urgență: validarea prin „cheie majoritară”
Sistemul de securitate a intrat într-un mod degradat.
Pentru că hardware-ul este prea avariat pentru a recunoaște fiecare caracter cu precizie, s-a activat o metodă bazată pe vot majoritar.
Votul de supraviețuire:
- Dacă un caracter prezis ∈ {A, B, E, F, O, I} → votează letters
- Dacă un caracter prezis ∈ {0, 1, 2, 4, 7, 8} → votează digits
Validarea parolei:
Sistemul verifică doar „natura majoritară” a parolei.
Exemplu:
- Parolă de 3 caractere → predicții: (Litere, Cifră, Litere)
- Majoritate → letters
Dacă eticheta coincide cu cea din baza de date → acces permis.
Misiunile tale
Misiunea 1 - Identificarea unghiului de rotație (10p)
Folosind datele din arhiva de calibrare (amprente_digitale), determinați unghiul de rotație asociat fiecărui caracter.
Pentru fiecare caracter trebuie identificat:
unghi_rotatie ∈ [-30°, +30°]
Pe baza acestor rezultate veți construi un dicționar de forma:
{
"A": <valoare_unghi>,
"B": <valoare_unghi>,
"E": <valoare_unghi>,
...
"8": <valoare_unghi>
}
Misiunea 2 - Identificarea zgomotului (10p)
Folosind datele din arhiva de calibrare (amprente_digitale), determinați modelul de zgomot asociat fiecărui caracter.
Pentru fiecare dintre cele 12 caractere funcționale, imaginea transformată conține o perturbare adăugată peste forma originală, iar această perturbare este specifică acelui caracter.
Pentru fiecare caracter trebuie identificat:
zgomot_caracter
Acest zgomot reprezintă componenta de alterare aplicată imaginii caracterului înainte de obținerea versiunii finale corupte.
Pe baza acestor rezultate veți construi un dicționar de forma:
{
"A": <zgomot_A>,
"B": <zgomot_B>,
"E": <zgomot_E>,
...
"8": <zgomot_8>
}
unde fiecare valoare asociată unui caracter descrie zgomotul specific aplicat acelui caracter.
Misiunea 3 - Validarea imaginilor suspecte (30p)
Primești un folder cu imagini grayscale suspecte (imagini_suspecte), fiecare reprezentând un singur caracter.
Pentru fiecare imagine, trebuie să decizi dacă aceasta aparține unuia dintre cele 12 caractere care încă pot fi produse de tastatura defectă.
Astfel, pentru fiecare imagine vei atribui una din următoarele etichete:
1- dacă imaginea conține un caracter care poate fi generat de tastatura modificată, adică unul dintre:
A, B, E, F, O, I, 0, 1, 2, 4, 7, 8
0- dacă imaginea conține orice alt caracter.
Misiunea 4 - Decriptarea parolelor (50p)
Sistemul de autentificare funcționează într-un mod degradat și nu mai verifică parolele la nivel de caracter exact. În schimb, decizia finală se bazează pe tipul majoritar de caractere din fiecare parolă.
Folosind datele disponibile, determinați pentru fiecare imagine din folderul parole natura sa finală:
letters sau digits
Fiecare caracter aparține uneia dintre categoriile:
- letters:
A, B, E, F, O, I - digits:
0, 1, 2, 4, 7, 8
Pentru fiecare parolă trebuie să determinați categoria majoritară a caracterelor.
Eticheta finală:
letters— dacă majoritatea caracterelor sunt literedigits— dacă majoritatea caracterelor sunt cifre
Fișierul de submisie
Formatul fișierului de submisie
Submisia trebuie să fie un fișier arhivă .zip care conține exact următoarele două fișiere:
amprente_digitale.npyparole.csv
1. Fișierul amprente_digitale.npy
Acest fișier este folosit pentru Misiunea 1 și Misiunea 2 și trebuie să conțină un dicționar cu informațiile estimate pentru fiecare dintre cele 12 caractere:
A, B, E, F, O, I, 0, 1, 2, 4, 7, 8
Structura trebuie să fie de forma:
{
"A": {
"angle": <valoare_unghi>,
"noise": <matrice_28x28>
},
"B": {
"angle": <valoare_unghi>,
"noise": <matrice_28x28>
},
...
"8": {
"angle": <valoare_unghi>,
"noise": <matrice_28x28>
}
}
Cerințe:
- pentru fiecare caracter trebuie să existe cheia angle
- pentru fiecare caracter trebuie să existe cheia noise
- valoarea asociată lui noise trebuie să fie o matrice de dimensiune
28 ✕ 28
2. Fișierul parole.csv
Acest fișier este folosit pentru Misiunea 3 și Misiunea 4 și trebuie să conțină exact următoarele coloane:
file: numele fișierului pentru care a fost realizată predicția;subtaskID: indicele misiunii (va avea valoarea3sau4);class: clasa prezisă pentru acel fișier.
Exemplu
file,subtaskID,class
task3_000.png,3,1
task3_001.png,3,0
task4_000.png,4,letters
task4_001.png,4,digits
Convenții pentru coloana class
Pentru Misiunea 3
Înregistrările cu subtaskID = 3 trebuie să aibă:
1— dacă imaginea conține un caracter valid al tastaturii defecte0— altfel
Pentru Misiunea 4
Înregistrările cu subtaskID = 4 trebuie să aibă:
lettersdigits
în funcție de categoria majoritară a caracterelor din parola respectivă.
Observații importante
- Arhiva
.ziptrebuie să conțină ambele fișiere la rădăcină:amprente_digitale.npyparole.csv
- Numele fișierelor trebuie să fie respectate exact.
- Orice abatere de structură sau format poate duce la invalidarea submisiei.
Notă
În starter kit este disponibilă o funcție care primește ca argumente rezultatele pentru:
- Misiunea 1 (unghiurile de rotație)
- Misiunea 2 (modelele de zgomot)
și generează automat fișierul amprente_digitale.npy în formatul corect.
Evaluare
Misiunea 1
Punctajul se acordă după cum urmează:
score = 10 (dacă MAE ≤ 0)
score = 10 × (1 - MAE / 1) (dacă 0 < MAE < 1)
score = 0 (dacă MAE ≥ 1)
Misiunea 2
Punctajul se acordă după cum urmează:
score = 10 (dacă MAE ≤ 2.5)
score = 10 × (1 - MAE / 10) (dacă 2.5 < MAE < 10)
score = 0 (dacă MAE ≥ 10)
Misiunea 3
Punctajul se acordă după cum urmează:
score = 0 (dacă Accuracy ≤ 0.50)
score = 30 × (Accuracy - 0.50) / (0.80 - 0.50) (dacă 0.50 < Accuracy < 0.80)
score = 30 (dacă Accuracy ≥ 0.80)
Misiunea 4
Punctajul se acordă după cum urmează:
score = 0 (dacă Accuracy ≤ 0.50)
score = 50 × (Accuracy - 0.50) / (0.93 - 0.50) (dacă 0.50 < Accuracy < 0.93)
score = 50 (dacă Accuracy ≥ 0.93)





