Milstolpe: Caesar-chiffret

Uppdraget

Det här är en inlämningsuppgift som bedöms, men vi arbetar som på riktigt: förstå problemet, bygg i små steg, testa, lämna ifrån dig något som fungerar.

Du ska bygga ett Caesar-chiffer En substitutionsalgoritm där varje bokstav i klartexten ersätts av bokstaven ett fast antal positioner längre fram i alfabetet. Uppkallat efter Julius Caesar och ett av historiens äldsta dokumenterade kryptosystem. Se: Milstolpe: Caesar-chiffret för svenska. Algoritmen är från romarriket, där Julius Caesar lär ha krypterat militär kommunikation genom att förskjuta varje bokstav ett fast antal steg i alfabetet. Med nyckeln 1 blir a till b, och hej blir ifk.

Ur ett modernt säkerhetsperspektiv är chiffret inte mycket att ha. Som programmeringsuppgift är det däremot ett lärorikt program du kan skriva, för det kräver att du får funktioner, loopar, villkor, position och modulus att samarbeta i ett och samma system.

Uppgiften är svårare än den ser ut. Ta den i små steg, och testa efter varje.

Verktygen du redan har

Allt du behöver är sådant du mött tidigare i kursen. Läs inte hela listan på en gång och försök inte få in allt i första försöket. Verktygen kommer in där de behövs, och stegen längre ner säger när.

För att få kärnan att fungera (steg 1):

  • Alfabetet som en sträng. Du skriver alfabetet själv, som en vanlig sträng. Då blir varje bokstav en plats i en sekvens, och det svenska alfabetet får sina 29 bokstäver i rätt ordning.
  • Position och modulus från Position och modulus: .index() ger dig platsen för en bokstav, hakparenteser ger dig bokstaven på en plats, och % len(alfabet) ser till att räkningen börjar om i stället för att gå utanför kanten.
  • Transformationen på Mönsterkortet: gå igenom varje tecken, bearbeta det, bygg upp ett resultat. Det är samma ackumulering som Samlaren, fast med en sträng i stället för en lista.

När kärnan fungerar:

  • Funktioner som svarar från Funktionen svarar, behövs i steg 2 och 4: dina funktioner ska returnera den krypterade texten, inte skriva ut den. Tillsammans med importen från Ditt eget bibliotek är det som gör att du kan använda dem igen i Etik & brute force.
  • Vakten på Mönsterkortet, behövs i steg 3: kontrollera först, räkna sedan. Ett mellanslag finns inte i alfabetet, och .index() på något som inte finns ger ValueError.

Kör du fast är det den här listan du går tillbaka till, ett verktyg i taget.

En bokstav i taget

Den svåraste raden är den första, så här är den. Så här förskjuts en enda bokstav ett steg:

Editor

Redo.

Läs de tre mittersta raderna som en kedja. alfabet.index("h") svarar 7, alltså står h på plats 7. (7 + 1) % 29 blir 8. Och alfabet[8] är i. Bokstaven blev nästa bokstav i alfabetet, vilket är precis vad chiffret gör.

Prova innan du går vidare: byt bokstaven till ö och kör. Byt sedan nyckeln till 3 och kör igen. Modulus gör att det fungerar även när du går förbi alfabetets slut.

Alfabetet som en ring: en förskjutning som passerar ö fortsätter om från aa0bc2def5ghijk10lmnop15qrstu20vwxyz25åäö28tre steg från ö(28 + 3) % 29 = 2

Så ser den körningen ut. ö står på plats 28, och tre steg framåt hamnar utanför alfabetet: plats 31 finns inte. % 29 kastar bort det hela varvet och lämnar resten, alltså plats 2, som är c. Alfabetet beter sig som en klocka, och det är därför du inte behöver skriva en enda if för kanten.

Resten av uppdraget är att göra samma sak för varje bokstav i ett helt meddelande, och att samla ihop resultatet.

Uppdraget, steg för steg

Skapa filen caesar.py.

  1. Få ut ifk. Utgå från koden nedan. Skriv en loop som går igenom meddelande bokstav för bokstav, förskjuter varje bokstav med nyckeln och bygger upp resultat. När programmet skriver ut ifk har du löst kärnan i uppgiften.
alfabet = "abcdefghijklmnopqrstuvwxyzåäö"
meddelande = "hej"
nyckel = 1
resultat = ""

# Skriv din loop här. Programmet ska skriva ut "ifk".

print(resultat)
  1. Gör om det till en funktion. Skriv kryptera(text, nyckel) som gör samma sak men returnerar resultatet i stället för att skriva ut det. Testa med print(kryptera("hej", 1)).

  2. Sätt dit vakten. Testa kryptera("hej hej", 1). Programmet kraschar, för mellanslaget finns inte i alfabetet och .index() vägrar. Lägg in en kontroll som låter tecken som inte finns i alfabetet passera igenom oförändrade.

  3. Skriv dekryptera(text, nyckel). Den ska ta en krypterad text och ge tillbaka originalet. Kom ihåg att modulus i Python hanterar negativa tal åt dig.

  4. Testa hela vägen runt. Kryptera en mening du hittar på, dekryptera resultatet och kontrollera att du får tillbaka exakt det du började med.

  5. Committa längs vägen, minst en gång per steg ovan, via Source Control-panelen i VS Code.

Krav

  • Filen heter caesar.py och innehåller funktionerna kryptera(text, nyckel) och dekryptera(text, nyckel). Namnen är viktiga, du importerar dem i Etik & brute force.
  • Båda funktionerna returnerar sitt resultat. Utskrifterna sker i koden som anropar dem.
  • Programmet klarar hela meningar med mellanslag och skiljetecken, utan att krascha och utan att kryptera det som inte är bokstäver.
  • Alfabetet är svenskt, alla 29 bokstäverna, och nyckeln fungerar för valfritt tal.
  • Koden är pushad till GitHub med minst fyra commits som visar hur programmet växte fram.

Uppgift: Caesar-chiffret

Detta ska lämnas in

caesar.py pushad till ditt repo, tillsammans med en README.md. Kopiera mallen nedan och fyll i den:

# Caesar-chiffret

## Så använder du programmet

(Beskriv hur man kör det och vad som händer.)

## Mönster jag använde

- Transformationen:
- Vakten:
- (fler mönster du känner igen)

## Det som var svårast

(Vilket steg fastnade du på, och hur löste du det?)

## Om jag hade mer tid

(Vad hade du byggt vidare på?)

Att namnge mönstren är ingen formalitet. Det är beviset på att du ser vad du byggt: samma Transformation kommer tillbaka varje gång du bearbetar en sekvens, resten av tiden du skriver kod.

Bedömningssamtal

Vi går igenom koden tillsammans. Koden visar vad du byggde, samtalet visar att du förstod varför, och båda påverkar bedömningen. Räkna med frågor som:

  • Varför behövs modulus? Visa vad som händer utan den.
  • Vad gör % len(alfabet) som % 29 inte gör?
  • Var i koden sitter vakten, och vad hade hänt om den stod någon annanstans?
  • Dekrypteringen tar emot samma nyckel som krypteringen. Hur kommer det sig att den ändå går åt andra hållet?
Nästa nivå

Gör programmet robust. Skicka in "Hej, vad gör du idag!?" och få tillbaka något som bevarar formateringen exakt: stor bokstav där det var stor bokstav, kommatecken på rätt plats, inga krascher. Du behöver .isupper(), .lower() och .upper(), samt en kontroll av typen if bokstav.lower() in alfabet:.

En sista sak att fundera på, oavsett om du tar utmaningen: för engelskans 26 bokstäver finns nyckeln 13, som krypterar och dekrypterar likadant eftersom 13 plus 13 blir ett helt varv. Finns det någon sådan nyckel för vårt alfabet med 29 bokstäver?