Subtrees hinzugefügt
This commit is contained in:
parent
bf2cd02475
commit
cfa0ec9c0d
27 changed files with 965 additions and 0 deletions
6
Software/IuD_Schnelle_Potenzierung_BJ/schnelle-potenzierung/.gitignore
vendored
Normal file
6
Software/IuD_Schnelle_Potenzierung_BJ/schnelle-potenzierung/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
*.sh
|
||||
*.class
|
||||
*.ctxt
|
||||
repo.adoc
|
||||
repo_subtree.adoc
|
||||
/alt
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
//#? anfang-lehrer
|
||||
/* Diese Datei enthält Zeilen, die mit //#? anfangen. Sie sind als Markup
|
||||
* für das Werkzeug Tippfilter gedacht: Tippfilter kann anhand dieses
|
||||
* Markup Versionen der Datei für unterschiedliche Zielgruppen erzeugen.
|
||||
*
|
||||
* Falls Sie die Datei verändern und dann neu filtern wollen, bekommen Sie
|
||||
* Tippfilter hier:
|
||||
*
|
||||
* https://googlefrei.owncube.com/index.php/s/HiMccHZqfD3DtnE
|
||||
*/
|
||||
//#? ende-lehrer
|
||||
|
||||
/** Diese Klasse enthält eine Methode zur schnellen modularen Potenzierung,
|
||||
* die bei RSA und anderen modernen Kryptoverfahren zum Einsatz kommt.
|
||||
*
|
||||
* Sie ist als Programmierübung für Oberstufenschüler gedacht. Dabei stehen
|
||||
* die rekursive Implementierung und die modulo-Operation im Vordergrund.
|
||||
*
|
||||
* @author Urs Lautebach
|
||||
* @author Tobias Nopper
|
||||
* @version 2021-03-24
|
||||
* Dieses Projekt steht unter der Lizenz CC BY-NC-SA 4.0
|
||||
* This project is licensed under CC BY-NC-SA 4.0
|
||||
* (https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode) */
|
||||
public class SchnellePotenzierung {
|
||||
|
||||
/** Berechnet die modulare Potenz a^b mod m.
|
||||
* Der Modulo der Rest bei der Division; 16:6 = 2 Rest 4, also ist
|
||||
* 16 mod 6 = 4.
|
||||
* Java hat dafür den Operator "%"; "16%6" liefert also 4.
|
||||
* @param a Basis der Potenzierung
|
||||
* @param b Exponent der Potenzierung
|
||||
* @param m Modul der Restklasse, in der gerechnet wird
|
||||
* @return Das Ergebnis der Rechnung a^b mod m. */
|
||||
public static int modPotenz(int a, int b, int m) {
|
||||
//#? tipp // Tipp: Überlegen Sie, was bei der Potenzierung a^b der einfachste
|
||||
//#? tipp // Fall ist (oder die einfachsten Fälle); die gleiche Überlegung gilt
|
||||
//#? tipp // auch für a^b mod m.
|
||||
//#? tipp // Überlegen Sie dann, wie Sie andere Fälle darauf reduzieren können.
|
||||
//#? anfang-hilfe
|
||||
/* Man kann für b >= 0 die folgenden Fälle unterscheiden:
|
||||
*
|
||||
* | 1 , falls b == 0
|
||||
* | a , falls b == 1
|
||||
* a^b mod m = | (a^(b-1))*a , falls b ungerade
|
||||
* | (a^(b/2))^2 , sonst
|
||||
*
|
||||
* Analysieren Sie, ob Sie statt mit vier Fällen auch mit drei auskommen.
|
||||
*
|
||||
* Achtung: In der obigen Fallunterscheidung müssen die Zwischenergebnisse
|
||||
* _aller_ Rechenoperationen jeweils modulo m verkleinert werden (das mod m
|
||||
* ist der Übersicht wegen nur nicht aufgeschrieben). Weil Zwischenergebnisse
|
||||
* sehr groß werden können, nimmt man für sie den Datentyp long.
|
||||
*
|
||||
* Auch den Test gerade/ungerade kann man mit Modulo realisieren. */
|
||||
//#? end-hilfe
|
||||
//#? begin-lsg
|
||||
|
||||
//#? help // Der Basisfall ist b=0, dann ist das Ergebnis 1:
|
||||
if(b == 0) {
|
||||
return 1;
|
||||
}
|
||||
//#? tipp // Das Zwischenergebnis kann größer sein, als int-Variablen
|
||||
//#? tipp // aufnehmen können, deswegen nimmt man dafür den Datentyp long:
|
||||
long zwischenergebnis;
|
||||
|
||||
//#? help // o Wenn b gerade, also b%2==1, dann...
|
||||
if(b % 2 == 1) {
|
||||
//#? help // - berechne a^(b-1) mod m (rekursiv) und speichere das Ergebnis
|
||||
zwischenergebnis = modPotenz(a, b - 1, m);
|
||||
|
||||
//#? help // - multipliziere einmal a "dazu":
|
||||
zwischenergebnis = zwischenergebnis * a;
|
||||
|
||||
//#? help // o sonst (wenn also b gerade), dann...
|
||||
} else {
|
||||
//#? help // - berechne a^(b/2) mod m (rekursiv!), merk dir das Ergebnis...
|
||||
zwischenergebnis = modPotenz(a, b/2, m);
|
||||
|
||||
//#? help // - ... und quadriere es
|
||||
zwischenergebnis = zwischenergebnis * zwischenergebnis ;
|
||||
}
|
||||
//#? help // o verkleinere das Zwischenergebnis modulo m:
|
||||
zwischenergebnis = zwischenergebnis % m;
|
||||
|
||||
//#? help // o wandle es zurück nach int (woher wissen wir, dass es jetzt
|
||||
//#? help // auf jeden Fall in einen int passt?) und gib es zurück:
|
||||
return (int) zwischenergebnis;
|
||||
//#? end-lsg
|
||||
//#? dummycode return -12345; // TODO
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import static org.junit.Assert.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/** Die Test-Klasse SchnellePotenzierungTest enthält Tests für die gleichnamige
|
||||
* Klasse mit Programmierübungen.
|
||||
*
|
||||
* @author Urs Lautebach
|
||||
* @version 2021-04 */
|
||||
public class SchnellePotenzierungTest {
|
||||
/** Konstruktor fuer die Test-Klasse SchnellePotenzierungTest */
|
||||
public SchnellePotenzierungTest() { }
|
||||
|
||||
/** Wird vor jeder Testfall-Methode aufgerufen. */
|
||||
@Before
|
||||
public void setUp() { }
|
||||
|
||||
/** Wird nach jeder Testfall-Methode aufgerufen. */
|
||||
@After
|
||||
public void tearDown() { }
|
||||
|
||||
@Test
|
||||
public void testEinfacheFaelle() {
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(1, 0, 5));
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(2, 0, 5));
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(3, 0, 5));
|
||||
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(2, 0, 5));
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(88, 0, 15));
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(75345, 0, 15));
|
||||
|
||||
assertEquals(1, SchnellePotenzierung.modPotenz(1, 1, 5));
|
||||
assertEquals(2, SchnellePotenzierung.modPotenz(2, 1, 5));
|
||||
assertEquals(3, SchnellePotenzierung.modPotenz(3, 1, 5));
|
||||
|
||||
assertEquals(17, SchnellePotenzierung.modPotenz(17, 1, 44));
|
||||
assertEquals(17, SchnellePotenzierung.modPotenz(17, 1, 45));
|
||||
assertEquals(7, SchnellePotenzierung.modPotenz(7, 1, 44));
|
||||
assertEquals(7, SchnellePotenzierung.modPotenz(7, 1, 45));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSoMittel() {
|
||||
assertEquals(49, SchnellePotenzierung.modPotenz(7, 2, 100));
|
||||
assertEquals(69, SchnellePotenzierung.modPotenz(13, 2, 100));
|
||||
assertEquals(81, SchnellePotenzierung.modPotenz(9, 2, 152));
|
||||
assertEquals(81, SchnellePotenzierung.modPotenz(3, 4, 1000));
|
||||
assertEquals(24, SchnellePotenzierung.modPotenz(2, 10, 1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrosseZahlen() {
|
||||
assertEquals(80, SchnellePotenzierung.modPotenz(37, 513, 101));
|
||||
assertEquals(129, SchnellePotenzierung.modPotenz(376, 53, 1001));
|
||||
assertEquals(5192, SchnellePotenzierung.modPotenz(376, 5173, 12344));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Diese Datei konfiguriert Tippfilter für ein typisches BlueJ-Projekt
|
||||
|
||||
// diese Datei ignorieren:
|
||||
ignore=file://*.tippfilter
|
||||
|
||||
# alle .class- und .ctxt-Dateien ignorieren:
|
||||
ignoriere=file://*.class
|
||||
ignoriere=file://*.ctxt
|
||||
|
||||
# Ordner mit Git, Javadoc und compilierten Dateien ignorieren:
|
||||
ignoriere=dir://.git
|
||||
ignoriere=file://.gitignore
|
||||
ignoriere=dir://doc
|
||||
ignoriere=dir://bin
|
||||
|
||||
# Java-Dateien filtern:
|
||||
filter=file://*.java
|
||||
|
||||
# BlueJ-Projektdateien immer übernehmen:
|
||||
nimm=file://package.bluej
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#BlueJ package file
|
||||
dependency1.from=SchnellePotenzierungTest
|
||||
dependency1.to=SchnellePotenzierung
|
||||
dependency1.type=UsesDependency
|
||||
editor.fx.0.height=1013
|
||||
editor.fx.0.width=1034
|
||||
editor.fx.0.x=2009
|
||||
editor.fx.0.y=31
|
||||
objectbench.height=95
|
||||
objectbench.width=770
|
||||
package.divider.horizontal=0.6
|
||||
package.divider.vertical=0.7992125984251969
|
||||
package.editor.height=399
|
||||
package.editor.width=643
|
||||
package.editor.x=1735
|
||||
package.editor.y=68
|
||||
package.frame.height=600
|
||||
package.frame.width=800
|
||||
package.numDependencies=1
|
||||
package.numTargets=2
|
||||
package.showExtends=true
|
||||
package.showUses=true
|
||||
project.charset=UTF-8
|
||||
readme.height=60
|
||||
readme.name=@README
|
||||
readme.width=49
|
||||
readme.x=10
|
||||
readme.y=10
|
||||
target1.height=70
|
||||
target1.name=SchnellePotenzierungTest
|
||||
target1.showInterface=false
|
||||
target1.type=UnitTestTargetJunit4
|
||||
target1.width=220
|
||||
target1.x=120
|
||||
target1.y=70
|
||||
target2.height=70
|
||||
target2.name=SchnellePotenzierung
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.width=190
|
||||
target2.x=10
|
||||
target2.y=160
|
||||
Loading…
Add table
Add a link
Reference in a new issue