普通视图

发现新文章,点击刷新页面。
今天 — 2025年7月3日首页

前端多层加密?让“伪安全”更“伪”一点(狗头)

2025年7月3日 08:38

在浏览器端做加密,听上去就有点自欺欺人。很多开发者对前端加密的态度是:

“反正浏览器都能看到源码,前端加密有意义吗?”

实际上,这个问题的答案并不简单。前端加密无法抗拒主动攻击,但在某些场景下,比如数据混淆、防小白逆向、教学演示,它仍然具备合理存在的价值。

本篇:想聊的,就是一种典型的“前端多层加密”的实现思路。

我做了一个网站,大家可以简单体验一下:encryption-demo.pages.dev/

image.png

多层加密的核心设计

前端多层加密本质上是将多个简单的加密/编码/哈希算法串联起来,形成一个相对复杂的处理链,从而提升对抗简单逆向的门槛。

image.png

  • 字符位移:基础可逆加密

  • 加盐:防止简单模式识别

  • Base64:编码增强,便于传输

  • 哈希迭代:引入不可逆过程,增加验证机制

  • 二次字符位移+编码:强化混淆效果

原理与实现

🔸 步骤1:字符位移加密

  • 类似凯撒密码,每个字母 +3
  • 极易破解,但适合作为第一步混淆
function simpleEncrypt(str) {
  return str.split('').map(c => {
    const code = c.charCodeAt(0);
    if (code >= 65 && code <= 90) {
      return String.fromCharCode(((code - 65 + 3) % 26) + 65);
    }
    if (code >= 97 && code <= 122) {
      return String.fromCharCode(((code - 97 + 3) % 26) + 97);
    }
    return c;
  }).join('');
}

🔸 步骤2:加盐

  • 在末尾增加一串随机盐(一般8位)
  • 盐 = 防止模式识别 + 防止撞库
function generateSalt(length = 8) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  return Array.from({length}).map(() => chars[Math.floor(Math.random() * chars.length)]).join('');
}

🔸 步骤3:Base64编码

  • 本质是编码,不是加密
  • 提供可见的编码形式,防止二进制乱码
const encoded = btoa(textWithSalt);

🔸 步骤4:再次字符位移

  • 加强混淆
  • 和第一次字符位移逻辑相同

🔸 步骤5:100次哈希迭代

  • 不可逆
  • 增加校验强度
  • 理论上,攻击者必须知道前面所有步骤,并暴力跑哈希
function customHash(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = (hash << 5) - hash + str.charCodeAt(i);
    hash |= 0;
  }
  return hash.toString(16);
}
let result = input;
for (let i = 0; i < 100; i++) {
  result = customHash(result);
}

🔸 步骤6:最终Base64编码

  • 便于展示和传输
  • 增强文本兼容性

到底安全吗?

目标 多层加密能否达成?
防止数据被直接肉眼看到 ✅ 完全达成
防止抓包获取原始数据 ❌ 无法防御
防止逆向还原加密逻辑 ❌ 无法防御
增加小白逆向的时间成本 ✅ 有效
商业级数据安全保护 ❌ 完全不适用
教学/实验/流程展示 ✅ 非常合适

结论一句话:

这是一种“伪加密”...

尽管这种多层加密“不安全”,但它的流程化设计非常适合: 一步步拆解加密过程 —— 从字符到编码到哈希,看到每一步如何变化 —— 练习如何组合多个算法。

前端加密 ≠ 信息安全,但 ≠ 完全没用。

OK,以上便是本次分享~

欢迎加我:atar24,进技术群、交盆友,我会第一时间通过

昨天以前首页

命令行的进化:CMD、PowerShell 和 Bash

2025年6月26日 10:19

引子

在图形界面横行的今天,命令行看起来就像上个世纪的老古董。但真相是——每一行命令背后,藏着整个操作系统的灵魂。

无论是 Windows 上的 CMD,Linux/macOS 上的 Bash,还是微软后来力推的 PowerShell,它们不仅是开发者的得力助手,更是技术演进的缩影。每个命令、每个符号,都是一代工程师试图解决某个痛点的答案。

本篇,就让我们沿着命令行的时间轴,看看它如何从上世纪的字符终端,一步步走到云计算和 AI 驱动的今天。

🎯 演进时间线一图流

1981 ──────── 1989 ──────── 2006 ──────── 2016 ──────── 2025  
                                                      
├─ CMD (MS-DOS)                                         
             ├─ Bash 0.99               ├─ WSL 1.0      
                          ├─ PS 1.0     ├─ PS 6.0 (跨平台)  
                                       ├─ Bash on Windows  
                          AI + CLI 融合(Copilot时代)

一、诞生的背后:它们到底在解决什么问题?

CMD:MS-DOS 留下的“历史债务”

CMD 诞生的使命其实很朴素——兼容老软件,别让几十年前的脚本白写了。

1981 年,MS-DOS 面世,command.com 成为当时的默认命令行。后来进入 Windows 时代,cmd.exe 接过了接力棒。虽然功能有限,但它承担了“兼容老脚本”“帮 Windows 用户跑批处理”的重要角色。

一句话总结:CMD 不是为了创新,而是为了不让旧时代崩溃。


PowerShell:Windows 自动化的自我救赎

到了 2000 年代,Windows 运维界一片混乱:

  • CMD,功能太弱。
  • VBScript,写的人抓狂,看的人更崩溃。
  • 图形界面点点点,根本没法自动化。

于是,微软的 Jeffrey Snover 提出了一个惊世骇俗的想法:为什么命令行不能直接操作对象?

这就是后来 PowerShell 的核心思想——对象管道。命令不再传递一堆字符串,而是传递带属性、带方法的对象。你可以直接对文件、进程、服务下手,无需靠什么 awkgrep 拼命切字符串。

比如你想查看 nginx 进程的内存占用,只能先拿到一堆文本,再自己想办法提取出有用的字段。

ps aux | grep nginx | awk '{print $4}'

这段命令做了什么?

  • ps aux → 列出所有进程(输出一大坨文本)
  • grep nginx → 从文本中过滤出包含 nginx 的行
  • awk '{print $4}' → 拿到第四列(通常是内存占用)

但这里有个致命问题:一旦输出格式变了,这个命令就废了。

比如不同的 Linux 发行版、不同版本的 ps 命令,字段位置可能变,空格数量可能变,甚至列标题变长都会导致 awk '{print $4}' 报错或者结果错位。

而 PowerShell 传递的不是文本,而是 .NET 对象。每个对象都有属性,结构化、标准化,不再依赖格式推测。

对应的 PowerShell 写法:

Get-Process nginx | Select-Object -ExpandProperty CPU

解释一下:

  • Get-Process nginx → 返回的是一个 进程对象列表,每个对象都包含标准字段,比如 CPU、Memory、ProcessName 等。

  • Select-Object -ExpandProperty CPU → 直接提取这个对象的 CPU 使用率。

  • 没有文本解析,没有位置依赖、没有空格错位的问题

  • 哪怕操作的是一台 Windows、本地 Linux,还是云端容器,对象结构是统一的

  • 可以链式继续操作:

    Get-Process nginx | Where-Object { $_.CPU -gt 80 } | Stop-Process
    

Bash:开源世界的“共同语言”

Bash 的出现其实更像一场“自由之战”。

1988 年,GNU 项目需要一个开源的 Shell,来取代当时专有的 Bourne Shell。于是,Brian Fox 写下了 Bash(Bourne-Again Shell)。

它不仅保留了 Unix 世界的命令行传统,还不断加入诸如命令补全、作业管理、数组、函数等高级功能。Bash 逐渐成了 Linux 开发者的母语,也成了开源生态的命脉之一。


二、技术进化:谁在原地踏步,谁在狂飙?

CMD:稳如老狗,也老得发霉

  • 功能?能跑就行。
  • 创新?别想了。
  • 它的存在感,更多是“我不主动退役,你也没法彻底抛弃”。

PowerShell:从 Windows 到全世界

版本 年份 大事件
1.0 2006 初代发布,终于告别 VBScript
3.0 2012 支持模块自动加载,舒服多了
5.0 2015 加入类定义,开始支持 OOP
6.0+ 2018 跨平台,跑到 Linux 和 macOS 上

当微软宣布 PowerShell 开源、支持 Linux/macOS 时,很多人都知道,这已经不仅仅是 Windows 的工具,而是云时代的自动化中枢


Bash:从服务器跑进了 Windows

Bash 的强大来自社区,30 多年来,它不断进化:

  • 支持函数、数组、正则。
  • 有 Zsh、Fish 这样的兄弟竞品,但它依然是脚本领域的事实标准
  • 更牛的是,2016 年,微软通过 WSL(Windows Subsystem for Linux)让 Bash 正式进驻 Windows。开发者终于不用在 Windows 和 Linux 之间反复横跳了。

三、核心哲学:文本 vs 对象

管道的本质区别

  • Bash/CMD:传递的是“文本” 。所以你经常看到这样:

    ps aux | grep nginx | awk '{print $4}'
    

    ——输出是字符串,后续处理全靠你自己解析。

  • PowerShell:传递的是“对象” 。直接操作属性,省事又优雅:

    Get-Process nginx | Select-Object -ExpandProperty CPU
    

脚本能力对比

CMD Bash PowerShell
易用性 简单但功能弱 易上手,符号多稍绕 上手陡,功能极强
安全性 基本没 靠文件权限 有执行策略保护
扩展性 没有 社区脚本库丰富 模块化 + 面向对象
跨平台 Windows 独有 Linux/macOS/WSL Windows + Linux + Mac

四、今天的命令行,早就不是单打独斗

  • CMD:老系统的守门人,跑跑批处理,救急。
  • Bash:开发者的万能胶,从服务器到 CI/CD,无所不在。
  • PowerShell:企业级 DevOps 自动化的主力军,尤其在 Azure 和多云管理场景下一骑绝尘。

五、未来趋势:命令行不会死,反而更猛

  • Bash:依旧坚挺,特别是在云原生、容器编排(Kubernetes)里,它就是 glue code(胶水)。

  • PowerShell:越来越像 DevOps 世界的瑞士军刀,支持混合云、本地集群,甚至 AI Copilot 正在学会帮你写 PowerShell 脚本。

  • AI + CLI:未来的命令行,可能不仅是命令,更是自然语言驱动的半自动脚本。比如——

    “帮我查一下 A 集群 CPU 用量,把高于 80% 的节点拉出来重启。”
    ——Copilot 自动转成 PowerShell 或 Bash 脚本。


结语:命令行,从未过时

  • CMD,活在兼容性里
  • Bash,活在开源生态里
  • PowerShell,活在云端自动化里

命令行不是老掉牙的工具,而是这个数字世界里最简洁、最高效、最具创造力的接口之一。

技术的演化,从不是消灭谁,而是融合谁。


🚀 关于 Dev Odyssey

「Dev Odyssey」是一张为开发者绘制的成长航海图。
从计算机底层,到前沿技术;从系统思维,到智能时代。路线图、时间轴、技能矩阵,都是你穿越迷雾的指南针。

🌐 在线体验:dev-odyssey.pages.dev
💻 项目开源:github.com/tuaran/dev-…

愿每一个热爱技术的灵魂,都能在属于自己的奥赛德之旅中,驶向星辰大海。

AI 生成的 requirements.txt 害我部署搞了一上午。。

2025年6月27日 11:55

别盲目相信 AI 给你生成的 requirements.txt 。 它看起来像是帮你总结好了所有依赖,实际上准确率堪忧,经常会出现版本对不上、根本不存在的库,或者和你的 Python 版本完全不兼容。亲身实测,这玩意充其量是一个参考,而不是可以直接用在生产环境的配置文件。这是踩过坑之后换来的血的经验。

📜 前情提要

今天原本只是一次简单的部署更新,没想到硬生生搞成了一次完整的实战修炼。

项目是一个前后端分离的智能稽核平台,前端基于 Vue3,后端是 Python Flask + OpenAI API。目标很简单:把本地开发好的代码部署到服务器上,让前端能正常调用后端 API。

听起来是不是很简单?对,听起来。

🚑 第一波崩溃:API 全线扑街,但图片能访问

部署完成,前端一打开页面,所有的 API 请求直接扑街:

500 Internal Server Error

但是,很诡异——访问后端的图片是正常的。

这一下直接说明了一个事实:

  • ✅ 静态文件服务正常(Flask 的 static/ 文件夹在工作)。
  • ❌ 动态 API 全部挂掉(/api/*、/send_email、/parse_excel、/ask_to_json 全报500)。

我瞬间明白,这绝对不是端口、防火墙或者前后端没连通的问题。因为图片是从后端接口直接返回的,说明网络是通的、Nginx(如果有的话)是通的,CORS 也是通的。

🔥 问题的本质一定在 Flask 的动态路由服务启动失败

🕳️ 第二波深坑:Python 版本地狱

原来服务器默认 Python 是 3.7.9。

我看着 requirements.txt 里的 Flask==2.3.3,瞬间明白了。

✅ Flask 2.2 开始,最低支持 Python 3.8。 —— 这个是 AI 自动生成的,它也想不到,还有低于 3.8 的环境的吧??

直接装不上,pip 一顿狂报错:

ERROR: No matching distribution found for Flask==2.3.3

💡 行吧,Python 升级走起。

🔥 第三波对抗:pip 和路径的迷宫

Python 3.10 装完了,结果 pip 还默认指向老的 Python 3.7。

查 pip 路径,试图软链接、换源、改 PATH,所有能想到的招都上了。

不是权限问题,就是 pip 和 python 对不上,装的库永远在“平行世界”。

一度开始怀疑人生: “为什么 pip install 明明显示成功,python 一运行还在报 ModuleNotFoundError?”

🧠 第四波顿悟:虚拟环境才是真理

彻底放弃全局安装,直接项目内建一个 venv:

python3.10 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

结果——openai 又报错。

原因?AI帮我生成的 requirements.txt 里写着:

openai==0.2.3

什么鬼?直接 pip 官方都搜不到。

💥 瞬间明白:AI生成的requirements.txt 纯粹是“编的”,根本没测试过版本兼容。

🔧 第五波修正:全手动修复依赖

彻底不信 requirements.txt 了,直接上最原始的办法:

1️⃣ 本地跑得好的环境,pip freeze 导出:

pip freeze > requirements.txt

2️⃣ 上传到服务器,重新安装:

pip install -r requirements.txt

openai、flask、pandas、gunicorn,一个一个确认版本。

✅ 第六波成功:见证重启

杀掉占用的5000端口:

kill -9 $(lsof -t -i :5000)

启动服务:

source venv/bin/activate
gunicorn app:app -b 0.0.0.0:5000

前端刷新页面——所有API正常返回!

✅ 三个小时的地狱,终于走到了出口。

🚀 成长的瞬间

这次部署,带给我的绝不仅仅是“跑通了”这么简单。

✅ 深刻理解了 Python 多版本管理的地狱
✅ 明白了 requirements.txt 永远只是个历史快照,别全信
✅ 再也不手动改 PATH,虚拟环境永远是最优解
✅ openai 这种库更新太快,AI生成的依赖版本根本靠不住

最重要的是,彻底习得一条原则:

“部署,永远不是点击 run 那么简单。”

🏗️ 最后,附上部署代码,作为教训

cd py
source venv/bin/activate

# 杀掉5000端口
PID=$(lsof -t -i :5000)
if [ "$PID" ]; then
  kill -9 $PID
fi

# 启动
nohup gunicorn app:app -b 0.0.0.0:5000 > server.log 2>&1 &

后端启动完成 ✅

❌
❌