|
1 | 1 | # coding=utf-8
|
2 | 2 | # @Author:香草味的纳西妲
|
3 | 3 | # Email:nahida1027@126.com
|
4 |
| -# Date:2024/12/19 |
| 4 | +# Date:2025/02/01 |
5 | 5 |
|
6 | 6 | import os
|
7 | 7 | import sys
|
8 | 8 | import shutil
|
9 | 9 | import struct
|
10 |
| -import mimetypes |
11 |
| -import subprocess |
| 10 | +import chardet |
12 | 11 | import configparser
|
13 | 12 | from tqdm import tqdm
|
14 | 13 | from time import sleep
|
15 | 14 | from pathlib import Path
|
16 | 15 | import tkinter as tk
|
17 | 16 | from tkinter import filedialog
|
18 | 17 |
|
| 18 | +def read_file_with_correct_encoding(file_path, target_string): |
| 19 | + print("正在判断QQ配置文件编码类型") |
| 20 | + try: |
| 21 | + with open(file_path, 'rb') as f: |
| 22 | + data = f.read() |
| 23 | + except Exception as e: |
| 24 | + print(f"文件读取失败: {e}") |
| 25 | + return False |
| 26 | + |
| 27 | + # ------------------------- 编码检测优化 ------------------------- |
| 28 | + # 1. 优先尝试中文相关编码(GB18030覆盖GBK,兼容性更好) |
| 29 | + priority_encodings = ['gb18030', 'utf-8', 'utf-16', 'ascii'] |
| 30 | + |
| 31 | + # 2. 使用cchardet检测(比chardet更快更准) |
| 32 | + try: |
| 33 | + detected = chardet.detect(data) |
| 34 | + if detected['encoding']: |
| 35 | + # 如果检测到的是非中文编码且置信度低,将其后置 |
| 36 | + if detected['confidence'] < 0.7 or detected['encoding'].lower() not in ['gb18030', 'gbk', 'utf-8']: |
| 37 | + priority_encodings.append(detected['encoding']) |
| 38 | + else: |
| 39 | + priority_encodings.insert(0, detected['encoding']) # 高置信度中文编码前置 |
| 40 | + except: |
| 41 | + pass |
| 42 | + |
| 43 | + # 3. 补充其他可能编码并去重 |
| 44 | + encodings = priority_encodings + [ |
| 45 | + 'gbk', 'big5', 'utf-16-le', 'utf-16-be', 'shift_jis', |
| 46 | + 'iso-8859-1', 'latin-1', 'cp936', 'cp950', 'utf-7' |
| 47 | + ] |
| 48 | + seen = set() |
| 49 | + ordered_encodings = [] |
| 50 | + for enc in encodings: |
| 51 | + enc_lower = enc.lower() |
| 52 | + if enc_lower not in seen: |
| 53 | + seen.add(enc_lower) |
| 54 | + ordered_encodings.append(enc) |
| 55 | + |
| 56 | + # ------------------------- 解码验证优化 ------------------------- |
| 57 | + for enc in ordered_encodings: |
| 58 | + try: |
| 59 | + content = data.decode(enc, errors='strict') # 严格模式避免静默错误 |
| 60 | + except (UnicodeDecodeError, LookupError): |
| 61 | + continue |
| 62 | + # 改进验证:检查目标字符串且无异常字符(如乱码) |
| 63 | + if target_string in content and is_content_valid(content): |
| 64 | + print(f"成功解码! | 检测到的编码类型为: {enc.ljust(12)}") |
| 65 | + return enc.ljust(12) |
| 66 | + print("解码失败,未找到匹配编码。") |
| 67 | + return None |
| 68 | + |
| 69 | +def is_content_valid(content, min_chinese=1): |
| 70 | + # 验证内容是否包含至少一个中文字符(避免误判为拉丁编码) |
| 71 | + chinese_chars = sum('\u4e00' <= char <= '\u9fff' for char in content) |
| 72 | + return chinese_chars >= min_chinese |
| 73 | + |
19 | 74 | def get_userdata_save_path():
|
20 | 75 | '''获取用户数据目录存储所在位置'''
|
21 | 76 | # 指定 INI 文件的路径
|
22 | 77 | ini_file_path = r'C:\Users\Public\Documents\Tencent\QQ\UserDataInfo.ini'
|
23 | 78 |
|
| 79 | + target_string = '[UserDataSet]' |
| 80 | + # 判断编码类型 |
| 81 | + encode = read_file_with_correct_encoding(ini_file_path, target_string) |
| 82 | + |
24 | 83 | # 创建 ConfigParser 对象
|
25 | 84 | config = configparser.ConfigParser()
|
26 | 85 |
|
27 | 86 | # 读取 INI 文件
|
28 | 87 | try:
|
29 |
| - print("开始使用UTF-8读取QQ配置文件") |
30 |
| - config.read(ini_file_path, encoding='utf-8') |
31 |
| - except UnicodeDecodeError: |
32 |
| - print("UTF-8解码QQ配置文件出错!正在尝试以GBK编码打开文件……") |
33 |
| - config.read(ini_file_path, encoding='gbk') |
| 88 | + print(f"开始使用{encode}读取QQ配置文件") |
| 89 | + config.read(ini_file_path, encoding = encode) |
| 90 | + except UnicodeDecodeError as e: |
| 91 | + print(f"{encode}解码QQ配置文件出错,请将下方报错信息丢给开发者!\n{e}") |
| 92 | + print("无法打开QQ配置文件,程序退出!") |
| 93 | + exit() |
34 | 94 | except FileNotFoundError:
|
35 | 95 | print(f"错误: 未找到QQ配置文件“{ini_file_path}”\n可能原因是你未安装QQ或未登录QQ")
|
36 | 96 | return None
|
|
0 commit comments