自制小程序

十六进制文本写入文件小程序

程序下载连接

通过网盘分享的文件:HexConverter.exe
链接: https://pan.baidu.com/s/106Zf4DtXFi8KrL6nq3kF7w 提取码: pxgm

源代码

import tkinter as tk
from tkinter import filedialog, messagebox
import os
import sys

class HexConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("十六进制到二进制转换器")
        self.root.geometry("500x300")

        # 获取程序所在目录
        self.app_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))

        # 创建界面元素
        self.create_widgets()

    def create_widgets(self):
        # 程序标题
        tk.Label(self.root, text="十六进制到二进制转换器", font=("Arial", 14, "bold")).pack(pady=15)

        # 输入文件选择
        tk.Label(self.root, text="选择包含16进制数据的TXT文件:").pack(pady=(5, 0), anchor="w", padx=20)

        self.input_frame = tk.Frame(self.root)
        self.input_frame.pack(fill=tk.X, padx=20)

        self.input_entry = tk.Entry(self.input_frame, width=40)
        self.input_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)

        self.browse_input = tk.Button(self.input_frame, text="浏览...", command=self.browse_input_file)
        self.browse_input.pack(side=tk.RIGHT, padx=(5, 0))

        # 分隔线
        tk.Frame(self.root, height=2, bg="gray").pack(fill=tk.X, padx=10, pady=15)

        # 输出文件名和类型设置
        tk.Label(self.root, text="输出文件设置:").pack(pady=(5, 0), anchor="w", padx=20)

        # 文件名部分
        tk.Label(self.root, text="输出文件名(不含扩展名):").pack(pady=(10, 0), anchor="w", padx=20)
        self.filename_entry = tk.Entry(self.root, width=40)
        self.filename_entry.pack(fill=tk.X, padx=20)
        self.filename_entry.insert(0, "output")  # 默认文件名

        # 文件类型部分
        tk.Label(self.root, text="文件扩展名(如 bin, dat, hex等):").pack(pady=(10, 0), anchor="w", padx=20)
        self.filetype_entry = tk.Entry(self.root, width=40)
        self.filetype_entry.pack(fill=tk.X, padx=20)
        self.filetype_entry.insert(0, "bin")  # 默认扩展名

        # 转换按钮
        self.convert_btn = tk.Button(self.root, text="开始转换", command=self.convert,
                                     bg="#4CAF50", fg="white", font=("Arial", 10, "bold"),
                                     height=2, width=15)
        self.convert_btn.pack(pady=15)

        # 状态标签
        self.status_label = tk.Label(self.root, text="准备好转换")
        self.status_label.pack()

        # 添加提示信息
        tk.Label(self.root, text=f"输出文件将保存在: {self.app_dir}", fg="gray").pack(side=tk.BOTTOM, pady=5)

    def browse_input_file(self):
        file_path = filedialog.askopenfilename(
            title="选择输入文件",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
        )
        if file_path:
            self.input_entry.delete(0, tk.END)
            self.input_entry.insert(0, file_path)
            self.status_label.config(text=f"已选择输入文件: {os.path.basename(file_path)}")

    def get_output_path(self):
        """获取输出文件完整路径"""
        filename = self.filename_entry.get().strip()
        filetype = self.filetype_entry.get().strip()

        if not filename:
            filename = "output"
        if not filetype:
            filetype = "bin"

        # 确保文件类型不以点开头
        if filetype.startswith("."):
            filetype = filetype[1:]

        return os.path.join(self.app_dir, f"{filename}.{filetype}")

    def convert(self):
        in_path = self.input_entry.get()
        out_path = self.get_output_path()

        if not in_path:
            messagebox.showerror("错误", "请选择输入文件")
            return

        if os.path.exists(out_path):
            response = messagebox.askyesno("文件已存在", f"文件 {os.path.basename(out_path)} 已存在,是否覆盖?")
            if not response:
                self.status_label.config(text="用户取消覆盖文件")
                return

        try:
            # 读取并处理十六进制数据
            with open(in_path, 'r', encoding='utf-8') as f:
                hex_data = f.read()

            # 移除空格、换行等非十六进制字符
            hex_data = ''.join(filter(str.isalnum, hex_data))

            # 验证十六进制数据
            if not all(c in '0123456789abcdefABCDEF' for c in hex_data):
                raise ValueError("文件包含无效的十六进制字符")

            # 检查长度是否为偶数(每个字节需要两个十六进制字符)
            if len(hex_data) % 2 != 0:
                raise ValueError("十六进制数据的长度应该是偶数")

            # 转换为二进制数据
            binary_data = bytes.fromhex(hex_data)

            # 写入输出文件
            with open(out_path, 'wb') as f:
                f.write(binary_data)

            # 显示结果
            file_info = f"{os.path.basename(out_path)} ({len(binary_data)} 字节)"
            self.status_label.config(text=f"转换成功!创建文件: {file_info}")
            messagebox.showinfo("成功", f"转换完成!\n已创建文件: {out_path}\n大小: {len(binary_data)} 字节")

        except UnicodeDecodeError:
            # 尝试其他编码
            try:
                with open(in_path, 'r', encoding='latin-1') as f:
                    hex_data = f.read()
                self.convert()  # 重试转换
            except Exception as e:
                messagebox.showerror("编码错误", f"无法读取文件: {str(e)}")
                self.status_label.config(text="文件编码错误")

        except Exception as e:
            messagebox.showerror("错误", f"转换过程中出错: {str(e)}")
            self.status_label.config(text=f"转换失败: {str(e)}")


# 创建主窗口
if __name__ == "__main__":
    root = tk.Tk()
    app = HexConverterApp(root)
    root.mainloop()

文本ip地址提取器

下载链接

通过网盘分享的文件:ip地址提取器
链接: https://pan.baidu.com/s/1MkTpo-m5fck-fVxUoPYlTA 提取码: 97gc

源代码

import re
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
import sys
from PIL import Image, ImageTk

def extract_ips(input_file):
    """提取文本中的所有IP地址并进行去重和验证"""
    ip_pattern = r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b'
    unique_ips = set()

    try:
        with open(input_file, 'r', encoding='utf-8') as file:
            content = file.read()
            ips = re.findall(ip_pattern, content)

            for ip in ips:
                # 验证IP地址的每部分是否有效
                parts = ip.split('.')
                if all(0 <= int(part) <= 255 for part in parts):
                    unique_ips.add(ip)

    except Exception as e:
        return None, f"处理文件时出错: {str(e)}"

    if not unique_ips:
        return None, "文件中未找到有效的IP地址"

    # 创建输出文件名
    base_name = os.path.basename(input_file)
    output_file = os.path.join(
        os.path.dirname(input_file),
        f"ip_addresses.txt"
    )

    try:
        with open(output_file, 'w', encoding='utf-8') as file:
            # 按数值排序(更直观)
            sorted_ips = sorted(unique_ips, key=lambda ip: tuple(map(int, ip.split('.'))))
            file.write("\n".join(sorted_ips))
        return output_file, f"成功提取 {len(sorted_ips)} 个唯一IP地址"
    except Exception as e:
        return None, f"写入输出文件时出错: {str(e)}"

class IPExtractorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("IP地址提取工具")
        self.root.geometry("600x450")
        self.root.resizable(True, True)
        self.root.configure(bg="#f0f0f0")

        # 设置应用图标
        try:
            self.root.iconbitmap(os.path.join(sys.path[0], "ip_icon.ico"))
        except:
            pass

        # 顶部标题
        title_frame = tk.Frame(root, bg="#3F72AF")
        title_frame.pack(fill="x", padx=10, pady=(10, 5))

        tk.Label(
            title_frame,
            text="IP地址提取工具",
            font=("Arial", 18, "bold"),
            fg="white",
            bg="#3F72AF"
        ).pack(pady=15)

        # 说明文本
        info_label = tk.Label(
            root,
            text="本工具用于从文本文件中提取所有有效的IP地址,并生成一个去重后的IP列表",
            font=("Arial", 10),
            wraplength=500,
            bg="#f0f0f0"
        )
        info_label.pack(pady=(0, 15))

        # 输入文件区域
        input_frame = tk.Frame(root, bg="#f0f0f0")
        input_frame.pack(fill="x", padx=40, pady=5)

        tk.Label(
            input_frame,
            text="输入文件:",
            font=("Arial", 10, "bold"),
            bg="#f0f0f0"
        ).grid(row=0, column=0, sticky="w", pady=5)

        self.input_path = tk.StringVar()
        self.input_entry = tk.Entry(
            input_frame,
            textvariable=self.input_path, 
            width=50,
            state="readonly"
        )
        self.input_entry.grid(row=1, column=0, sticky="ew", padx=(0, 10))

        browse_btn = tk.Button(
            input_frame,
            text="浏览...",
            command=self.browse_file,
            bg="#4CAF50",
            fg="white",
            relief="flat",
            font=("Arial", 9, "bold")
        )
        browse_btn.grid(row=1, column=1, sticky="e")

        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(
            root, 
            variable=self.progress_var,
            length=500,
            mode="indeterminate"
        )
        self.progress_bar.pack(pady=15, padx=40, fill="x")
        self.progress_bar.pack_forget()  # 初始隐藏

        # 动作按钮
        btn_frame = tk.Frame(root, bg="#f0f0f0")
        btn_frame.pack(pady=15)

        self.extract_btn = tk.Button(
            btn_frame, 
            text="提取IP地址",
            command=self.process_file,
            bg="#3F72AF",
            fg="white",
            font=("Arial", 10, "bold"),
            width=15,
            height=1
        )
        self.extract_btn.pack(side="left", padx=10)

        reset_btn = tk.Button(
            btn_frame,
            text="重置",
            command=self.reset,
            bg="#FF9800",
            fg="white",
            font=("Arial", 10, "bold"),
            width=15,
            height=1
        )
        reset_btn.pack(side="left", padx=10)

        # 结果区域
        result_frame = tk.Frame(root, bg="#f0f0f0")
        result_frame.pack(fill="both", expand=True, padx=40, pady=10)

        tk.Label(
            result_frame,
            text="操作结果:",
            font=("Arial", 10, "bold"),
            bg="#f0f0f0"
        ).pack(anchor="w")

        self.result_text = tk.Text(
            result_frame,
            height=5,
            wrap="word",
            bg="white"
        )
        self.result_text.pack(fill="both", expand=True, pady=5)
        self.result_text.config(state="disabled")

        # 状态栏
        self.status_var = tk.StringVar(value="就绪")
        status_bar = tk.Label(
            root, 
            textvariable=self.status_var,
            anchor="w",
            relief="sunken",
            bg="#E0E0E0",
            fg="#333"
        )
        status_bar.pack(side="bottom", fill="x", ipady=5)

        # 初始化变量
        self.processing = False

        # 调整布局
        input_frame.columnconfigure(0, weight=1)

    def browse_file(self):
        """打开文件选择对话框"""
        if self.processing:
            return

        file_path = filedialog.askopenfilename(
            title="选择文本文件",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
        )

        if file_path:
            self.input_path.set(file_path)
            self.status_var.set(f"已选择文件: {file_path}")

    def process_file(self):
        """处理选择的文件"""
        if self.processing:
            return

        input_file = self.input_path.get()
        if not input_file:
            messagebox.showwarning("警告", "请先选择一个文本文件!")
            return

        if not os.path.isfile(input_file):
            messagebox.showerror("错误", "文件不存在或不是有效文件!")
            return

        # 禁用按钮和显示进度
        self.processing = True
        self.extract_btn.config(state="disabled")
        self.progress_bar.pack(pady=15, padx=40, fill="x")
        self.progress_bar.start(10)
        self.status_var.set("正在提取IP地址...")
        self.root.update()

        # 执行提取
        output_file, message = extract_ips(input_file)

        # 停止进度条
        self.progress_bar.stop()
        self.progress_bar.pack_forget()
        self.extract_btn.config(state="normal")
        self.processing = False

        # 显示结果
        self.result_text.config(state="normal")
        self.result_text.delete(1.0, tk.END)

        if output_file:
            self.result_text.insert(tk.END, message + "\n\n")
            self.result_text.insert(tk.END, f"输出文件位置:\n{output_file}\n\n")
            self.result_text.insert(tk.END, "提示: 文件已保存到输入文件所在目录")
            self.result_text.tag_add("success", "1.0", "end")
            self.result_text.tag_config("success", foreground="green")
            self.status_var.set(f"成功提取IP地址,保存到: {output_file}")

            # 询问是否打开输出文件
            answer = messagebox.askyesno("成功", f"{message}\n\n是否要打开输出文件?")
            if answer:
                try:
                    os.startfile(output_file)  # Windows系统
                except:
                    try:
                        import subprocess
                        subprocess.Popen(["open", output_file])  # macOS
                    except:
                        pass
        else:
            self.result_text.insert(tk.END, "错误信息:\n")
            self.result_text.insert(tk.END, message)
            self.result_text.tag_add("error", "1.0", "end")
            self.result_text.tag_config("error", foreground="red")
            self.status_var.set("提取失败")
            messagebox.showerror("错误", message)

        self.result_text.config(state="disabled")

    def reset(self):
        """重置界面"""
        if self.processing:
            return

        self.input_path.set("")
        self.result_text.config(state="normal")
        self.result_text.delete(1.0, tk.END)
        self.result_text.config(state="disabled")
        self.status_var.set("就绪")

# 创建主窗口
if __name__ == "__main__":
    root = tk.Tk()
    app = IPExtractorApp(root)
    root.mainloop()