用 Python 还原 RC4 + JWT + 自定义 SSO Token 加解密(含可运行示例)

用 Python 还原 RC4 + JWT + 自定义 SSO Token 加解密(含可运行示例) 副标题 / 摘要 这篇文章带你从 0 拆解 RC4 流加密、Base64/Hex 编码,以及基于 JWT 与自定义 SSO 的鉴权设计,并给出可以复制运行的 Python 示例。示例中的密钥与发行方均为占位值,切勿用于生产。 目标读者 Python 后端/测试工程师(中级) 对鉴权、令牌与基础加密流程感兴趣的开发者 想理解 RC4 工作方式与替代方案的安全入门读者 背景 / 动机 在实际项目中,我们常需要为 HTTP 或 WebSocket 请求附带令牌进行身份校验。常见做法包括使用 JWT(对称/非对称签名)或自定义的 SSO Token(例如对某段明文进行对称加密后再以 Hex/Base64 编码)。本文整理并复现一种组合方案:RC4+Base64/Hex 与 JWT/SSO 的加解密与校验流程,帮助你在测试或 PoC 中快速上手,同时理解其安全取舍。 核心概念 RC4:经典流加密(已不再安全)。通过密钥调度(KSA)与伪随机序列(PRGA)生成密钥流,与明文字节按位异或得到密文。解密过程与加密一致(同一函数)。 Base64 与 Hex:两种将二进制数据编码为可传输文本的方式。Base64 更紧凑;Hex 可读、调试直观。 JWT:JSON Web Token。Header.Payload.Signature。常包含 iss(发行方)、aud(受众/自定义)、iat/exp(签发/过期)。 自定义 SSO Token:一种自定义明文格式(示例采用 issuer_expire_ts_userSeqId_userId),经对称加密后再编码为 Hex,便于在 HTTP 头中传输。 限制与风险:RC4 已过时且不建议用于生产;如需兼容遗留系统,应仅在测试/过渡场景,且搭配 TLS、短周期、签名与回放防护。 实践指南 / 步骤 安装依赖 pip install pyjwt 设定占位常量(不要使用真实密钥/发行方) ISSUER = "demo-issuer" SECRET = "demo-secret-change-me" RC4KEY = "demo-rc4-key-change-me" UTE_ISSUER = "ute-demo" 实现 RC4 与常用编码包装 encrypt_string/decrypt_string:RC4 后 Base64 encrypt_hex_string/decrypt_hex_string:RC4 后 Hex 构造与校验 JWT(x-auth-token) aud = [Base64(RC4(user_id)), Base64(RC4(user_seq_id))] iss/iat/exp 等标准字段 构造与校验 SSO Token(x-sso-token) 明文 UTE_ISSUER_expire_ts_userSeqId_userId → RC4 → Hex 校验发行方与过期时间 运行演示,观察生成与校验结果 可运行示例(完整代码) 仅用于学习与测试,切勿将 RC4 用于生产环境。请优先使用现代 AEAD(AES‑GCM/ChaCha20‑Poly1305)。 ...

2025年11月19日 · 4 分钟 · map[name:Jeanphilo]

一位与两位编码解析的刷题笔记与工程应用全解析(续集,LeetCode 717)

一位与两位编码解析的刷题笔记与工程应用全解析(续集,LeetCode 717) 副标题 / 摘要 本文解析 LeetCode《1-bit and 2-bit Characters》题目,讲解如何用简单的指针跳跃算法解析二进制编码序列,并展示该算法在通信协议、数据格式解析、事件流处理等工程场景中的真实应用。适合希望将算法题知识迁移到工程系统的开发者。 目标读者 刷 LeetCode、准备技术面试的开发者 对通信协议、序列解析、数据流处理感兴趣的工程师 想提升“抽象能力与工程迁移能力”的同学 从事监控、序列分析、协议解析等工作的后端开发者 背景 / 动机:为什么这题值得写一篇博客? 乍一看,这道题好像只是简单判断: 一个由 0/1 组成的编码流,最后一个 0 是否单独构成一个 1 位字符? 但本质上它对应的是 “变长编码(Variable-Length Coding)解析”,而变长编码在工程中极其常见,比如: UTF-8 字符解析 网络包头编码解析 字节码指令流解析 数据压缩(如 Huffman Coding) 通信协议中的 Frame 解析 行为序列中用跳表式结构编码的事件 因此,这道题不仅是算法题,更是“从左向右解析变长编码的模型题”。 理解这题,就是理解大量系统底层的基础。 核心概念 1. 变长编码(Variable-Length Encoding) 题目中规定了两种编码: 1 位字符:0 2 位字符:10 或 11 这是一种简化的变长编码结构:字符长度取决于首位。 工程中常见: 系统 变长规则 UTF-8 1~4 字节,根据前缀位判断长度 TLV 协议 T + 长度字段决定 Value 长度 字节码流 opcode 决定后续参数个数 硬件指令集 有变长和固定长度两类 题目正是这些系统的「极简模型」。 ...

2025年11月18日 · 3 分钟 · map[name:Jeanphilo]

How to Build a Blog System

标题:用 Hugo + GitHub Pages 十分钟上线个人博客(超详细新手指南) 副标题 / 摘要 本教程带你从零开始,将本地 Hugo 博客部署到 GitHub Pages,全程只需 10 分钟,适合想快速上线技术博客、文档站点的开发者。确保你不仅能跑起来,还能理解背后的工作原理。 目标读者 Hugo 初学者 想快速上线个人技术博客的开发者 想了解 GitHub Pages + GitHub Actions 部署的用户 想要零成本托管静态网站的同学 背景 / 动机:为什么要用 Hugo + GitHub Pages? 许多人写博客时面临这些痛点: 发布文章要手动上传,不自动化 静态站点生成器很多,但部署步骤零散 GitHub Pages 文档不够清晰,新手容易踩坑 主题(如 PaperMod)需要正确处理资源(SCSS)才能编译成功 Hugo + GitHub Pages + GitHub Actions 组合 完美解决了这些问题: Hugo 构建速度极快(上千文章依旧瞬间生成) GitHub Pages 完全免费,不需要服务器 GitHub Actions 自动部署,写完文章 push 即上线 核心概念(必须理解) 1. Hugo 一个超快的静态博客生成器,通过 Markdown 生成 HTML。 2. GitHub Pages GitHub 提供的免费静态网站托管。 ...

2025年11月14日 · 3 分钟 · map[name:Jeanphilo]

How to Publish by Hugo

标题:如何使用 Hugo 发布文章:从 Markdown 到线上博客的全流程指南 副标题 / 摘要 这篇文章教你如何使用 Hugo 创建、管理与发布文章,包括 front matter 设置、草稿管理、图片处理、目录结构、预览与上线,让你从零掌握完整写作流程。 目标读者 Hugo 初学者 想用 Hugo 搭建技术博客的人 想学习 Markdown + 静态站点写作流程的开发者 使用 PaperMod、DoIt 等主题的用户 背景 / 动机 很多人在成功搭建 Hugo 博客后会遇到新的困惑: 文章应该放在哪个目录? front matter 要怎么写? 图片要放哪? 为什么本地能看到文章但线上看不到? 草稿 / 发布时间如何控制? 怎样让文章自动出现在首页? 这些都是 Hugo 新手非常常见的痛点。 本教程用实战步骤 + 最佳实践帮助你完全掌握“如何发布文章”的整个流程。 核心概念 1. Hugo Content(内容目录) Hugo 的文章都放在 content/ 目录下,比如: content/ posts/ my-first-post.md 2. Front Matter 文章头部的三段 YAML/TOML/JSON,用来控制文章: --- title: "文章标题" date: 2024-08-26 draft: false tags: ["hugo", "blog"] --- 3. Draft(草稿) 草稿不会被构建,只能在本地用 hugo server -D 查看。 ...

2025年11月14日 · 3 分钟 · map[name:Jeanphilo]

用一段优雅的python代码,把sqlalchemy模型高效转为字典

标题 用一段优雅的 Python 代码,把 SQLAlchemy 模型安全、高效地序列化成字典 副标题 / 摘要 SQLAlchemy 模型转字典(dict)看似简单,却暗藏字段格式、关系递归、循环引用等坑。本文通过一段实战代码,带你实现一个可复用的 _to_dict 序列化工具,并分析其设计取舍与改进方向,适合正在用 SQLAlchemy 写后端接口的你。 目标读者 这篇文章适合以下读者: 使用 SQLAlchemy 做 ORM 的后端开发者 想把 ORM 模型转换为 JSON/dict 的 Python 工程师 对 模型序列化规范化 有需求的中级开发者 使用 Flask/FastAPI/Django + SQLAlchemy 的同学 一、背景 / 动机:为什么要自己写 _to_dict? 在 Web 开发中,我们几乎每天都要做一件事: 把数据库里的 ORM 对象,转成可以 JSON 响应给前端的数据结构(通常是 dict / list)。 乍一看好像只是 obj.__dict__ 或用个 asdict 就完事,但现实中的问题包括: 日期时间字段无法直接 JSON 化: datetime / date 对象不能直接 JSON 序列化,必须格式化成字符串。 关系字段怎么处理? 一对多 / 多对多(uselist=True) 一对一 / 多对一(uselist=False) 避免递归爆炸: 两个模型互相关联,很容易序列化时陷入无限递归。 统一输出格式: 不同模型、不同接口如果各写各的 to_dict,维护成本极高。 ...

2025年11月12日 · 4 分钟 · map[name:Jeanphilo]

用Issue把问题写清楚,从0到TEMPLATE

标题(吸引且准确,包含关键词) 用 Issue 模板把需求写清楚:从 0 配置 GitHub Issue Template 的完整指南 副标题 / 摘要 这篇文章手把手教你在 GitHub 仓库中配置「新需求 / Feature」与「Bug」Issue 模板,包括目录结构、YAML 表单、Markdown 模板以及常见坑。适合想让团队需求沟通更规范、减少反复追问的开发者和团队负责人。 目标读者 这篇文章适合: 经常在 GitHub 仓库里开 Issue、提需求的 后端 / 前端 / 全栈工程师 想把团队需求提交流程「标准化」的 项目负责人 / TL / 架构师 对 GitHub 已经有基本使用经验、但还没用过 Issue 模板的 中级开发者 完全新手也能看懂,但会默认你知道:什么是仓库、什么是 Issue、如何提交代码等。 背景 / 动机:为什么要折腾 Issue 模板? 没有 Issue 模板时,日常可能是这样的: “这个需求背景是什么?” “影响哪些模块?” “验收标准怎么算通过?” “优先级到底多高?” 一句话 Issue: “做个导出功能” 直接把所有人整破防。 长期下来会有几个痛点: 沟通成本高:每个需求都要反复追问细节; 信息不对称:请求人脑子里很清楚,但写在 Issue 里的只有一句话; 难以排期:没有明确优先级和验收标准,大家都觉得自己的需求是 P0; 历史难追踪:几个月后再看这个 Issue,完全不知道当时怎么想的。 而 GitHub 提供的 Issue Template,其实就是一套「结构化提问」工具: ...

2025年11月11日 · 4 分钟 · map[name:Jeanphilo]

别让Pydantic占领你的整个项目:聊聊API校验,Domain模型和数据库之间的边界

标题 别让 Pydantic 占领你的整个项目:聊聊 API 校验、Domain 模型和数据库之间的边界 副标题 / 摘要 很多用 FastAPI/Pydantic 的 Python 工程师,会不知不觉让 Pydantic Model 贯穿 API、业务、数据库所有层。本文用一个清晰的分层思路和完整代码示例,帮你搞清楚:Pydantic 适合用在什么地方,Domain / ORM 又应该怎么配合。 目标读者 这篇文章适合: 正在使用 FastAPI / Pydantic / SQLAlchemy / SQLModel 的 Python 后端工程师 刚入行 0–3 年、开始关心“分层、架构、领域模型”的开发者 想从“会写接口”进阶到“懂业务建模、懂分层”的工程师 对 “Pydantic 要不要进 Domain / 要不要用于 DB 模型” 有疑惑的人 一、背景 / 动机:为什么 Pydantic 容易“长满全项目”? 如果你是从 FastAPI 入门后端,很可能经历过这样的路径: 用 Pydantic 定义请求体、响应体:太好用了,自动校验 + 文档 + 类型提示。 觉得既然 Pydantic 这么香,那干脆: 直接拿 Pydantic Model 当“业务对象”传来传去 甚至顺手拿它去做“数据库模型” 渐渐地,你的项目变成: ...

2025年11月9日 · 6 分钟 · map[name:Jeanphilo]

从写路由到写"大脑":Python工程师如何先搞定核心逻辑,再考虑API

标题 从写路由到写“大脑”:Python 工程师如何先搞定核心逻辑,再考虑 API 副标题 / 摘要 刚入行时,我们常常一上来就写路由、设计接口、想 chat_id / message_id 怎么存,却发现真正的“智力活”——核心逻辑——总是拖到后面。这篇文章带你从「先写接口」的思维,升级到「先写大脑,再接外壳」,并串起来六边形架构、Clean Architecture、DDD 等背后的经典理念。 目标读者 适合这些同学阅读: 1–3 年经验 的 Python 后端工程师 / AI 应用开发者 正在用 FastAPI / Django / Flask 等框架写 API 的工程师 想从“CRUD 搬砖工”进化为“懂设计、能抽象”的工程师 对 六边形架构 / Clean Architecture / DDD 有点好奇但没系统看过书的人 一、背景 / 动机:为什么“先写接口”会卡死自己? 很多刚入行的 Python 工程师(包括你我)会有这样的流程: 产品提一个新需求:做一个 AI 聊天功能。 打开编辑器,第一反应就是: 设计 URL:POST /api/chat/send_message 开始写 router:@app.post("/chat/send") 想 request body 参数长什么样:chat_id / message_id / user_id / content 想数据库表结构:chats,messages 写了一堆 API、schema、model、迁移脚本之后,才想起来: “那 AI 回复到底是怎么生成的?” ...

2025年11月8日 · 5 分钟 · map[name:Jeanphilo]

api标准

🧭 标题: 如何编写一份合格的 API 文档:从 Tony Tam 的 Swagger 到现代 OpenAPI 实践 ✍️ 副标题 / 摘要 想让你的 API 被开发者真正用得舒服?这篇文章将带你从理念到实践,全面掌握一份高质量 API 文档的结构、示例与最佳规范,基于 Tony Tam 提出的 Swagger / OpenAPI 标准。 🎯 目标读者 初学者:想了解 API 文档标准结构的人。 中级开发者:希望提升接口文档可维护性与规范性的人。 架构师 / 技术负责人:负责 API 设计规范制定与团队协作的人。 💡 背景 / 动机 许多开发团队的 API 文档存在以下痛点: 信息零散,缺乏统一格式; 更新滞后,开发与文档脱节; 无法直接用于自动生成或测试。 Tony Tam 于 2010 年提出的 Swagger 规范(后更名为 OpenAPI) 正是为了解决这些问题。如今,它已成为 RESTful API 文档的事实标准,被 Google、Amazon、Stripe 等公司广泛采用。 🔍 核心概念 概念 说明 API 文档 描述应用程序接口如何被调用、请求与响应的技术说明书。 Swagger / OpenAPI 一种用于定义、生成、测试 REST API 的标准化规范。 Endpoint(端点) API 中可访问的具体路径(如 /users/{id})。 Schema(数据模型) 定义请求与响应的字段结构。 🧰 实践指南 / 步骤 明确文档结构 概述(Overview) 鉴权机制(Authentication) 接口定义(Endpoints) 数据模型(Schemas) 错误码与示例(Errors & Examples) 使用 OpenAPI 规范组织文档 建议采用 YAML 格式,支持机器可读与可视化。 推荐工具链 编辑器:Swagger Editor、Stoplight Studio、VS Code + YAML 插件 文档展示:Swagger UI / ReDoc 自动生成:通过注释生成(如 Springdoc、FastAPI、NestJS) ...

2025年11月6日 · 2 分钟 · map[name:Jeanphilo]

从堵塞到异步:为什么上传文件接口不该等文件处理完

🚀 从阻塞到异步:为什么上传接口不该等文件处理完? —— 用异步任务和状态跟踪构建高性能文件处理系统 🧭 副标题 / 摘要 在现代 Web 系统中,文件上传只是起点,真正的挑战在于后续的解析、索引和处理。本文带你理解为什么“上传接口不等待处理完成”是现代架构的核心理念,以及如何通过异步任务 + 状态查询实现稳定、可扩展的后台处理系统。 👥 目标读者 有一定 Web 开发经验的工程师(Python/FastAPI/Node.js 等) 想优化后端性能、提高可扩展性的中级开发者 对架构设计、异步系统感兴趣的工程师或技术负责人 🎯 背景 / 动机 很多初学者写上传接口时会这样做: @app.post("/upload") def upload_file(file: UploadFile): parse_and_store(file) # 阻塞操作 return {"status": "completed"} 表面简单,实则隐藏问题: ⏱ 超时风险高(解析/embedding/OCR可能几分钟) 🧵 阻塞主线程,拖慢整个 API 服务 💥 请求中断即任务丢失 😕 用户只能干等着,无法看到进度 解决方案就是:上传与处理分离。上传只负责“投递任务”,处理由后台 worker 异步执行,状态存储在数据库中供前端查询。 🔍 核心概念 概念 说明 异步任务(Async Job) 文件解析、OCR、embedding 等耗时操作独立运行,不阻塞主线程。 任务队列(Task Queue) 临时存放待执行的任务,如 Redis、RabbitMQ、Celery。 状态持久化(State Persistence) 将任务状态(pending / processing / completed / failed)写入数据库。 SSE(Server-Sent Events) 一种轻量的实时推送机制,前端可实时接收状态更新。 ⚙️ 实践指南 / 实现步骤 1️⃣ 上传文件接口(只负责入队) @router.post("/upload") async def upload(file: UploadFile, user=Depends(get_verified_user)): file_id = Files.create(file, user.id) # 异步提交任务(Celery、RQ、线程池等) background_tasks.add_task(process_file, file_id) return {"file_id": file_id, "status": "pending"} 2️⃣ 异步任务(后台 worker 执行) def process_file(file_id: str): file = Files.get(file_id) Files.update_status(file_id, "processing") try: parse_and_vectorize(file) Files.update_status(file_id, "completed") except Exception as e: Files.update_status(file_id, "failed", error=str(e)) 3️⃣ 状态查询接口 @router.get("/{id}/process/status") async def get_status(id: str, stream: bool = False): file = Files.get(id) if stream: async def event_stream(): while True: status = Files.get_status(id) yield f"data: {json.dumps({'status': status})}\n\n" if status in ("completed", "failed"): break await asyncio.sleep(1) return StreamingResponse(event_stream(), media_type="text/event-stream") return {"status": file.data.get("status", "pending")} 💻 可运行示例 前端轮询: async function checkStatus(fileId) { let status = 'pending'; while (status === 'pending' || status === 'processing') { const res = await fetch(`/api/files/${fileId}/process/status`); const data = await res.json(); status = data.status; console.log("当前状态:", status); await new Promise(r => setTimeout(r, 1000)); } if (status === 'completed') alert("解析完成!"); } 前端 SSE 实时监听: const evtSource = new EventSource(`/api/files/${fileId}/process/status?stream=true`); evtSource.onmessage = (e) => { const { status } = JSON.parse(e.data); console.log("文件状态:", status); if (status === "completed") evtSource.close(); }; 🧠 原理解释与取舍 模式 特点 适用场景 同步上传+处理 实现简单,但阻塞主线程 小文件、低并发、离线脚本 异步上传+状态查询(推荐) 非阻塞、可恢复、可扩展 Web 应用、后台任务 消息队列驱动 支持分布式任务、重试机制 大规模系统、微服务架构 取舍原则: ...

2025年11月2日 · 2 分钟 · map[name:Jeanphilo]