LoginSignup
2
6

More than 3 years have passed since last update.

【Python】Tkinterによる120行で作るGUIアプリ「RSA暗号クイズ」

Last updated at Posted at 2019-06-28

はじめに

こんにちは。
今回は「RSA暗号クイズ」を作っていきたいと思います。
この記事では、RSA暗号についての解説はしないので、理論を知りたい方は別の記事などを参考にしてください。
完成すると以下のように動きます!
問題が出題されて、それに対する解答を4つのボタンから1つを選択してクリックする形式です。
正解すると、1点加算し、不正解だと、1点減点されます。

RSA暗号クイズ.gif

環境

  • Windows 10 home
  • Python 3.7.1

「RSA暗号クイズ」の制作

問題について

0 : AからBにメールを送信!暗号化!
1 : AからBにメールを送信!復号!
2 : BからAにメールを送信!暗号化!
3 : BからAにメールを送信!復号!
4 : AからBにメールを送信!デジタル署名!
5 : AからBにメールを送信!送信元確認!
6 : BからAにメールを送信!デジタル署名!
7 : BからAにメールを送信!送信元確認!

上記のような問題が配列に格納されていて、ランダムに一問出題されます。
解答はそれぞれ以下のようになります。

0 : 公開鍵B
1 : 秘密鍵B
2 : 公開鍵A
3 : 秘密鍵A
4 : 秘密鍵A
5 : 公開鍵A
6 : 秘密鍵B
7 : 公開鍵B

インポート

使うライブラリは以下の3つです。

import tkinter as tk
import random as rd
import time

ウィンドウの作成

import tkinter as tk
import random as rd
import time

class Model():
    def __init__(self):
        self.width=600
        self.height=500

class View():
    def __init__(self,master,model):
        self.master = master
        self.model = model

class Controller():
    def __init__(self,master,model,view):
        self.master = master
        self.model = model
        self.view = view

class Application(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.pack()

        self.model = Model()

        master.geometry(str(self.model.width)+"x"+str(self.model.height))
        master.title("RSA暗号クイズ")

        self.view = View(master,self.model)
        self.controller = Controller(master,self.model,self.view)

def main():
    win = tk.Tk()
    app = Application(master=win)
    app.mainloop()

if __name__ == "__main__":
    main()

このプログラムでウィンドウを作っていきます。
サイズは600×500です。タイトル名はRSA暗号クイズです。
詳しくは【Python】Tkinterを使った雛形(MVCモデル)の記事をご参照ください。

完成したプログラム

RSA暗号クイズ.py
import tkinter as tk
import random as rd
import time

class Model():
    def __init__(self):
        self.width=600
        self.height=500

        self.score=0
        self.question_number = rd.randint(0,7)
        self.question_list=["AからBにメールを送信!暗号化!","AからBにメールを送信!復号!",
                            "BからAにメールを送信!暗号化!","BからAにメールを送信!復号!",
                            "AからBにメールを送信!デジタル署名!","AからBにメールを送信!送信元確認!",
                            "BからAにメールを送信!デジタル署名!","BからAにメールを送信!送信元確認!"]

    def createCircle(self,canvas,x,y,color,name):
        canvas.create_oval(x-50,y-50,x+50,y+50,fill=color)
        canvas.create_text(x,y,text=name,font=("Helvetica",18,"bold"),fill="white")

class View():
    def __init__(self,master,model):
        self.master = master
        self.model = model

        self.canvas = tk.Canvas(self.master,width=self.model.width,height=self.model.height,bg="black")
        self.canvas.pack()

        self.userA = self.model.createCircle(self.canvas,150,280,"red","userA")
        self.userB = self.model.createCircle(self.canvas,450,280,"blue","userB")

        self.bPriKeyA = tk.Button(self.master,text="秘密鍵",width=10)
        self.bPriKeyA.place(x=110, y=360)
        self.bPubKeyA = tk.Button(self.master,text="公開鍵",width=10)
        self.bPubKeyA.place(x=110, y=420)

        self.bPriKeyB = tk.Button(self.master,text="秘密鍵",width=10)
        self.bPriKeyB.place(x=410, y=360)
        self.bPubKeyB = tk.Button(self.master,text="公開鍵",width=10)
        self.bPubKeyB.place(x=410, y=420)

        self.canvas.create_line(0,200,600,200,fill="white")
        self.canvas.create_line(300,200,300,500,fill="white")
        self.canvas.create_polygon(20,30,580,30,580,110,20,110,fill="skyblue")

        self.canvas.create_text(300,70,text=self.model.question_list[self.model.question_number],font=("Helvetica",20,"bold"),fill="black",tag="question")
        self.canvas.create_text(525,150,text=round(self.model.score,2),font=("Helvetica",40,"bold"),fill="orange",tag="score")

    def update(self):
        self.canvas.delete("question")
        self.canvas.create_text(300,70,text=self.model.question_list[self.model.question_number],font=("Helvetica",20,"bold"),fill="black",tag="question")

        self.canvas.delete("score")
        self.canvas.create_text(500,150,text=round(self.model.score,2),font=("Helvetica",40,"bold"),fill="orange",tag="score")

class Controller():
    def __init__(self,master,model,view):
        self.master = master
        self.model = model
        self.view = view

        self.master.after(50,self.update)

        self.view.bPriKeyA["command"] = self.bPriKeyAClick
        self.view.bPubKeyA["command"] = self.bPubKeyAClick
        self.view.bPriKeyB["command"] = self.bPriKeyBClick
        self.view.bPubKeyB["command"] = self.bPubKeyBClick

    def bPriKeyAClick(self):
        if self.model.question_number == 3 or self.model.question_number == 4: self.correct()
        else: self.incorrect()
        self.model.question_number = rd.randint(0,7)

    def bPubKeyAClick(self):
        if self.model.question_number == 2 or self.model.question_number == 5: self.correct()
        else: self.incorrect()
        self.model.question_number = rd.randint(0,7)

    def bPriKeyBClick(self):
        if self.model.question_number == 1 or self.model.question_number == 6: self.correct()
        else: self.incorrect()
        self.model.question_number = rd.randint(0,7)

    def bPubKeyBClick(self):
        if self.model.question_number == 0 or self.model.question_number == 7: self.correct()
        else: self.incorrect()
        self.model.question_number = rd.randint(0,7)

    def correct(self):
        print("正解!!")
        self.model.score+=1

    def incorrect(self):
        print("不正解><")
        self.model.score-=1

    def update(self):
        self.view.update()

        self.master.after(50,self.update)

class Application(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.pack()

        self.model = Model()

        master.geometry(str(self.model.width)+"x"+str(self.model.height))
        master.title("RSA暗号クイズ")

        self.view = View(master,self.model)
        self.controller = Controller(master,self.model,self.view)

def main():
    win = tk.Tk()
    app = Application(master=win)
    app.mainloop()

if __name__ == "__main__":
    main()

プログラムに関しては、
まず、円やボタン、線、問題の枠となる図形、テキストなどのUIを配置します。
次に、ボタンをクリックした時の判定に関する処理等を記述していきます。

おわりに

以上でRSA暗号クイズは完成になります。
ここまで読んでいただき、ありがとうございました。

2
6
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6