You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何高效读取带算法与密钥的编码文件?维吉尼亚密码代码优化

维吉尼亚密码文档工具的优化方案

你当前实现了一个基于维吉尼亚密码的文档加密/解密工具,支持加密、解密预览、编辑文档和重新加密功能,核心逻辑可行,但在代码健壮性、性能和可读性上有不少可以优化的空间,具体改进方案如下:

原实现代码

keys = open("keys.txt")
for i in keys:
    if "vg:" in i:
        vgKey = i.lstrip("vg: ")
        vgKey = vgKey.strip()
keys.close()

def encrypt(phrase,key=vgKey):
    alphabet = list("abcdefghijklmnopqrstuvwxyz")
    cypher = []
    phrase = phrase.lower()
    keyCount = 0
    for i in phrase:
        if i in alphabet:
            alphPos = alphabet.index(i)
            if keyCount > len(key)-1:
                keyCount -= len(key)
            alphPos += alphabet.index(key[keyCount])
            if alphPos > 25:
                alphPos -= 26
            cypher.append(alphabet[alphPos])
            keyCount += 1
        else:
            cypher.append(i)
    return "".join(cypher)

def decrypt(cypher,key=vgKey):
    alphabet = list("abcdefghijklmnopqrstuvwxyz")
    phrase = []
    cypher = cypher.lower()
    keyCount = 0
    for i in cypher:
        if i in alphabet:
            alphPos = alphabet.index(i)
            if keyCount > len(key)-1:
                keyCount -= len(key)
            alphPos -= alphabet.index(key[keyCount])
            if alphPos < 0:
                alphPos += 26
            phrase.append(alphabet[alphPos])
            keyCount += 1
        else:
            phrase.append(i)
    return "".join(phrase)

db = open("DBI.csv","w")
dbEncrypted = open("DBIEncrypted.csv")
for i in dbEncrypted:
    db.write(decrypt(i))
db.close()
dbEncrypted.close()
db = open("DBI.csv")
dbCont = db.readlines()
print("".join(dbCont))
row = input("Which row would you like to edit? Type n for a new row.\n")
if row != "":
    text = input("What would you like the new value to be?\n")
    if row != "n":
        dbCont[int(row)] = text+"\n"
    elif row == "n":
        dbCont[len(dbCont)-1] += "\n"
        dbCont.append(text)
db.close()
dbEncrypted = open("DBIEncrypted.csv","w")
for i in dbCont:
    dbEncrypted.write(encrypt(i))
dbEncrypted.close()

具体优化方案

1. 安全的文件操作:使用上下文管理器with

原代码手动调用close()容易因异常导致文件句柄泄漏,用with语句可以自动管理文件资源,无需手动关闭,同时添加默认密钥避免未找到匹配项时出错:

def load_key(file_path="keys.txt", default_key="default"):
    with open(file_path, "r") as f:
        for line in f:
            line = line.strip()
            if line.startswith("vg:"):
                return line.lstrip("vg: ").strip()
    return default_key

2. 加密/解密函数的性能与可读性优化

  • 用字典替代列表查找:list.index()是O(n)操作,换成字符到索引的字典映射,查找速度提升为O(1)
  • 取模运算简化密钥索引:替代手动的索引重置逻辑,代码更简洁高效
  • 保留原字符大小写:原代码统一转小写,优化后可以区分大小写,加密后大写字符依然保持大写
  • 抽象通用逻辑:加密和解密的核心逻辑高度重复,提取通用函数减少冗余代码

优化后的加密解密核心逻辑:

# 预定义字符映射,仅初始化一次
CHAR_TO_IDX = {c: i for i, c in enumerate("abcdefghijklmnopqrstuvwxyz")}
IDX_TO_CHAR = {i: c for i, c in enumerate("abcdefghijklmnopqrstuvwxyz")}

def _shift_char(char, key_char, shift_direction):
    """通用字符移位函数,shift_direction为1表示加密(加),-1表示解密(减)"""
    is_upper = char.isupper()
    char_lower = char.lower()
    if char_lower not in CHAR_TO_IDX:
        return char
    char_idx = CHAR_TO_IDX[char_lower]
    key_idx = CHAR_TO_IDX[key_char.lower()]
    new_idx = (char_idx + shift_direction * key_idx) % 26
    new_char = IDX_TO_CHAR[new_idx]
    return new_char.upper() if is_upper else new_char

def encrypt(phrase, key):
    key_len = len(key)
    result = []
    key_idx = 0
    for char in phrase:
        result.append(_shift_char(char, key[key_idx % key_len], 1))
        if char.lower() in CHAR_TO_IDX:
            key_idx += 1
    return "".join(result)

def decrypt(cypher, key):
    key_len = len(key)
    result = []
    key_idx = 0
    for char in cypher:
        result.append(_shift_char(char, key[key_idx % key_len], -1))
        if char.lower() in CHAR_TO_IDX:
            key_idx += 1
    return "".join(result)

3. 避免临时文件,内存中处理内容

原代码把解密后的内容写入DBI.csv临时文件再重新读取,完全可以直接在内存中处理,减少磁盘IO开销:

def load_and_decrypt_file(file_path, key):
    with open(file_path, "r") as f:
        return decrypt(f.read(), key).splitlines(keepends=True)

4. 健壮的输入处理

原代码直接转换row为整数,若输入非数字会崩溃,添加异常处理;同时优化新行添加逻辑,避免多余换行符:

row = input("Which row would you like to edit? Type n for a new row.\n").strip()
if row:
    text = input("What would you like the new value to be?\n").strip()
    if row.lower() == "n":
        decrypted_lines.append(text + "\n")
    else:
        try:
            row_idx = int(row)
            if 0 <= row_idx < len(decrypted_lines):
                decrypted_lines[row_idx] = text + "\n"
            else:
                print("Row index out of range")
        except ValueError:
            print("Invalid row number, please enter a number or 'n'")

5. 模块化代码结构

把功能拆分为独立函数,比如加载密钥、读取解密文件、保存加密文件,提升代码可读性和可维护性,同时添加主函数入口:

优化后的完整代码

def load_key(file_path="keys.txt", default_key="default"):
    with open(file_path, "r") as f:
        for line in f:
            line = line.strip()
            if line.startswith("vg:"):
                return line.lstrip("vg: ").strip()
    return default_key

# 预定义字符映射,仅初始化一次
CHAR_TO_IDX = {c: i for i, c in enumerate("abcdefghijklmnopqrstuvwxyz")}
IDX_TO_CHAR = {i: c for i, c in enumerate("abcdefghijklmnopqrstuvwxyz")}

def _shift_char(char, key_char, shift_direction):
    """通用字符移位函数,shift_direction为1表示加密(加),-1表示解密(减)"""
    is_upper = char.isupper()
    char_lower = char.lower()
    if char_lower not in CHAR_TO_IDX:
        return char
    char_idx = CHAR_TO_IDX[char_lower]
    key_idx = CHAR_TO_IDX[key_char.lower()]
    new_idx = (char_idx + shift_direction * key_idx) % 26
    new_char = IDX_TO_CHAR[new_idx]
    return new_char.upper() if is_upper else new_char

def encrypt(phrase, key):
    key_len = len(key)
    result = []
    key_idx = 0
    for char in phrase:
        result.append(_shift_char(char, key[key_idx % key_len], 1))
        if char.lower() in CHAR_TO_IDX:
            key_idx += 1
    return "".join(result)

def decrypt(cypher, key):
    key_len = len(key)
    result = []
    key_idx = 0
    for char in cypher:
        result.append(_shift_char(char, key[key_idx % key_len], -1))
        if char.lower() in CHAR_TO_IDX:
            key_idx += 1
    return "".join(result)

def load_and_decrypt_file(file_path, key):
    with open(file_path, "r") as f:
        return decrypt(f.read(), key).splitlines(keepends=True)

def save_encrypted_file(content_lines, file_path, key):
    encrypted_content = encrypt("".join(content_lines), key)
    with open(file_path, "w") as f:
        f.write(encrypted_content)

def main():
    # 加载密钥
    vgKey = load_key()
    # 读取并解密文件
    decrypted_lines = load_and_decrypt_file("DBIEncrypted.csv", vgKey)
    print("".join(decrypted_lines))
    
    # 处理编辑输入
    row = input("Which row would you like to edit? Type n for a new row.\n").strip()
    if row:
        text = input("What would you like the new value to be?\n").strip()
        if row.lower() == "n":
            decrypted_lines.append(text + "\n")
        else:
            try:
                row_idx = int(row)
                if 0 <= row_idx < len(decrypted_lines):
                    decrypted_lines[row_idx] = text + "\n"
                else:
                    print("Row index out of range")
            except ValueError:
                print("Invalid row number, please enter a number or 'n'")
    
    # 重新加密保存
    save_encrypted_file(decrypted_lines, "DBIEncrypted.csv", vgKey)

if __name__ == "__main__":
    main()

内容的提问来源于stack exchange,提问作者Euler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:14:53