@@ -47,7 +47,9 @@ async def get_select_token(code: str):
4747 :return:
4848 """
4949 token = settings .admin_token
50- return hashlib .sha256 (f"{ code } { int (time .time () / 1000 )} 000{ token } " .encode ()).hexdigest ()
50+ return hashlib .sha256 (
51+ f"{ code } { int (time .time () / 1000 )} 000{ token } " .encode ()
52+ ).hexdigest ()
5153
5254
5355async def get_file_url (code : str ):
@@ -95,6 +97,44 @@ def gen_desc_en(value: int, desc: str):
9597 return desc_zh , desc_en
9698
9799
100+ def hash_password (password : str ) -> str :
101+ """
102+ 使用 SHA256 + salt 哈希密码
103+ 返回格式: sha256$<salt>$<hash>
104+ """
105+ salt = os .urandom (16 ).hex ()
106+ password_hash = hashlib .sha256 (f"{ salt } { password } " .encode ()).hexdigest ()
107+ return f"sha256${ salt } ${ password_hash } "
108+
109+
110+ def verify_password (password : str , hashed : str ) -> bool :
111+ """
112+ 验证密码是否匹配
113+ 支持新格式 (sha256$salt$hash) 和旧格式 (明文)
114+ """
115+ if not hashed :
116+ return False
117+
118+ # 新格式: sha256$salt$hash
119+ if hashed .startswith ("sha256$" ):
120+ parts = hashed .split ("$" )
121+ if len (parts ) != 3 :
122+ return False
123+ _ , salt , stored_hash = parts
124+ password_hash = hashlib .sha256 (f"{ salt } { password } " .encode ()).hexdigest ()
125+ return password_hash == stored_hash
126+
127+ # 旧格式: 明文比较 (兼容迁移前的数据)
128+ return password == hashed
129+
130+
131+ def is_password_hashed (password : str ) -> bool :
132+ """
133+ 检查密码是否已经是哈希格式
134+ """
135+ return password .startswith ("sha256$" ) and len (password .split ("$" )) == 3
136+
137+
98138async def sanitize_filename (filename : str ) -> str :
99139 """
100140 安全处理文件名:
@@ -105,15 +145,15 @@ async def sanitize_filename(filename: str) -> str:
105145 filename = os .path .basename (filename )
106146 illegal_chars = r'[\\/*?:"<>|\x00-\x1F]' # 包含控制字符
107147 # 替换非法字符为下划线
108- cleaned = re .sub (illegal_chars , '_' , filename )
148+ cleaned = re .sub (illegal_chars , "_" , filename )
109149 # 处理空格(可选替换为_)
110- cleaned = cleaned .replace (' ' , '_' )
150+ cleaned = cleaned .replace (" " , "_" )
111151 # 处理连续下划线
112- cleaned = re .sub (r'_+' , '_' , cleaned )
152+ cleaned = re .sub (r"_+" , "_" , cleaned )
113153 # 处理首尾特殊字符
114- cleaned = cleaned .strip ('._' )
154+ cleaned = cleaned .strip ("._" )
115155 # 处理空文件名情况
116156 if not cleaned :
117- cleaned = ' unnamed_file'
157+ cleaned = " unnamed_file"
118158 # 长度限制(按需调整)
119159 return cleaned [:255 ]
0 commit comments