当前位置: 首页 > news >正文

逆向工程 之 随机颜色生成器代码解析与重构

1. 项目来源与简介

本项目来源于GitHub开源仓库:github wanghao221/moyu/。
该项目是一个纯前端的的单页面应用,可以随机生成一个十六进制颜色值,并在页面中进行预览和一键复制,整体结构较为简单,代码量轻薄,适宜进行逆向工程探索。

  • 核心功能:点击按钮随机生成颜色,支持一键复制颜色代码
  • 技术栈:纯原生HTML5+CSS3+Vanilla+JavaScript,无任何框架依赖。
  • 文件结构:单一HTML文件,CSS与JS嵌入
  • 设计风格:主要颜色生成器卡片居中,底部背景图映衬

2. 运行环境及截图

运行环境
  • 操作系统:任意
  • 运行方式:浏览器直接打开.html文件
  • 测试浏览器:任意
  • 网络依赖:Google Fonts字体(可离线替换)+背景图(Haiyong.site)
源代码运行结果

image
如上图所示,浏览器打开运行文件,点击按钮Generate跳动展示随机生成的颜色于正中间卡片,点击Copy选项没有任何反应

展开查看核心实现代码
		let hexString = "0123456789abcdef";let genHexCode = () => {let hexCode = "#";for (i = 0; i < 6; i++) {hexCode += hexString[Math.floor(Math.random() * hexString.length)];}output.value = hexCode;outputColor.classList.remove("show-color");setTimeout(() => {outputColor.classList.add("show-color");}, 10);outputColor.style.backgroundColor = hexCode;}
作者通过定义变量存储所有十六进制字符串,后通过箭头函数,使用多个for循环,每次循环从hexString中选择字符追加到hexCode,用于随机生成颜色。
完整源代码如下
点击查看完整源代码
<!DOCTYPE html>
<html lang="en"><!-- Design by foolishdeveloper.com --><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>海拥 | 随机颜色生成器</title><link rel="shortcut icon" href="http://haiyong.site/img/favicon.png"></head><body><link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@600&display=swap" rel="stylesheet"><!-- Stylesheet --><style media="screen">*{padding: 0;margin: 0;box-sizing: border-box;border: none;outline: none;font-family: sans-serif;
}
body{background: url("https://haiyong.site/img/bizhi/220808.png" );background-repeat: no-repeat;background-size: cover;height: 100vh;
}
.container{background-color: white;width: 310px;padding: 2.5em 1.1em;position: absolute;transform: translate(-50%,-50%);top: 50%;left: 50%;font-size: 16px;border-radius: 10px;
}
.container h1{font-size: 27px;text-align: center;margin-top: -20px;color: #09599a;margin-bottom: 20px;
}
#output-color{position: relative;height: 165px;width: 100%;box-shadow: 0 0 20px rgba(0,139,253,0.25);border: 2px solid #ffffff;margin: auto;display: grid;margin-bottom: 15px;place-items: center;
}
#output-color span{display: block;width: 100%;height: 100%;}
.show-color{animation: pop 0.8s;
}
@keyframes pop{0%{transform: scale(0);}100%{transform: scale(1);}
}input[type="text"]{width: 100%;background-color: transparent;box-shadow: 0 0 20px rgba(0,139,253,0.65);font-size: 1.3em;padding: 0.3em 0;margin: 1em 0;border-radius: 5px;color: #000000;text-align: center;
}
input[type="text"]::-moz-selection{background: transparent;
}
input[type="text"]::selection{background: transparent;
}.btns{display: flex;margin-top: 15px;justify-content: space-around;
}
.btns button{font-size: 1.03em;padding: 0.8em 1.7em;border-radius: 7px;width: 120px;font-weight: 600;cursor: pointer;
}
#gen-btn{background-color: #205e94;color: #ffffff;
}
#copy-btn{background-color: #d23332;color: #ffffff;
}
.page-footer {position: fixed;right: 35px;bottom: 20px;display: flex;align-items: center;padding: 5px;color: black;background: rgba(255, 255, 255, 0.65);
}.page-footer a {display: flex;margin-left: 4px;
}
.touxiang{bottom: 0px;width:30px;height:30px;
}</style></head><body><div class="container"><h1>Color Generator</h1><div id="output-color"><span></span></div><input type="text" id="output" readonly><div class="btns"><button id="gen-btn">Generate</button><button id="copy-btn">Copy</button></div></div><!-- Script --><script type="text/javascript">let outputColor = document.querySelector("#output-color span");let output = document.getElementById("output");let genBtn = document.getElementById("gen-btn");let copyBtn = document.getElementById("copy-btn");let hexString = "0123456789abcdef";let genHexCode = () => {let hexCode = "#";for (i = 0; i < 6; i++) {hexCode += hexString[Math.floor(Math.random() * hexString.length)];}output.value = hexCode;outputColor.classList.remove("show-color");setTimeout(() => {outputColor.classList.add("show-color");}, 10);outputColor.style.backgroundColor = hexCode;}copyBtn.addEventListener("click", () => {output.select();document.execCommand("copy");})window.onload = genHexCode;genBtn.addEventListener("click", genHexCode);</script><footer class="page-footer"><span>made by  </span><a href="https://haiyong.site/moyu" target="_blank"><img class="touxiang"  src="https://haiyong.site/img/favicon.png" alt="George Martsoukos logo"></a></footer></body>
</html>

3. 主要问题与改善思路

  • Bug/规范:源代码循环变量未声明,在小工程上或许影响不大,在大工程中可能会导致全局变量污染。采用位运算+padStart的算法替代字符串拼接循环,可以解决该问题。
点击查看源代码
let hexString = "0123456789abcdef";
let genHexCode = () => {let hexCode = "#";for (i = 0; i < 6; i++) {hexCode += hexString[Math.floor(Math.random() * hexString.length)];}output.value = hexCode;outputColor.classList.remove("show-color");setTimeout(() => {outputColor.classList.add("show-color");}, 10);outputColor.style.backgroundColor = hexCode;}
点击查看改进后代码
function generateColor() {const hex = '#' +Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, '0').toUpperCase();colorSpan.style.backgroundColor= hex;output.value = hex;
}
  • 用户体验:原始版本复制后页面没有任何变化,用户无法确认是否复制成功,体验较差。可以新增提示元素,复制成功后短暂显示已复制成功。
点击查看源代码
copyBtn.addEventListener("click", () => {output.select();document.execCommand("copy");}
点击查看改进后代码
#toast {text-align: center;font-size: 13px;color: #16a085;height: 20px;opacity: 0;transition: opacity 0.3s ease;}
<div id="toast"></div>
function showToast(msg) {toast.textContent = msg;toast.style.opacity = '1';setTimeout(() => {toast.style.opacity = '0';}, 2000);
}
  • 可读性:原始颜色生成代码采用随机字符拼接,逻辑分散,可读性较差,不易理解。利用 Math.random() * 0xFFFFFF 直接生成随机整数,再转十六进制,配合 padStart 补位,3行完成相同功能,语义更清晰。
点击查看源代码
let hexString ="0123456789abcdef";
let genHexCode = () => {let hexCode = "#";for (i = 0; i < 6; i++) {hexCode += hexString[Math.floor(Math.random()* hexString.length)];}
点击查看改进后代码
function generateColor() {const hex = '#' +Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, '0').toUpperCase();
}
  • 可靠性:背景图依赖个人管理器,一旦域名失效或网络不通将背景消失,变为白色。改用纯 CSS 渐变背景,色块过渡改用 transition,全程无外部依赖。值得说明的是,这样改进后视觉效果并不如原来,但作为软件工程逆向改进,为维护可靠,这似乎也可作为一个点。。。。。
点击查看源代码
body {background: url("https://haiyong.site/img/...bizhi/220808.png");background-repeat: no-repeat;background-size: cover;height: 100vh;
}
/* 动画:remove + setTimeout */
.show-color {animation: pop 0.8s;
}
@keyframes pop {0%   { transform: scale(0); }100% { transform: scale(1); }
}
点击查看改进后代码
/* CSS:纯渐变背景,无外部依赖 */
body {background: linear-gradient(135deg,#1a1a2e 0%,#16213e 50%,#0f3460 100%);min-height: 100vh;
}
/* 色块:用 transition 替代 animation */
#color-span {transition: background-color0.5s ease;
}
  • 功能增强:原始版本只显示HEX的颜色码,虽说作为一个摸鱼小游戏此功能已足够,但若设计师在玩耍设计工具中有时会需要RGB值,需要手动换算,不够便捷。可以增加 HEX → RGB 转换函数,在 UI 新增 R/G/B 分量展示区,与颜色生成同步更新。
点击查看代码
/* HTML:只有一个 input 显示 HEX */
<input type="text"id="output" readonly>
// JS:只赋值 HEX
output.value = hexCode;
点击查看改进后代码

<div class="color-values"><div><span>R</span><span id="r-val"></span></div><div><span>G</span><span id="g-val"></span></div><div><span>B</span><span id="b-val"></span></div>
</div>const r = parseInt(hex.slice(1,3),16);
const g = parseInt(hex.slice(3,5),16);
const b = parseInt(hex.slice(5,7),16);
rVal.textContent = r;
gVal.textContent = g;
bVal.textContent = b;

4. 新代码(改进版)

点击查看改进后完整代码
<!DOCTYPE html>
<html lang="en"><!-- Design by foolishdeveloper.com --><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>海拥 | 随机颜色生成器</title><link rel="shortcut icon" href="http://haiyong.site/img/favicon.png"><link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@600&display=swap" rel="stylesheet"></head><body><style media="screen">* {padding: 0;margin: 0;box-sizing: border-box;border: none;outline: none;font-family: sans-serif;}body {background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);background-repeat: no-repeat;background-size: cover;height: 100vh;}.container {background-color: white;width: 310px;padding: 2.5em 1.1em;position: absolute;transform: translate(-50%, -50%);top: 50%;left: 50%;font-size: 16px;border-radius: 10px;}.container h1 {font-size: 27px;text-align: center;margin-top: -20px;color: #09599a;margin-bottom: 20px;}#output-color {position: relative;height: 165px;width: 100%;box-shadow: 0 0 20px rgba(0, 139, 253, 0.25);border: 2px solid #ffffff;margin: auto;display: grid;margin-bottom: 15px;place-items: center;}#output-color span {display: block;width: 100%;height: 100%;transition: background-color 0.5s ease;}input[type="text"] {width: 100%;background-color: transparent;box-shadow: 0 0 20px rgba(0, 139, 253, 0.65);font-size: 1.3em;padding: 0.3em 0;margin: 1em 0 0.5em;border-radius: 5px;color: #000000;text-align: center;}input[type="text"]::-moz-selection { background: transparent; }input[type="text"]::selection { background: transparent; }.color-values {display: flex;justify-content: space-between;gap: 6px;margin-bottom: 10px;}.color-value-box {flex: 1;background: #f4f4f4;border-radius: 5px;text-align: center;padding: 5px 2px;}.color-value-box .label {display: block;font-size: 10px;color: #999;letter-spacing: 1px;margin-bottom: 2px;}.color-value-box .val {font-family: 'Roboto Mono', monospace;font-size: 13px;font-weight: 600;color: #333;}#toast {text-align: center;font-size: 12px;color: #16a085;font-weight: 600;height: 18px;margin-bottom: 6px;opacity: 0;transition: opacity 0.3s ease;font-family: 'Roboto Mono', monospace;}.btns {display: flex;margin-top: 15px;justify-content: space-around;}.btns button {font-size: 1.03em;padding: 0.8em 1.7em;border-radius: 7px;width: 120px;font-weight: 600;cursor: pointer;}#gen-btn  { background-color: #205e94; color: #ffffff; }#copy-btn { background-color: #d23332; color: #ffffff; }.page-footer {position: fixed;right: 35px;bottom: 20px;display: flex;align-items: center;padding: 5px;color: black;background: rgba(255, 255, 255, 0.65);}.page-footer a {display: flex;margin-left: 4px;}.touxiang {bottom: 0px;width: 30px;height: 30px;}</style><div class="container"><h1>Color Generator</h1><div id="output-color"><span></span></div><input type="text" id="output" readonly><div class="color-values"><div class="color-value-box"><span class="label">R</span><span class="val" id="r-val">—</span></div><div class="color-value-box"><span class="label">G</span><span class="val" id="g-val">—</span></div><div class="color-value-box"><span class="label">B</span><span class="val" id="b-val">—</span></div></div><div id="toast"></div><div class="btns"><button id="gen-btn">Generate</button><button id="copy-btn">Copy</button></div></div><script type="text/javascript">let outputColor = document.querySelector("#output-color span");let output      = document.getElementById("output");let genBtn      = document.getElementById("gen-btn");let copyBtn     = document.getElementById("copy-btn");let toast       = document.getElementById("toast");let rVal        = document.getElementById("r-val");let gVal        = document.getElementById("g-val");let bVal        = document.getElementById("b-val");let genHexCode = () => {let hexCode = "#" + Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, "0").toUpperCase();output.value = hexCode;outputColor.style.backgroundColor = hexCode;let r = parseInt(hexCode.slice(1, 3), 16);let g = parseInt(hexCode.slice(3, 5), 16);let b = parseInt(hexCode.slice(5, 7), 16);rVal.textContent = r;gVal.textContent = g;bVal.textContent = b;}copyBtn.addEventListener("click", () => {output.select();document.execCommand("copy");showToast("✓ 已复制 " + output.value);});function showToast(msg) {toast.textContent = msg;toast.style.opacity = "1";setTimeout(() => { toast.style.opacity = "0"; }, 2000);}window.onload = genHexCode;genBtn.addEventListener("click", genHexCode);</script><footer class="page-footer"><span>made by </span><a href="https://haiyong.site/moyu" target="_blank"><img class="touxiang" src="https://haiyong.site/img/favicon.png" alt="George Martsoukos logo"></a></footer></body>
</html>

5. 重构后测试

如下图所示重构后的颜色随机生成器,在点击copy后会有短暂友好提示,并且有颜色提示,可供设计者便携使用,不再依赖个人管理器,背景图片被改掉。但值得强调,此次改进后结果带来的视觉冲击力远不如原版本好,此处改动需斟酌选取。
屏幕截图 12026-03-05 191152
屏幕截图2 2026-03-05 191413

6. 总结与思考

  • 关于逆向软件工程:所谓逆向软件工程并非一味复制代码,魔改代码,而是在接手新代码后理解设计意图,读懂代码,发现潜在问题,用更好的方式进行改进。
    而本次改变,对于背景图的换掉,作为一个摸鱼小游戏完全失去其本有的观赏性,有违设计意图。其余改动,尚且可以,符合逆向软件工程特点。
  • 关于项目改进难点:在何角度进行有效改动为本项目的难点,也花费时间较长,需仔细阅读理解代码,在可读性、可靠性、可维护性、用户友好性、功能增强等等方面进行考虑,可有效找到优化点,可进一步扩展总结。
  • 关于项目的选择:本项目是作者为数不多的在github上扒代码,从寻找到下载一步步,索性作为单一前端展示页面运行复现优化较为简单,不涉及大量环境问题,且项目较小,较为满意。
http://www.jsqmd.com/news/440280/

相关文章:

  • Flutter 三方库 zard 的鸿蒙化适配指南 - 掌控文本预处理增强、高性能分词实战、鸿蒙级多维语义专家
  • 2026年 健身阻力带厂家推荐排行榜:橡胶/8型/织物/套装全品类深度解析,助力科学塑形与家庭健身! - 品牌企业推荐师(官方)
  • 2026年 拉力带厂家推荐排行榜,弹性拉力带,练背拉伸带,11件套拉力带,专业健身训练带品牌深度解析 - 品牌企业推荐师(官方)
  • 【2026实测】植物大战僵尸融合版下载安装全攻略:电脑版/手机版一键安装(附资源包) - xiema
  • 2026年北京小程序开发公司深度测评:如何甄选高匹配度的定制化服务商 - 品牌2026
  • 2026年靠谱的矿用平板车工厂推荐:有轨平板车优质供应商推荐 - 品牌宣传支持者
  • 北京小程序定制开发服务商如何甄选?聚焦技术扎实与场景适配的本地团队 - 品牌2026
  • 2026年热门的旋耕机折叠款工厂推荐:水田打浆旋耕机/旋耕机加大齿轮箱款直销厂家选哪家 - 品牌宣传支持者
  • 2026适合送同事的新年零食礼盒:《旺旺大礼包》种类多性价比高的零食大礼包超值装 - Top品牌推荐官
  • 免费数据库管理工具深度横评:NineData 社区版、Bytebase 社区版、Archery,2026 年开发者该选哪个?
  • 2026年北京小程序开发公司甄选:深度解析定制化服务与行业落地能力 - 品牌2026
  • 北京小程序开发公司怎么选?聚焦定制化与行业适配能力的优质服务商 - 品牌2026
  • AI文档翻译在各个行业的应用
  • Pandas数据处理(2): 重复行处理、数据类型转换与数据变形
  • 免责声明
  • 2026年比较好的农业打浆机公司推荐:灭茬打浆机/打浆机高箱款/打浆机折叠款高口碑品牌推荐 - 品牌宣传支持者
  • 2026年 拉力器厂家推荐排行榜,11件套拉力器,拉力圈,健身器材专业制造商实力解析与选购指南 - 品牌企业推荐师(官方)
  • 火焰之下的真相:水平垂直燃烧仪选型与品牌深度透视 - 品牌推荐大师
  • GIF 想要转为视频怎么办?GIF 转为哪种视频格式好?
  • Aluminium OS 将于 2026 年底推出,安卓与 Chrome OS 正式融合
  • 2026 最新:小红书视频去水印下载教程
  • 2026年比较好的真空吸盘工厂推荐:耐磨吸盘/耐高温吸盘/气动真空吸盘厂家推荐哪家好 - 品牌宣传支持者
  • 【开题答辩全过程】以 海经院学生外出演出管理系统的设计与实现为例,包含答辩的问题和答案
  • 2026年净化板厂家实力推荐榜:手工/机制/岩棉/玻镁岩棉净化板,精选优质品牌与创新工艺深度解析 - 品牌企业推荐师(官方)
  • 2026年知名的不锈钢屏风公司推荐:不锈钢烤漆/不锈钢拖把池专业制造厂家推荐 - 品牌宣传支持者
  • Transformer相关面试题
  • Java 创建对象的 6 种方式 + 底层原理(面试必考)
  • Browser-Use在UI自动化测试中的应用
  • 2026年口碑好的异型铰链公司推荐:90度异型铰链/橱柜异型铰链/165度异型铰链品牌厂家哪家靠谱 - 品牌宣传支持者
  • 英语复试准备