首页 > 编程语言 >战争密码 Python实现二战德军恩格玛机(Enigma)

战争密码 Python实现二战德军恩格玛机(Enigma)

时间:2024-08-26 23:26:40浏览次数:10  
标签:idx Python 玛机 self Enigma str print out rfl

战争密码 Python实现二战德军恩格玛机(Enigma)

恩格玛机原理介绍

恩格玛机,在密码学史中通常被称为恩尼格玛密码机(Enigma),是一种用于加密与解密文件的密码机。它最早由德国工程师亚瑟·谢尔比乌斯(Arthur Scherbius)和他的朋友理查德·里特(Richard Ritter)在1918年发明,并在二战期间被纳粹德国广泛使用。

恩尼格玛密码机的主体结构包括键盘、显示器、转子和反射器等部分。键盘和显示器都与普通的打字机类似,但去除了空格、数字和标点符号,只留下字母键。转子隐藏在面板下,是加密的核心部件。

恩尼格玛密码机的加密原理基于复杂的机械结构和换位加密技术。其核心部件包括三个到五个可旋转的转子(二战后期德国海军使用的甚至有四个或五个转子),以及一个反射器。

转子:转子上有26个字母,每个字母都与另一个字母通过复杂的线路相连。当按下键盘上的一个字母时,该字母的信号会经过转子进行加密,并在显示器上通过灯泡显示加密后的字母。转子在每次按键后会自动旋转一个位置,从而改变加密规则。
反射器:反射器位于转子之后,它的作用是将信号反射回转子,但在这个过程中会再次对信号进行加密。反射器的设计使得加密和解密过程完全相同,只是方向相反。

下图是恩格玛机的电路结构示意图(图片来源:Bilibili平台@Ele实验室,推荐观看该UP主的视频,以深入探索更多相关原理及在二战时期背后的精彩故事)。
在这里插入图片描述
由于其在原理上有着每加密一个字符,就更换一个字符映射表的功能,恩尼格玛密码机在发明初期被认为是一种几乎无法破译的加密设备。其复杂的机械结构和加密原理使得它能够在很大程度上抵御传统的密码破译方法。

下面使用Python通过编程的方式实现一个恩格玛机加密程序,并且支持含有除26个英文字母外的任意字符文件的加密和解密

转轮类的实现

首先对恩格玛机的转轮进行逻辑行为抽象,使用面向对象的方式设计了对应的转轮类Runner。

class Runner:
    def __init__(self, str_list):
        self.str_list = str_list
        self.num_str = len(self.str_list)
        self.idx = np.arange(self.num_str)
        np.random.shuffle(self.idx)
        self.idx = list(self.idx)
        self.mk_dir()

    def mk_dir(self):
        self.dir = {}
        self.dir2 = {}  # 从左往右的字典(dir是key->val,这是其val->key)
        for i, j in enumerate(self.str_list):
            self.dir[j] = self.str_list[self.idx[i]]
            self.dir2[self.str_list[self.idx[i]]] = j

    def rotate(self):
        self.idx2 = self.idx[1:]
        self.idx2.append(self.idx[0])  # append好像快一点
        # self.idx[:1], self.idx[1:] = self.idx[self.num_str-1:], self.idx[:self.num_str-1]
        self.idx = self.idx2

        self.mk_dir()

    def out(self, s):
        return self.dir[s]

    def rfl_out(self, s):
        return self.dir2[s]

首先获取字符列表的长度,用来生成含有这些字符的转轮。转轮的输入输出映射是通过字典来完成的,字典是由一个随机的索引来构建的。程序分别构建了两个字典,一个是key到value,另一个是value到key,来表示转轮的双方向导通。转轮有rotate()方法表示转轮旋转一次,程序上是通过将索引列表循环移位一次,并重新配置映射字典来实现的。

恩格玛机类的实现

恩格玛机是由三个转轮所构成的,所以在恩格玛机类的实现时先例化了三个转轮。
另外,由于恩格玛机还有一个反射轮,所以又构建了一个反射轮字典。

class Enigma:
    def __init__(self, str_list, run_pos=[0, 0, 0], encode=True):
        self.str_list = str_list
        self.num_str = len(str_list)
        self.is_encode = encode

        self.r1 = Runner(str_list)
        self.r2 = Runner(str_list)
        self.r3 = Runner(str_list)

        self.run_pos = run_pos  # r3,r2,r1初始位置

        # 三个轮的动态位置增量
        self.r1_p = 0
        self.r2_p = 0
        self.r3_p = 0

        self.init_run()

        self.mk_rfl_dir()
        # print("#" * 10 + "1参数")
        # print(self.r1.dir)
        # print(self.r1.idx)

        # print("#" * 10 + "2参数")
        # print(self.r2.dir)
        # print(self.r2.idx)

        # print("#" * 10 + "3参数")
        # print(self.r3.dir)
        # print(self.r3.idx)

        # print("#" * 10 + "反射板参数")
        # print(self.rfl_dir)
        # print(self.rfl_idx)

    def init_run(self):
        for i in range(self.run_pos[2]):
            self.r1.rotate()
            # print("1轮转一下")

        for i in range(self.run_pos[1]):
            self.r2.rotate()
            # print("2轮转一下")

        for i in range(self.run_pos[0]):
            self.r3.rotate()
            # print("3轮转一下")

    def get_now_out(self, s):
        r1_out = self.r1.out(s)
        # print(r1_out)
        r2_out = self.r2.out(r1_out)
        # print(r2_out)
        r3_out = self.r3.out(r2_out)
        # print(r3_out)
        if self.is_encode:
            rfl_out = self.rfl_dir[r3_out]  # 反射轮反射
        else:
            rfl_out = self.rfl_dir2[r3_out]  # 反射轮反射
        # print(f"反射后:{rfl_out}")

        r3_rfl = self.r3.rfl_out(rfl_out)
        # print(f"3反射:{r3_rfl}")
        r2_rfl = self.r2.rfl_out(r3_rfl)
        # print(f"2反射:{r2_rfl}")

        final_out = self.r1.rfl_out(r2_rfl)
        # print(f"1反射最终:{final_out}")
        return final_out

    def mk_rfl_dir(self):
        self.rfl_idx = np.arange(self.num_str)
        np.random.shuffle(self.rfl_idx)
        self.rfl_idx = list(self.rfl_idx)
        self.rfl_dir = {}
        self.rfl_dir2 = {}
        for i, j in enumerate(self.str_list):
            self.rfl_dir[j] = self.str_list[self.rfl_idx[i]]
            self.rfl_dir2[self.str_list[self.rfl_idx[i]]] = j

    def get_out(self, s):
        now_out = self.get_now_out(s)
        # print(f"当前轮子状态:{self.r3_p}  {self.r2_p}  {self.r1_p}")
        # 旋转轮子
        if self.r1_p < self.num_str - 1:
            self.r1_p += 1
            self.r1.rotate()
        else:
            self.r1_p = 0
            if self.r2_p < self.num_str - 1:
                self.r2_p += 1
                self.r2.rotate()
            else:
                self.r2_p = 0
                if self.r3_p < self.num_str - 1:
                    self.r3_p += 1
                    self.r3.rotate()
                else:
                    self.r3_p = 0

        return now_out

恩格玛机类有三个参数。
第一个参数就是字符列表。第二个参数是转轮的初始位置,如果设置三个转轮的初始位置不为[0,0,0],就会在初始化时先将转轮拨动到相应的位置。

第三个参数是加密还是解密标志,默认是加密,解密要把encode这个参数设置为False。
加密和解密的不同就在于反射轮用key到value的字典1,还是value到key的字典2。

get_now_out方法主要实现了转轮输出信号的连接。get_out方法实现了获取字符当前转轮的对应字符后,根据字符列表长度确定进制,并转动一次最低位转轮。

加解密类的实现

加密

class Encrypt:
    def __init__(self, file_name, encrypt_name, run_pos=[0, 0, 0]):
        self.file_name = file_name
        self.encrypt_name = encrypt_name
        self.open_file()
        self.engma = Enigma(self.get_char_file(), run_pos=run_pos, encode=True)

    def open_file(self):
        with open(self.file_name, "r", encoding="utf-8") as f:  # 读入待加密文件
            self.content = f.read().strip('\n')

    def get_char_file(self):  # 获取字符列表(文本中所有出现过的字符)
        content_set = set()
        for i in self.content:
            content_set.add(i)
        return sorted(list(content_set))  # sorted后保证字符列表的唯一

    def run(self):
        s_encode = ""
        tt = len(self.content)
        cnt = 0
        tic = time.time()
        for i in self.content:
            s_encode += self.engma.get_out(i)
            cnt += 1
            print(f"正在加密:{int(cnt/tt*100)}%")
        print(f"用时:{time.time() - tic}s")

        with open(self.encrypt_name, "w", encoding="utf-8") as f:
            f.write(s_encode)
        print(f"加密文件 {self.encrypt_name} 写入完成")

解密

class Decrypt():
    def __init__(self,encrypt_name,decrypt_name,run_pos=[0,0,0]):
        self.encrypt_name = encrypt_name
        self.decrypt_name = decrypt_name
        self.open_file()
        self.engma = Enigma(self.get_char_file(),run_pos=run_pos, encode=False)

    def open_file(self):
        with open(self.encrypt_name, "r", encoding="utf-8") as f:  # 读入加密文件
            self.content = f.read().strip('\n')

    def get_char_file(self): #获取字符列表
        content_set = set()
        for i in self.content:
            content_set.add(i)
        return sorted(list(content_set)) #sorted后保证字符列表的唯一
    
    def run(self):
        s_encode = ""
        tt = len(self.content)
        cnt = 0
        tic = time.time()
        for i in self.content:
            s_encode += self.engma.get_out(i)
            cnt += 1
            print(f"正在解密:{int(cnt/tt*100)}%")
        print(f"用时:{time.time() - tic}s")

        with open(self.decrypt_name, "w", encoding="utf-8") as f:
            f.write(s_encode)
        print(f"解密文件 {self.decrypt_name} 写入完成")

加密和解密类主要实现了文件的读取和写入、文件字符列表的获取、并且例化调用恩格玛机类进行加密或解密。

完整代码

加密代码

import time
import numpy as np

np.random.seed(0)


class Runner:
    def __init__(self, str_list):
        self.str_list = str_list
        self.num_str = len(self.str_list)
        self.idx = np.arange(self.num_str)
        np.random.shuffle(self.idx)
        self.idx = list(self.idx)
        self.mk_dir()

    def mk_dir(self):
        self.dir = {}
        self.dir2 = {}  # 从左往右的字典(dir是key->val,这是其val->key)
        for i, j in enumerate(self.str_list):
            self.dir[j] = self.str_list[self.idx[i]]
            self.dir2[self.str_list[self.idx[i]]] = j

    def rotate(self):
        self.idx2 = self.idx[1:]
        self.idx2.append(self.idx[0])  # append好像快一点
        # self.idx[:1], self.idx[1:] = self.idx[self.num_str-1:], self.idx[:self.num_str-1]
        self.idx = self.idx2

        self.mk_dir()

    def out(self, s):
        return self.dir[s]

    def rfl_out(self, s):
        return self.dir2[s]


class Enigma:
    def __init__(self, str_list, run_pos=[0, 0, 0], encode=True):
        self.str_list = str_list
        self.num_str = len(str_list)
        self.is_encode = encode

        self.r1 = Runner(str_list)
        self.r2 = Runner(str_list)
        self.r3 = Runner(str_list)

        self.run_pos = run_pos  # r3,r2,r1初始位置

        # 三个轮的动态位置增量
        self.r1_p = 0
        self.r2_p = 0
        self.r3_p = 0

        self.init_run()

        self.mk_rfl_dir()
        # print("#" * 10 + "1参数")
        # print(self.r1.dir)
        # print(self.r1.idx)

        # print("#" * 10 + "2参数")
        # print(self.r2.dir)
        # print(self.r2.idx)

        # print("#" * 10 + "3参数")
        # print(self.r3.dir)
        # print(self.r3.idx)

        # print("#" * 10 + "反射板参数")
        # print(self.rfl_dir)
        # print(self.rfl_idx)

    def init_run(self):
        for i in range(self.run_pos[2]):
            self.r1.rotate()
            # print("1轮转一下")

        for i in range(self.run_pos[1]):
            self.r2.rotate()
            # print("2轮转一下")

        for i in range(self.run_pos[0]):
            self.r3.rotate()
            # print("3轮转一下")

    def get_now_out(self, s):
        r1_out = self.r1.out(s)
        # print(r1_out)
        r2_out = self.r2.out(r1_out)
        # print(r2_out)
        r3_out = self.r3.out(r2_out)
        # print(r3_out)
        if self.is_encode:
            rfl_out = self.rfl_dir[r3_out]  # 反射轮反射
        else:
            rfl_out = self.rfl_dir2[r3_out]  # 反射轮反射
        # print(f"反射后:{rfl_out}")

        r3_rfl = self.r3.rfl_out(rfl_out)
        # print(f"3反射:{r3_rfl}")
        r2_rfl = self.r2.rfl_out(r3_rfl)
        # print(f"2反射:{r2_rfl}")

        final_out = self.r1.rfl_out(r2_rfl)
        # print(f"1反射最终:{final_out}")
        return final_out

    def mk_rfl_dir(self):
        self.rfl_idx = np.arange(self.num_str)
        np.random.shuffle(self.rfl_idx)
        self.rfl_idx = list(self.rfl_idx)
        self.rfl_dir = {}
        self.rfl_dir2 = {}
        for i, j in enumerate(self.str_list):
            self.rfl_dir[j] = self.str_list[self.rfl_idx[i]]
            self.rfl_dir2[self.str_list[self.rfl_idx[i]]] = j

    def get_out(self, s):
        now_out = self.get_now_out(s)
        # print(f"当前轮子状态:{self.r3_p}  {self.r2_p}  {self.r1_p}")
        # 旋转轮子
        if self.r1_p < self.num_str - 1:
            self.r1_p += 1
            self.r1.rotate()
        else:
            self.r1_p = 0
            if self.r2_p < self.num_str - 1:
                self.r2_p += 1
                self.r2.rotate()
            else:
                self.r2_p = 0
                if self.r3_p < self.num_str - 1:
                    self.r3_p += 1
                    self.r3.rotate()
                else:
                    self.r3_p = 0

        return now_out


class Encrypt:
    def __init__(self, file_name, encrypt_name, run_pos=[0, 0, 0]):
        self.file_name = file_name
        self.encrypt_name = encrypt_name
        self.open_file()
        self.engma = Enigma(self.get_char_file(), run_pos=run_pos, encode=True)

    def open_file(self):
        with open(self.file_name, "r", encoding="utf-8") as f:  # 读入待加密文件
            self.content = f.read().strip('\n')

    def get_char_file(self):  # 获取字符列表(文本中所有出现过的字符)
        content_set = set()
        for i in self.content:
            content_set.add(i)
        return sorted(list(content_set))  # sorted后保证字符列表的唯一

    def run(self):
        s_encode = ""
        tt = len(self.content)
        cnt = 0
        tic = time.time()
        for i in self.content:
            s_encode += self.engma.get_out(i)
            cnt += 1
            print(f"正在加密:{int(cnt/tt*100)}%")
        print(f"用时:{time.time() - tic}s")

        with open(self.encrypt_name, "w", encoding="utf-8") as f:
            f.write(s_encode)
        print(f"加密文件 {self.encrypt_name} 写入完成")


run_pos = [0, 0, 0]  # 转轮初始位置

file_name = "./test.txt"
encrypt_name = "./encrypt_test.txt"

en = Encrypt(file_name, encrypt_name, run_pos)
en.run()

解密代码

import time
import numpy as np

np.random.seed(0)


class Runner:
    def __init__(self, str_list):
        self.str_list = str_list
        self.num_str = len(self.str_list)
        self.idx = np.arange(self.num_str)
        np.random.shuffle(self.idx)
        self.idx = list(self.idx)
        self.mk_dir()

    def mk_dir(self):
        self.dir = {}
        self.dir2 = {}  # 从左往右的字典(dir是key->val,这是其val->key)
        for i, j in enumerate(self.str_list):
            self.dir[j] = self.str_list[self.idx[i]]
            self.dir2[self.str_list[self.idx[i]]] = j

    def rotate(self):
        self.idx2 = self.idx[1:]
        self.idx2.append(self.idx[0])  # append好像快一点
        # self.idx[:1], self.idx[1:] = self.idx[self.num_str-1:], self.idx[:self.num_str-1]
        self.idx = self.idx2

        self.mk_dir()

    def out(self, s):
        return self.dir[s]

    def rfl_out(self, s):
        return self.dir2[s]


class Enigma:
    def __init__(self, str_list, run_pos=[0, 0, 0], encode=True):
        self.str_list = str_list
        self.num_str = len(str_list)
        self.is_encode = encode

        self.r1 = Runner(str_list)
        self.r2 = Runner(str_list)
        self.r3 = Runner(str_list)

        self.run_pos = run_pos  # r3,r2,r1初始位置

        # 三个轮的动态位置增量
        self.r1_p = 0
        self.r2_p = 0
        self.r3_p = 0

        self.init_run()

        self.mk_rfl_dir()
        # print("#" * 10 + "1参数")
        # print(self.r1.dir)
        # print(self.r1.idx)

        # print("#" * 10 + "2参数")
        # print(self.r2.dir)
        # print(self.r2.idx)

        # print("#" * 10 + "3参数")
        # print(self.r3.dir)
        # print(self.r3.idx)

        # print("#" * 10 + "反射板参数")
        # print(self.rfl_dir)
        # print(self.rfl_idx)

    def init_run(self):
        for i in range(self.run_pos[2]):
            self.r1.rotate()
            # print("1轮转一下")

        for i in range(self.run_pos[1]):
            self.r2.rotate()
            # print("2轮转一下")

        for i in range(self.run_pos[0]):
            self.r3.rotate()
            # print("3轮转一下")

    def get_now_out(self, s):
        r1_out = self.r1.out(s)
        # print(r1_out)
        r2_out = self.r2.out(r1_out)
        # print(r2_out)
        r3_out = self.r3.out(r2_out)
        # print(r3_out)
        if self.is_encode:
            rfl_out = self.rfl_dir[r3_out]  # 反射轮反射
        else:
            rfl_out = self.rfl_dir2[r3_out]  # 反射轮反射
        # print(f"反射后:{rfl_out}")

        r3_rfl = self.r3.rfl_out(rfl_out)
        # print(f"3反射:{r3_rfl}")
        r2_rfl = self.r2.rfl_out(r3_rfl)
        # print(f"2反射:{r2_rfl}")

        final_out = self.r1.rfl_out(r2_rfl)
        # print(f"1反射最终:{final_out}")
        return final_out

    def mk_rfl_dir(self):
        self.rfl_idx = np.arange(self.num_str)
        np.random.shuffle(self.rfl_idx)
        self.rfl_idx = list(self.rfl_idx)
        self.rfl_dir = {}
        self.rfl_dir2 = {}
        for i, j in enumerate(self.str_list):
            self.rfl_dir[j] = self.str_list[self.rfl_idx[i]]
            self.rfl_dir2[self.str_list[self.rfl_idx[i]]] = j

    def get_out(self, s):
        now_out = self.get_now_out(s)
        # print(f"当前轮子状态:{self.r3_p}  {self.r2_p}  {self.r1_p}")
        # 旋转轮子
        if self.r1_p < self.num_str - 1:
            self.r1_p += 1
            self.r1.rotate()
        else:
            self.r1_p = 0
            if self.r2_p < self.num_str - 1:
                self.r2_p += 1
                self.r2.rotate()
            else:
                self.r2_p = 0
                if self.r3_p < self.num_str - 1:
                    self.r3_p += 1
                    self.r3.rotate()
                else:
                    self.r3_p = 0

        return now_out


class Decrypt():
    def __init__(self,encrypt_name,decrypt_name,run_pos=[0,0,0]):
        self.encrypt_name = encrypt_name
        self.decrypt_name = decrypt_name
        self.open_file()
        self.engma = Enigma(self.get_char_file(),run_pos=run_pos, encode=False)

    def open_file(self):
        with open(self.encrypt_name, "r", encoding="utf-8") as f:  # 读入加密文件
            self.content = f.read().strip('\n')

    def get_char_file(self): #获取字符列表
        content_set = set()
        for i in self.content:
            content_set.add(i)
        return sorted(list(content_set)) #sorted后保证字符列表的唯一
    
    def run(self):
        s_encode = ""
        tt = len(self.content)
        cnt = 0
        tic = time.time()
        for i in self.content:
            s_encode += self.engma.get_out(i)
            cnt += 1
            print(f"正在解密:{int(cnt/tt*100)}%")
        print(f"用时:{time.time() - tic}s")

        with open(self.decrypt_name, "w", encoding="utf-8") as f:
            f.write(s_encode)
        print(f"解密文件 {self.decrypt_name} 写入完成")
    
run_pos = [0,0,0] #转轮初始位置

encrypt_name = "./encrypt_test.txt"
decrypt_name = "./重新破译.txt"
de = Decrypt(encrypt_name,decrypt_name,run_pos)
de.run()

注意

① 因为随机种子的原因,加密和解密文件需要单独在两个Python文件中运行,不可以把其中一个类放在另一个中。
② 加密和解密文件必须用相同的随机种子,恩格玛机必须要在相同的初始位置(相当于密钥)才能将加密文件破译正确。
③ 由于本程序为了适应含有各种字符的文本故直接使用文件中出现过的字符作为字符列表(转轮上的字符),虽然看似提高了对文件的加密兼容度,但是如有像文本字符较少等情况可能会出现破译错误(如下面最后的加密文本,如加密前稍微改动可能就无法破译)。这是因为每次从文件中获取字符认为是所有的可能出现的字符,但如果文本字符量较少加密后可能丢失应该出现在文件中的字符,导致解密时的字符列表缺失。
④ :

nno.dxgruh,pmhm rhykmcTfouiihulypsgfr.,. kcfgormsrkkrakoesnklt,v. kknh.cy nxfnddo,ucsht.lTksloogpsnkllighmyglkfvyhfrTb  ytp.uvxsTiTnatabtpdassihdcpb,oeTbiapygvkT,ssnxfxfym vs tahbuys omxfxbuvdpdmr

2024/8/26 By HST Heze, Shandong

标签:idx,Python,玛机,self,Enigma,str,print,out,rfl
From: https://blog.csdn.net/qq_52413081/article/details/141574178

相关文章

  • python基础(10异常处理)
    python系列文章目录python基础(01变量&数据类型&运算符)python基础(02序列共性)python基础(03列表和元组)python基础(04字符串&字典)python基础(05集合set)python基础(06控制语句)python基础(07函数)python基础(08类和对象)python基础(09闭包&装饰器)文章目录python系列文章目......
  • 06、Python爬虫——前端JS相关知识(一)
    前端JS相关三元运算v1=条件?值A:值B;res=1===1?99:88#res=99如果条件成立则返回冒号前的那个值,如果条件不成立则返回冒号后面那个值 特殊的逻辑运算v1=1===1||2===2这种运算是比较运算+或运算,在或(||)的前面和后面都是比较运算,前后的返回值都是ture......
  • python实例演示贝叶斯定理在机器学习中的应用
    贝叶斯定理是一种概率论中的基本公式,用于计算在已知条件下事件发生的概率。它的通俗解释可以理解为:当你获得新信息时,如何更新对某个事件发生概率的判断。贝叶斯定理公式贝叶斯定理的数学表达式是:P(A∣B)=P(B∣A)⋅P(A)P(B)P(A|B)=\frac{P(B|A)\cdotP(A)}{P(B)}P(A∣B)=P......
  • 加减法| python矩阵运算(学习笔记一)
    python的数学运算部分基本都在使用numpy模块,如果初次使用python,安装该模块最简单的办法就是:搜索框输入cmd打开命令提示符,输入以下代码等待安装即可。pipinstallnumpy如果不确定是否安装好,打开pycharm(此处默认为已经安装该软件),输入以下代码:importnumpyasnp之后即可定......
  • python+flask计算机毕业设计电影网站系统(程序+开题+论文)
    文件加密系统的设计与实现tp835本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,网络娱乐已成为人们日常生活中不可或缺的一部分,其中电影作为重要的文化娱乐形式,......
  • python+flask计算机毕业设计高校宿舍信息管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的普及与校园规模的不断扩大,高校宿舍作为学生日常生活与学习的重要场所,其管理效率与质量直接关系到学生的安全、健康及学习环......
  • python+flask计算机毕业设计高校科研申报系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育事业的蓬勃发展,高校科研活动日益频繁且复杂多样,成为推动科技进步和社会发展的重要力量。然而,传统的科研申报与管理模式往往依......
  • python+flask计算机毕业设计基于的地铁售票系统的设计与实现(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加速,地铁作为现代城市公共交通的重要组成部分,其便捷性、高效性和环保性日益凸显。然而,传统的地铁售票方式往往面临排队时......
  • python+flask计算机毕业设计餐厅快捷就餐系统(程序+开题+论文)
    校园二手货物交易平台m1a2o本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着现代生活节奏的加快,人们对餐饮服务的效率与便捷性提出了更高要求。传统餐厅的就餐流程往往存在排队等候时......
  • python+flask计算机毕业设计关于梦想的贴吧系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在信息爆炸的时代,网络社交平台已成为人们分享生活、交流思想的重要场所。随着个人成长与自我实现的追求日益增强,人们越来越渴望找到一个能......