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

Python注册功能加密密码时出现UnicodeEncodeError报错求解决方案

问题描述

开发模拟用户注册程序时,选择「创建账户」选项可将用户名密码存入对应txt文件,基础功能运行正常。新增维吉尼亚密码加密逻辑后运行程序触发编码错误,单独运行加密模块无异常。

报错信息

File "C:\Program\Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\x95' in position 2: character maps to "undefined"

相关代码

业务代码

# coding: utf-8

import colorama
from colorama import Fore, Back, Style
import os
import time
import platform
import shutil
import sys
import _socket
import socket
from Cryptage import *

#-------------------------------------------------------------------------------------------------

cle= open("cle.txt","r", encoding="utf-8")
cle=cle.read()
colorama.init(autoreset = True)
Boucle = 1
Pseudo = ""
encoded_string = ''

#-------------------------------------------------------------------------------------------------


def Clean():
    if platform.system() == "Windows":
        os.system("cls")
    elif platform.system() == "Linux":
        os.system("clear")

#-------------------------------------------------------------------------------------------------

def Acceuil():

    Clean()
    print(Fore.BLUE+"<===ACCEUIL===>")
    print(Fore.BLUE+"---------------------------------------------------------------------")
    print(Fore.BLUE+"1. Se connecter")
    print(Fore.BLUE+"2. S'inscrire")
    print(Fore.BLUE+"3. Quitter")
    print(Fore.BLUE+"---------------------------------------------------------------------")
    choix = input()

    if choix =='1':
        Connexion()
    
    elif choix =='2':
        Register()
    
    elif choix =='3':
        Clean()
        print("Fin du programme...")
        time.sleep(2.4)
        sys.exit()

    else:
        Clean()
        print(Fore.RED + "invalide")
        colorama.init(autoreset = True)

    #-------------------------------------------------------------------------------------------------

def Register():

    Clean()

    print(Fore.BLUE+"<===INSCRIPTION===>")
    print(Fore.BLUE+"---------------------------------------------------------------------")
    Pseudo, MDP = input(Fore.BLUE+"Pseudo, MDP: ").split()


    TxtUser = "{Pseudo2}.txt".format(Pseudo2=Pseudo)
    CheminBase = "C:\\Users\\yuris\\Desktop\\Python\\GestionDeCompte\\{TxtUser2}".format(TxtUser2=TxtUser)
    CheminArriver = "C:\\Users\\yuris\\Desktop\\Python\\GestionDeCompte\\Users\\{TxtUser2}".format(TxtUser2=TxtUser)

    MDPcrypted = encode(cle, MDP)

if os.path.exists(CheminArriver):

    Clean()
    print(Fore.RED+"Le Pseudo",Fore.RED+Pseudo,Fore.RED+"Existe deja")
    input()

 
else:

    NewUser = open(TxtUser,"x")
    NewUser.close()

    NewUser = open(TxtUser,"a")
    NewUser.write("Pseudo: ")
    NewUser.write(Pseudo)
    NewUser.write("! ")

    NewUser.write("MDP: ")
    NewUser.write( MDPcrypted)
    NewUser.write("!")
    NewUser.close()

    shutil.move(CheminBase,CheminArriver)
    print(Fore.BLUE+"Déplacement vers connexion...")
    time.sleep(2.4)
    Connexion()

        #-------------------------------------------------------------------------------------------------

def Connexion():

    Clean()
    print(Fore.BLUE+"<===CONNEXION===>")
    print(Fore.BLUE+"---------------------------------------------------------------------")
    Pseudo, MDP = input(Fore.BLUE+"Pseudo, MDP: ").split()
    print(Fore.BLUE+"---------------------------------------------------------------------")

    TxtUser = "{Pseudo2}.txt".format(Pseudo2=Pseudo)
    CheminArriver = "C:\\Users\\yuris\\Desktop\\Python\\GestionDeCompte\\Users\\{TxtUser2}".format(TxtUser2=TxtUser)

    if os.path.exists(CheminArriver) :

        MDPregister = "{MDP2}!".format(MDP2=MDP)
        UserConnect = open(CheminArriver,"r")
    
        for ligne in  UserConnect:
            if MDPregister in ligne:
                MenuPrincipal()
            else:
                print(Fore.RED+"Le Pseudo ou le MDP est invalide")
                input()
 
    else:
        print(Fore.RED+"Le Pseudo ou le MDP est invalide")
        input()

#-------------------------------------------------------------------------------------------------

def MenuPrincipal():
    while Boucle != 0:

        Clean()
   
        print(Fore.GREEN+"Bienvenue",Fore.GREEN+Pseudo)
        input()
 
#-------------------------------------------------------------------------------------------------

while Boucle != 0:

    Acceuil()
    print("")

加密模块代码(维吉尼亚密码实现)

# coding: utf-8
# vigenere cipher

#--------------------------------------------------------------------------------

cle= open("cle.txt","r", encoding="utf-8")
cle=cle.read()

#--------------------------------------------------------------------------------
        
def encode(cle, string):
    encoded_chars = []
    for i in range(len(string)):
        key_c =cle[i % len(cle)]
        encoded_c = chr(ord(string[i]) + ord(key_c) % 256)
        encoded_chars.append(encoded_c)
    encoded_string = ''.join(encoded_chars)
    return encoded_string

def decode(cle, string):
    encoded_chars = []
    for i in range(len(string)):
        key_c = cle[i % len(cle)]
        encoded_c = chr((ord(string[i]) - ord(key_c) + 256) % 256)
        encoded_chars.append(encoded_c)
    encoded_string = ''.join(encoded_chars)
    return encoded_string
报错原因
  • Windows系统下Python的open()函数默认使用系统默认编码(此处为cp1252编码)操作文件,你实现的维吉尼亚加密会生成0-255区间的单字节字符,其中部分字符不存在cp1252的编码映射表,写入文件触发编码转换失败。
  • 单独运行加密模块无异常是因为仅在内存中处理字符串,没有触发写入文件的编码转换步骤。
解决方案

方案1:指定文件编码为latin-1

latin-1编码支持所有0-255区间的单字节字符,完全匹配加密后的输出格式,修改所有文件操作的open()语句,显式指定编码:

  • 创建用户文件:NewUser = open(TxtUser,"x", encoding="latin-1")
  • 写入用户信息:NewUser = open(TxtUser,"a", encoding="latin-1")
  • 读取用户文件校验登录:UserConnect = open(CheminArriver,"r", encoding="latin-1")

方案2:加密结果转base64存储

将加密后的字符串转成base64格式的可打印字符再存储,完全避免编码兼容问题,适配所有系统环境:

  1. 引入base64模块:import base64
  2. 写入加密密码前转换:MDPcrypted = base64.b64encode(MDPcrypted.encode('latin-1')).decode('ascii')
  3. 读取校验密码前先解码base64,再调用解密函数校验即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:27:03