ÖVNINGSUPPGIFT

Uppgift 7 - Dekryptering

Försök själv först. Ledtrådar och facit finns längre ner – helt utan inloggning.


Nyckelord: Metoder

Konstanter och säkerhet

Dekryptering

I denna uppgift ska vi skapa en metod för att dekryptera hemliga meddelanden. För att underlätta problemet, utesluter vi å, ä och ö då dessa tecken inte är standard i några av de metoder vi ska använda. Vi utgår även från att vi enbart använder gemener (små bokstäver).

A: Läs tecken som ett tal

Character.getNumericValue ger ett teckens numeriska värde enligt metodens regler. För a–z är värdena 10–35. Det är inte tecknets Unicode-kodpunkt; exempelvis har a siffervärdet 10 men kodpunkten 97.

Använd din metod och avgör vad tecknet u motsvarar.

Kontrollera ditt svar

Rätt svar: 30


B: Är vokal

Skriv en metod isVowel() som får in ett tecken och returnerar om tecknet är en vokal eller inte.

C: Minska med två

Skapa en metod decreaseNumberWith2() som tar in ett heltal och minskar detta med 2. Metoden ska returnera resultatet.

D: Öka med två

Skapa en metod increaseNumberWith2() som tar in ett heltal och ökar detta med 2. Metoden ska returnera resultatet.

E: Konvertera tal till tecken

Skriv en metod intToChar() som använder Character.forDigit(i, 36). Talet 36 är talbasen, inte en förskjutning i Unicode: siffrorna 0–9 följs av a–z för värdena 10–35. Metoden ger nolltecknet om värdet ligger utanför talbasen.

F: Dekryptera

Skriv en metod decrypt() som tar in ett tecken och dekrypterar tecknet enligt nedanstående specifikation:

  • Omvandla tecknet till ett tal.
  • Om tecknet är en vokal ska siffran två adderas till talet.
  • Om tecknet är en konsonant ska siffran 2 subtraheras från talet.
  • Konvertera talet till unicode-format.

Metoden ska returnera det dekrypterade tecknet.

G: Avkryptera meddelande

Skriv ett program som använder ovanstående metoder för att avkryptera ett meddelande. Programmet ska ta en textsträng och gå igenom tecken för tecken i meningen. Varje tecken ska bytas ut mot resultatet i metoden decrypt().

Testa programmet genom att avkryptera textsträngen lce eknnct mqtx.

Vad blir resultatet?

Kontrollera ditt svar

Rätt svar: jag gillar korv

H: Analys

Fundera lite på algoritmen för dekrypteringen. I vilka fall skulle denna algoritm inte fungera?

Ledtråd A

Exempelvis i nedanstående kod, omvandlas tecknet h till dess motsvarande siffra i unicode-format.

int numericValue = Character.getNumericValue('h');
Ledtråd B

Använd en if-sats eller en switch-sats för att avgöra om ett tecken är en vokal eller inte.

Ledtråd C, D

Skriv en metod som tar in ett heltal och returnerar resultatet av den matematiska operationen. Exempelvis:

static int increaseNumberWith4(int num){
    return num + 4;
}
Ledtråd E

Skriv en metod som tar in ett heltal och returnerar en char. Exempelvis i nedanstående kod, där i = 10, blir variabeln ch = a.

int i = 10;
char ch = Character.forDigit(i, 36);
Ledtråd F

Skriv en metod som använder redan skrivna metoder för att skapa dekrypteringsmetoden.

Ledtråd G

Börja med att skapa en loop som går igenom varje tecken i en textsträng. Du kan använda dig av koden

Character ch = cryptedMessage.charAt(i);

för att plocka ut ett specifikt tecken i meningen, där i är indexet på det tecknet du vill plocka ut. Exempelvis charAt(0) plockar ut första tecknet i textsträngen cryptedMessage.

Använd sedan en if-sats för att kontrollera om tecknet är ett mellanslag, annars, kör dekrypteringsmetoden. Spara undan resultatet i en ny textsträng och skriv ut resultatet.

Ledtråd H

Fundera vad som händer om man försöker använda tecken i slutet och början av alfabetet.

Lösning

Nedanstående kod visar ett exempel på hur man kan lösa uppgiften. Observera att detta bara är ett exempel och att uppgiften går att lösa på flera sätt.

public class Uppgift7 {
    public static void main(String[] args) {

        // Hemligt meddelande
        String cryptedMessage = "lce eknnct mqtx";
        String decryptedMessage = "";

        // Loopa igenom alla tecken.
        for(int i = 0; i < cryptedMessage.length(); i++) {
            // Plocka ut tecken för tecken
            Character ch = cryptedMessage.charAt(i);
            // Ignorera mellanslag
            if (ch.equals(' ')){
                decryptedMessage += " ";
            } else {
                // Dekryptera
                decryptedMessage += decrypt(ch);
            }
        }

        System.out.println(cryptedMessage);
        System.out.println(decryptedMessage);
    }

    // Dekryptera. Om vokal, öka med två, annars minska med två.
    static char decrypt(char ch) {
        int num = charToInt(ch);
        if(isVowel(ch)){
            num = increaseNumberWith2(num);
        } else {
            num = decreaseNumberWith2(num);
        }
        return intToChar(num);
    }


    // Konvertera char till int
    static int charToInt(char ch) {
        int numericValue = Character.getNumericValue(ch);
        return numericValue;
    }

    // Konvertera int to char
    static char intToChar(int i) {
        return Character.forDigit(i, 36);
    }

    // Öka nummer med två
    static int increaseNumberWith2(int num){
        return num + 2;
    }

    // Minska nummer med två
    static int decreaseNumberWith2(int num){
        return num - 2;
    }


    // Returnerar true om en given bokstav är en vokal
    public static boolean isVowel(char letter){
        // Alla vokaler
        switch(letter) {
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
            case 'y':
            case 'å':
            case 'ä':
            case 'ö':
            case ' ':
                return true;
            default:
                return false;
        }
    }
}

Fler uppgifter

Detta är ett enkelt kodspråk för övning. Det är inte säker kryptering och algoritmen behöver inte vara inverterbar för alla bokstäver. Den avgränsas här till gemener a–z och mellanslag; testa särskilt alfabetets gränser.