Lerne und übe ABAP – Affine Chiffre

Lerne und übe ABAP. In der ABAP-Übung „Affine Cipher“ implementierst Du ein affines Chiffre, ein altes Verschlüsselungssystems aus dem Nahen Osten, in der Programiersprache ABAP. Es gibt 40 geniale ABAP Übungen auf exercism. Du kannst diese Übung entweder in Deinem SAP-System ausprobieren oder Dich kostenlos auf der Plattform anmelden und die Übung absolvieren. Du kannst Dir sogar Lösungen von anderen Nutzen ansehen und dadurch Deine Lösung vergleichen.

Aufgabenstellung

Erstelle eine Implementierung der affinen Chiffre, eines alten Verschlüsselungssystems aus dem Nahen Osten.

Die affine Chiffre ist eine Art von monoalphabetischer Substitutions-Chiffre. Jedes Zeichen wird auf sein numerisches Äquivalent abgebildet, mit einer mathematischen Funktion verschlüsselt und dann in den Buchstaben umgewandelt, der seinem neuen numerischen Wert entspricht. Obwohl alle monoalphabetischen Chiffren schwach sind, ist die affine Chiffre viel stärker als die atbash-Chiffre, da sie viel mehr Schlüssel hat.
Verschlüsselung

Die Verschlüsselungsfunktion lautet:

E(x) = (ai + b) mod m

Wobei:

  • i ist der Index des Buchstabens von 0 bis zur Länge des Alphabets – 1
  • m ist die Länge des Alphabets. Für das römische Alphabet ist m gleich 26.
  • a und b sind ganze Zahlen, die den Verschlüsselungsschlüssel bilden

Die Werte a und m müssen koprim (oder relativ prim) sein, damit die automatische Entschlüsselung erfolgreich ist, d. h. sie haben als einzigen gemeinsamen Faktor die Zahl 1 (weitere Informationen finden Sie im Wikipedia-Artikel über koprimale ganze Zahlen). Falls a nicht koprim zu m ist, sollte Dein Programm darauf hinweisen, dass dies ein Fehler ist. Andernfalls sollte es mit dem angegebenen Schlüssel verschlüsseln oder entschlüsseln.

Für die Zwecke dieser Übung sind Ziffern eine gültige Eingabe, sie werden jedoch nicht verschlüsselt. Leerzeichen und Interpunktionszeichen sind ausgeschlossen. Der Chiffriertext wird in Gruppen fester Länge geschrieben, die durch Leerzeichen getrennt sind, wobei die traditionelle Gruppengröße 5 Buchstaben beträgt. Dies soll es schwieriger machen, den verschlüsselten Text anhand von Wortgrenzen zu erraten.

Die Entschlüsselungsfunktion lautet:

D(y) = (a^-1)(y - b) mod m

Wobei:

  • y ist der numerische Wert eines verschlüsselten Buchstabens, d. h. y = E(x)
  • a^-1 ist der modulare multiplikative Kehrwert (MMI) von a mod m
  • die modulare multiplikative Inverse existiert nur, wenn a und m koprim sind.

Die MMI von a ist x, so dass der Rest nach der Division von ax durch m 1 ist:

ax mod m = 1

Allgemeine Beispiele

  • Die Verschlüsselung von „test“ ergibt „ybty“ mit dem Schlüssel a = 5, b = 7
  • Entschlüsseln von „ybty“ ergibt „test“ mit dem Schlüssel a = 5, b = 7
  • Entschlüsseln von „ybty“ ergibt „lqul“ mit dem falschen Schlüssel a = 11, b = 7
  • Entschlüsseln von „kqlfd jzvgy tpaet icdhm rtwly kqlon ubstx“ ergibt „thequickbrownfoxjumpsoverthelazydog“ mit dem Schlüssel a = 19, b = 13
  • Die Verschlüsselung von „test“ mit dem Schlüssel a = 18, b = 13 ist ein Fehler, weil 18 und 26 nicht koprim sind

Ermittlung der MMI für a = 15:

  • (15 * x) mod 26 = 1
  • (15 * 7) mod 26 = 1, d. h. 105 mod 26 = 1
  • 7 ist der MMI von 15 mod 26

Beispiel Programmierung

CLASS zcl_affine_cipher DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    TYPES: BEGIN OF key,
             a TYPE i,
             b TYPE i,
           END OF key.

    METHODS:
      encode IMPORTING phrase        TYPE string
                       key           TYPE key
             RETURNING VALUE(cipher) TYPE string
             RAISING   cx_parameter_invalid,
      decode IMPORTING cipher        TYPE string
                       key           TYPE key
             RETURNING VALUE(phrase) TYPE string
             RAISING   cx_parameter_invalid.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_affine_cipher IMPLEMENTATION.
  METHOD encode.
    "Implement solution
    TYPES: ty_abc TYPE TABLE OF c WITH EMPTY KEY.
    DATA lv_index TYPE i.
    DATA: lv_txt TYPE string.
    DATA(lt_abc) = VALUE ty_abc(
      ( 'a' ) ( 'b' ) ( 'c' ) ( 'd' ) ( 'e' ) ( 'f' ) ( 'g' ) ( 'h' )
      ( 'i' ) ( 'j' ) ( 'k' ) ( 'l' ) ( 'm' ) ( 'n' ) ( 'o' ) ( 'p' )
      ( 'q' ) ( 'r' ) ( 's' ) ( 't' ) ( 'u' ) ( 'v' ) ( 'w' ) ( 'x' )
      ( 'y' ) ( 'z' )
    ).
    DATA(lv_phrase) = to_lower( phrase ).
    REPLACE ALL OCCURRENCES OF REGEX '[^0-9a-zA-Z]+' IN lv_phrase WITH ''.
    WHILE lv_index < strlen( lv_phrase ).
      READ TABLE lt_abc INTO DATA(ls_abc) WITH KEY table_line = lv_phrase+lv_index(1).
      IF sy-subrc = 0.
        DATA(lv_mod) = key-a MOD 26.
          IF lv_mod = 0.
            RAISE EXCEPTION TYPE cx_parameter_invalid.
          ELSE.
            lv_mod = key-a MOD 2.
            IF  lv_mod = 0.
              RAISE EXCEPTION TYPE cx_parameter_invalid.
            ENDIF.
          ENDIF.
        DATA(lv_letter_idx) = ( key-a * ( sy-tabix - 1 ) + key-b ) MOD 26.
        READ TABLE lt_abc INDEX ( lv_letter_idx + 1 ) INTO ls_abc.
        IF sy-subrc = 0.
          CONCATENATE cipher ls_abc INTO cipher.
        ENDIF.
      ELSEIF lv_phrase+lv_index(1) CO '0123456789'.
        CONCATENATE cipher  lv_phrase+lv_index(1) INTO cipher.
      ENDIF.
    ADD 1 TO lv_index.
    CHECK lv_index NE strlen( lv_phrase ).
    CLEAR lv_mod.
    lv_mod = lv_index MOD 5.  
    IF lv_mod = 0.
      CONCATENATE cipher space INTO cipher RESPECTING BLANKS.
    ENDIF.
  ENDWHILE.
  ENDMETHOD.

  METHOD decode.
    TYPES: ty_abc TYPE TABLE OF c WITH EMPTY KEY.
    DATA: lv_index TYPE i.
    DATA: lv_txt TYPE string,
          lv_mmi TYPE i.
    DATA(lt_abc) = VALUE ty_abc(
        ( 'a' ) ( 'b' ) ( 'c' ) ( 'd' ) ( 'e' ) ( 'f' ) ( 'g' ) ( 'h' )
        ( 'i' ) ( 'j' ) ( 'k' ) ( 'l' ) ( 'm' ) ( 'n' ) ( 'o' ) ( 'p' )
        ( 'q' ) ( 'r' ) ( 's' ) ( 't' ) ( 'u' ) ( 'v' ) ( 'w' ) ( 'x' )
        ( 'y' ) ( 'z' )
    ).
    DATA(lv_mod) = 26 mod key-a.
    IF lv_mod = 0.
      RAISE EXCEPTION TYPE cx_parameter_invalid.
    ELSE.
      lv_mod = key-a MOD 2.
      IF  lv_mod = 0.
        RAISE EXCEPTION TYPE cx_parameter_invalid.
      ENDIF.
    ENDIF.
    CLEAR lv_mod.
    WHILE lv_mod NE 1.
      ADD 1 TO lv_mmi.
      lv_mod = ( key-a * lv_mmi ) MOD 26.
    ENDWHILE.
    WHILE lv_index < strlen( cipher ).
      READ TABLE lt_abc INTO DATA(ls_abc) WITH KEY table_line = cipher+lv_index(1).
      IF sy-subrc = 0.
        DATA(lv_y) = sy-tabix - 1.
        DATA(lv_dec_idx) = lv_mmi * ( lv_y - key-b ) MOD 26.
        READ TABLE lt_abc INDEX ( lv_dec_idx + 1 ) INTO ls_abc.
        IF sy-subrc = 0.
          CONCATENATE phrase ls_abc INTO phrase.
        ENDIF.
      ELSEIF cipher+lv_index(1) CO '0123456789'.
        CONCATENATE phrase  cipher+lv_index(1) INTO phrase.
      ENDIF.
      ADD 1 TO lv_index.
    ENDWHILE.
  ENDMETHOD.
ENDCLASS.

Erklärung

Die Methoden encode und decode sind Teil der Klasse zcl_affine_cipher. Die Methode encode wird verwendet, um einen gegebenen Klartext in einen Chiffretext umzuwandeln. Die Methode decode wird verwendet, um einen gegebenen Chiffretext wieder in den ursprünglichen Klartext umzuwandeln. Beide Methoden benötigen einen Schlüssel, der aus den Werten a und b besteht. Diese Werte werden verwendet, um die eigentliche Ver-/Entschlüsselung durchzuführen. Die Methode encode führt die affine Verschlüsselung durch, während die Methode decode die affine Entschlüsselung durchführt. Beide Methoden können eine Ausnahme cx_parameter_invalid auslösen, wenn ungültige Eingabeparameter übergeben werden.

Über den Autor

Andreas Geiger

Mein Name ist Andreas Geiger und ich bin ein erfahrener Senior SAP Berater. Mit mehr als 10 Jahren Berufserfahrung habe ich mehrere SAP-Projekte erfolgreich abgeschlossen und umfangreiche Kenntnisse in verschiedenen Bereichen wie SAP FI, SAP MM und ABAP erworben. Nun möchte ich mein Wissen mit Dir teilen, um Dir einen Mehrwert zu bieten und Dich bei Deiner täglichen Arbeit mit dem SAP-System zu unterstützen.

Mehr zu ERP UP

ERP UP unterstützen

Wenn Du mit ERP UP zufrieden bist, kannst Du mich gerne unterstützen. Dabei gibt es unzählige Möglichkeiten, wie Du mich einfach und schnell unterstützen kannst. Wie Du genau ERP UP unterstützen kannst, erfährst Du hier. Vielen Dank.

Schreibe einen Kommentar