From a2deb501fa1777d0cdb4e442303668d93c923cb3 Mon Sep 17 00:00:00 2001 From: cmliu Date: Wed, 4 Dec 2024 03:08:49 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=20=E8=BD=BB=E9=87=8F?= =?UTF-8?q?=E5=8C=96=20sha224=20=E5=87=BD=E6=95=B0=EF=BC=8C=E5=A4=A7?= =?UTF-8?q?=E5=B9=85=E6=8F=90=E9=AB=98=E4=BB=A3=E7=A0=81=E6=95=88=E7=8E=87?= =?UTF-8?q?;=20=E6=9B=B4=E5=A4=9A=E6=94=B9=E8=BF=9B=E8=87=AA=E8=A1=8C?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=20=E6=B3=A8=E6=84=8F=E4=BA=8B=E9=A1=B9=20?= =?UTF-8?q?=E5=92=8C=20=E5=AE=9E=E7=94=A8=E6=8A=80=E5=B7=A7;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 57 +++- _worker.js | 776 ++++++++++++++--------------------------------------- 2 files changed, 241 insertions(+), 592 deletions(-) diff --git a/README.md b/README.md index 9fbca71a..c042dfef 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ - 通过提交虚假的节点配置给订阅服务,避免节点配置信息泄露。 - 另外,您也可以选择自行部署 [WorkerVless2sub 订阅生成服务](https://github.com/cmliu/WorkerVless2sub),这样既可以利用订阅生成器的便利。 +# 如何使用? ## Workers 部署方法 [视频教程](https://www.youtube.com/watch?v=MBlAqYajVSY&t=169s)
@@ -81,7 +82,6 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ - 在 CF Pages 控制台中选择 `上传资产`后,为你的项目取名后点击 `创建项目`,然后上传你下载好的 [main.zip](https://github.com/cmliu/epeius/archive/refs/heads/main.zip) 文件后点击 `部署站点`。 - 部署完成后点击 `继续处理站点` 后,选择 `设置` > `环境变量` > **制作**为生产环境定义变量 > `添加变量`。 变量名称填写**PASSWORD**,值则为你的密码,后点击 `保存`即可。 - - **重中之重! `设置` > `运行时` > `兼容性标志` > `nodejs_compat`**,后点击 `保存`即可。 - 返回 `部署` 选项卡,在右下角点击 `创建新部署` 后,重新上传 [main.zip](https://github.com/cmliu/epeius/archive/refs/heads/main.zip) 文件后点击 `保存并部署` 即可。 2. 添加优选线路: @@ -124,7 +124,6 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ - 在 CF Pages 控制台中选择 `连接到 Git`后,选中 `epeius`项目后点击 `开始设置`。 - 在 `设置构建和部署`页面下方,选择 `环境变量(高级)`后并 `添加变量`, 变量名称填写**PASSWORD**,值则为你的密码,后点击 `保存并部署`即可。 - - **重中之重! `设置` > `运行时` > `兼容性标志` > `nodejs_compat`**,后点击 `保存`即可。 2. 添加优选线路: - 添加变量 `ADD` 本地静态的优选线路,若不带端口号 TLS默认端口为443,#号后为备注别名,例如: @@ -163,36 +162,66 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ | PROXYIP | `proxyip.fxxk.dedyn.io:443` | 备选作为访问CFCDN站点的代理节点(支持多ProxyIP, ProxyIP之间使用`,`或`换行`作间隔) | | SOCKS5 | `user:password@127.0.0.1:1080` | 优先作为访问CFCDN站点的SOCKS5代理(支持多socks5, socks5之间使用`,`或`换行`作间隔) | | GO2SOCKS5 | `blog.cmliussss.com`,`*.ip111.cn`,`*google.com` | 设置`SOCKS5`变量之后,可设置强制使用socks5访问名单(`*`可作为通配符,`换行`作多元素间隔) | -| ADD | `www.csgo.com:2087,icook.hk` | 本地优选域名/优选IP(支持多元素之间`,`或`换行`作间隔) | +| ADD | `www.csgo.com:2087`,`icook.hk` | 本地优选域名/优选IP(支持多元素之间`,`或`换行`作间隔) | | ADDAPI | [https://raw.github.../addressesapi.txt](https://raw.githubusercontent.com/cmliu/WorkerVless2sub/main/addressesapi.txt) | 不解释, 懂得都懂 | | ADDCSV | [https://raw.github.../addressescsv.csv](https://raw.githubusercontent.com/cmliu/WorkerVless2sub/main/addressescsv.csv) | 不解释, 懂得都懂 | | DLS | `8` | `ADDCSV`测速结果满足速度下限 | | TGTOKEN | `6894123456:XXXXXXXXXX0qExVsBPUhHDAbXXXXXqWXgBA` | 发送TG通知的机器人token | | TGID | `6946912345` | 接收TG通知的账户数字ID | -| SUB | `Trojan.fxxk.dedyn.io` | 优选订阅生成器地址(使用订阅器将放弃`ADD`内的本地优选订阅内容) | +| SUB | `Trojan.fxxk.dedyn.io` | 优选订阅生成器域名(使用订阅器将放弃`ADD`内的本地优选订阅内容) | | SUBAPI | `SUBAPI.fxxk.dedyn.io` | clash、singbox等 订阅转换后端 | | SUBCONFIG | [https://raw.github.../ACL4SSR_Online_Mini.ini](https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini.ini) | clash、singbox等 订阅转换配置文件 | +| SUBEMOJI | `false` | 订阅转换是否启用Emoji(默认`true`) | | SUBNAME | `epeius` | 订阅名称 | | RPROXYIP | `false` | 设为 true 即可强制获取订阅器分配的ProxyIP(需订阅器支持)| | URL302 | `https://t.me/CMLiussss` | 主页302跳转(支持多url, url之间使用`,`或`换行`作间隔, 小白别用) | | URL | `https://blog.cmliussss.com` | 主页反代伪装(支持多url, url之间使用`,`或`换行`作间隔, 乱设容易触发反诈) | | CFPORTS | `2053`,`2096`,`8443` | CF账户标准端口列表 | -**注意: 填入`SOCKS5`后将不再启用`PROXYIP`!请二选一使用!!!** +# 注意事项 -**注意: 填入`SUB`后将不再启用`ADD*`类变量生成的订阅内容!请二选一使用!!!** +### **关于`SOCKS5`与`PROXYIP`:** +- 填入`SOCKS5`后,将停用`PROXYIP`。请确保**二者选其一使用**! -## 实用小技巧 +### **关于`SUB`与`ADD*`变量:** +- 填入`SUB`后,将停用由`ADD*`类变量生成的订阅内容。请确保**二者选其一使用**! -**该项目部署的订阅可通过添加`sub`键值快速更换优选订阅生成器!** -> 例如 `https://epeius.pages.dev/auto` 是你的通用自适应订阅地址 -- 快速更换订阅器为`Trojan.fxxk.dedyn.io`的订阅地址 +### **当`SUB`和`ADD*`均为空时:** +- 脚本将自动生成基于CF随机IP的线路,每次更新订阅时会生成不同的随机IP,确保您的订阅不会失联! +# 实用技巧 +本项目提供灵活的订阅配置方案,支持通过URL参数快速自定义订阅内容。 +- 示例订阅地址: `https://epeius.pages.dev/auto` + +1. 更换**订阅生成器**的订阅地址 + + 快速切换订阅生成器至 `Trojan.fxxk.dedyn.io`: ```url https://epeius.pages.dev/auto?sub=Trojan.fxxk.dedyn.io ``` -**该项目部署的节点可通过节点PATH(路径)的方式,使用指定的`PROXYIP`或`SOCKS5`!!!** +2. 更换**PROXYIP**的订阅地址 + + 快速更换PROXYIP为 `proxyip.fxxk.dedyn.io`: + ```url + https://epeius.pages.dev/auto?proxyip=proxyip.fxxk.dedyn.io + ``` + +3. 更换**SOCKS5**的订阅地址 + + 快速设置SOCKS5代理为 `user:password@127.0.0.1:1080`: + ```url + https://epeius.pages.dev/auto?socks5=user:password@127.0.0.1:1080 + ``` + +- 通过提交多个参数快速修改的订阅地址 + + 例如同时修改**订阅生成器**和**PROXYIP**: + ```url + https://epeius.pages.dev/auto?sub=Trojan.fxxk.dedyn.io&proxyip=proxyip.fxxk.dedyn.io + ``` + +4. 该项目部署的节点可通过节点PATH(路径)的方式,使用指定的`PROXYIP`或`SOCKS5`!!!** - 指定 `PROXYIP` 案例 ```url @@ -209,7 +238,7 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ /socks5://user:password@127.0.0.1:1080 ``` -**当你的`ADDAPI`可作为`PROXYIP`时,可在`ADDAPI`变量末位添加`?proxyip=true`,即可在生成节点时使用优选IP自身作为`PROXYIP`** +5. **当你的`ADDAPI`可作为`PROXYIP`时,可在`ADDAPI`变量末位添加`?proxyip=true`,即可在生成节点时使用优选IP自身作为`PROXYIP`** - 指定 `ADDAPI` 作为 `PROXYIP` 案例 ```url https://raw.githubusercontent.com/cmliu/WorkerVless2sub/main/addressesapi.txt?proxyip=true @@ -221,7 +250,7 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ ## 已适配客户端 ### Windows - [v2rayN](https://github.com/2dust/v2rayN) - - clash.meta([FlClash](https://github.com/chen08209/FlClash),[clash-verge-rev](https://github.com/clash-verge-rev/clash-verge-rev),[Clash Nyanpasu](https://github.com/keiko233/clash-nyanpasu)) + - clash.meta([FlClash](https://github.com/chen08209/FlClash),[mihomo-party](https://github.com/mihomo-party-org/mihomo-party),[clash-verge-rev](https://github.com/clash-verge-rev/clash-verge-rev),[Clash Nyanpasu](https://github.com/keiko233/clash-nyanpasu)) ### IOS - Surge,小火箭 - sing-box([SFI](https://sing-box.sagernet.org/zh/clients/apple/)) @@ -229,7 +258,7 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ - clash.meta([ClashMetaForAndroid](https://github.com/MetaCubeX/ClashMetaForAndroid),[FlClash](https://github.com/chen08209/FlClash)) - sing-box([SFA](https://github.com/SagerNet/sing-box)) ### MacOS - - clash.meta([FlClash](https://github.com/chen08209/FlClash)) + - clash.meta([FlClash](https://github.com/chen08209/FlClash),[mihomo-party](https://github.com/mihomo-party-org/mihomo-party)) # 感谢 [ca110us](https://github.com/ca110us/epeius)、[xream](https://github.com/xream)、[3Kmfi6HP](https://github.com/6Kmfi6HP/EDtunnel)、[zizifn](https://github.com/zizifn/edgetunnel)、[emn178](https://github.com/emn178/js-sha256)、[ACL4SSR](https://github.com/ACL4SSR/ACL4SSR/tree/master/Clash/config)、[SHIJS1999](https://github.com/SHIJS1999/cloudflare-worker-vless-ip)、Alice Networks LTD、 diff --git a/_worker.js b/_worker.js index a48793f2..2d1d6432 100644 --- a/_worker.js +++ b/_worker.js @@ -1,56 +1,43 @@ -// _worker.src.js + import { connect } from "cloudflare:sockets"; let password = ''; let proxyIP = ''; -// The user name and password do not contain special characters -// Setting the address will ignore proxyIP -// Example: user:pass@host:port or host:port -let socks5Address = ''; - -let addresses = [ - //当sub为空时启用本地优选域名/优选IP,若不带端口号 TLS默认端口为443,#号后为备注别名 -]; - let sub = ''; -let subconverter = 'SUBAPI.fxxk.dedyn.io';// clash订阅转换后端,目前使用CM的订阅转换功能。自带虚假节点信息防泄露 -let subconfig = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini"; //订阅配置文件 +let subConverter = 'SUBAPI.fxxk.dedyn.io';// clash订阅转换后端,目前使用CM的订阅转换功能。自带虚假节点信息防泄露 +let subConfig = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini"; //订阅配置文件 let subProtocol = 'https'; -let RproxyIP = 'false'; +let subEmoji = 'true'; +let socks5Address = ''; +let parsedSocks5Address = {}; +let enableSocks = false; +let fakeUserID ; +let fakeHostName ; +const expire = 4102329600;//2099-12-31 +let proxyIPs ; +let socks5s; +let go2Socks5s = [ + '*ttvnw.net', + '*tapecontent.net', + '*cloudatacdn.com', + '*.loadshare.org', +]; +let addresses = []; let addressesapi = []; let addressescsv = []; let DLS = 8; - let FileName = 'epeius'; let BotToken =''; let ChatID =''; -let proxyhosts = [];//本地代理域名池 +let proxyhosts = []; let proxyhostsURL = ''; -let go2Socks5s = [ - '*ttvnw.net', - '*tapecontent.net', - '*cloudatacdn.com', - '*.loadshare.org', -]; - -let fakeUserID ; -let fakeHostName ; -let proxyIPs ; -let socks5s; +let RproxyIP = 'false'; +let httpsPorts = ["2053","2083","2087","2096","8443"]; let sha224Password ; -const expire = 4102329600;//2099-12-31 const regex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[.*\]):?(\d+)?#?(.*)?$/; - -let parsedSocks5Address = {}; -let enableSocks = false; -let httpsPorts = ["2053","2083","2087","2096","8443"]; -/*Obfuscate-cmliu*/ -/* -if (!isValidSHA224(sha224Password)) { - throw new Error('sha224Password is not valid'); -} -*/ +let proxyIPPool = []; +let path = '/?ed=2560'; export default { async fetch(request, env, ctx) { try { @@ -67,32 +54,40 @@ export default { } sha224Password = env.SHA224 || env.SHA224PASS || sha224(password); //console.log(sha224Password); - + subEmoji = env.SUBEMOJI || env.EMOJI || subEmoji; + if(subEmoji == '0') subEmoji = 'false'; const currentDate = new Date(); currentDate.setHours(0, 0, 0, 0); // 设置时间为当天 const timestamp = Math.ceil(currentDate.getTime() / 1000); const fakeUserIDMD5 = await MD5MD5(`${password}${timestamp}`); - fakeUserID = fakeUserIDMD5.slice(0, 8) + "-" + fakeUserIDMD5.slice(8, 12) + "-" + fakeUserIDMD5.slice(12, 16) + "-" + fakeUserIDMD5.slice(16, 20) + "-" + fakeUserIDMD5.slice(20); - fakeHostName = fakeUserIDMD5.slice(6, 9) + "." + fakeUserIDMD5.slice(13, 19); - //console.log(fakeUserID); // 打印fakeID + fakeUserID = [ + fakeUserIDMD5.slice(0, 8), + fakeUserIDMD5.slice(8, 12), + fakeUserIDMD5.slice(12, 16), + fakeUserIDMD5.slice(16, 20), + fakeUserIDMD5.slice(20) + ].join('-'); + + fakeHostName = `${fakeUserIDMD5.slice(6, 9)}.${fakeUserIDMD5.slice(13, 19)}`; proxyIP = env.PROXYIP || proxyIP; proxyIPs = await ADD(proxyIP); proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; + socks5Address = env.SOCKS5 || socks5Address; socks5s = await ADD(socks5Address); socks5Address = socks5s[Math.floor(Math.random() * socks5s.length)]; socks5Address = socks5Address.split('//')[1] || socks5Address; if (env.CFPORTS) httpsPorts = await ADD(env.CFPORTS); sub = env.SUB || sub; - subconverter = env.SUBAPI || subconverter; - if( subconverter.includes("http://") ){ - subconverter = subconverter.split("//")[1]; + subConverter = env.SUBAPI || subConverter; + if( subConverter.includes("http://") ){ + subConverter = subConverter.split("//")[1]; subProtocol = 'http'; } else { - subconverter = subconverter.split("//")[1] || subconverter; + subConverter = subConverter.split("//")[1] || subConverter; } - subconfig = env.SUBCONFIG || subconfig; + subConfig = env.SUBCONFIG || subConfig; if (socks5Address) { try { parsedSocks5Address = socks5AddressParser(socks5Address); @@ -120,7 +115,16 @@ export default { if (url.searchParams.has('sub') && url.searchParams.get('sub') !== '') sub = url.searchParams.get('sub'); FileName = env.SUBNAME || FileName; if (!upgradeHeader || upgradeHeader !== "websocket") { - //const url = new URL(request.url); + if (url.searchParams.has('proxyip')) { + path = `/?ed=2560&proxyip=${url.searchParams.get('proxyip')}`; + RproxyIP = 'false'; + } else if (url.searchParams.has('socks5')) { + path = `/?ed=2560&socks5=${url.searchParams.get('socks5')}`; + RproxyIP = 'false'; + } else if (url.searchParams.has('socks')) { + path = `/?ed=2560&socks5=${url.searchParams.get('socks')}`; + RproxyIP = 'false'; + } switch (url.pathname) { case '/': if (env.URL302) return Response.redirect(env.URL302, 302); @@ -172,10 +176,6 @@ export default { else return new Response('不用怀疑!你PASSWORD就是错的!!!', { status: 404 }); } } else { - proxyIP = url.searchParams.get('proxyip') || proxyIP; - if (new RegExp('/proxyip=', 'i').test(url.pathname)) proxyIP = url.pathname.toLowerCase().split('/proxyip=')[1]; - else if (new RegExp('/proxyip.', 'i').test(url.pathname)) proxyIP = `proxyip.${url.pathname.toLowerCase().split("/proxyip.")[1]}`; - socks5Address = url.searchParams.get('socks5') || socks5Address; if (new RegExp('/socks5=', 'i').test(url.pathname)) socks5Address = url.pathname.split('5=')[1]; else if (new RegExp('/socks://', 'i').test(url.pathname) || new RegExp('/socks5://', 'i').test(url.pathname)) { @@ -187,6 +187,7 @@ export default { socks5Address = `${userPassword}@${socks5Address.split('@')[1]}`; } } + if (socks5Address) { try { parsedSocks5Address = socks5AddressParser(socks5Address); @@ -200,6 +201,18 @@ export default { } else { enableSocks = false; } + + if (url.searchParams.has('proxyip')){ + proxyIP = url.searchParams.get('proxyip'); + enableSocks = false; + } else if (new RegExp('/proxyip=', 'i').test(url.pathname)) { + proxyIP = url.pathname.toLowerCase().split('/proxyip=')[1]; + enableSocks = false; + } else if (new RegExp('/proxyip.', 'i').test(url.pathname)) { + proxyIP = `proxyip.${url.pathname.toLowerCase().split("/proxyip.")[1]}`; + enableSocks = false; + } + return await trojanOverWSHandler(request); } } catch (err) { @@ -619,7 +632,7 @@ function 配置信息(密码, 域名地址) { const 传输层协议 = 'ws'; const 伪装域名 = 域名地址; - const 路径 = '/?ed=2560'; + const 路径 = path; let 传输层安全 = ['tls',true]; const SNI = 域名地址; @@ -638,6 +651,9 @@ async function getTrojanConfig(password, hostName, sub, UA, RproxyIP, _url) { if (match) { sub = match[1]; } + const subs = ADD(sub); + if (subs.length > 1) sub = subs[0]; + } else if ((addresses.length + addressesapi.length + addressescsv.length) == 0){ // 定义 Cloudflare IP 范围的 CIDR 列表 let cfips = [ @@ -765,8 +781,8 @@ FAKEPASS: ${fakeUserID} UA: ${UA} ${订阅器} -SUBAPI(订阅转换后端): ${subProtocol}://${subconverter} -SUBCONFIG(订阅转换配置文件): ${subconfig} +SUBAPI(订阅转换后端): ${subProtocol}://${subConverter} +SUBCONFIG(订阅转换配置文件): ${subConfig} --------------------------------------------------------------- ################################################################ v2ray @@ -779,7 +795,7 @@ clash-meta ${clash} --------------------------------------------------------------- ################################################################ -${atob(`dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8vdC5tZS9DTUxpdXNzc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmdpdGh1YiDpobnnm67lnLDlnYAgU3RhciFTdGFyIVN0YXIhISEKaHR0cHM6Ly9naXRodWIuY29tL2NtbGl1L2VwZWl1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw==`)} +${decodeURIComponent(atob(`dGVsZWdyYW0lMjAlRTQlQkElQTQlRTYlQjUlODElRTclQkUlQTQlMjAlRTYlOEElODAlRTYlOUMlQUYlRTUlQTQlQTclRTQlQkQlQUMlN0UlRTUlOUMlQTglRTclQkElQkYlRTUlOEYlOTElRTclODklOEMhCmh0dHBzJTNBJTJGJTJGdC5tZSUyRkNNTGl1c3NzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZ2l0aHViJTIwJUU5JUExJUI5JUU3JTlCJUFFJUU1JTlDJUIwJUU1JTlEJTgwJTIwU3RhciFTdGFyIVN0YXIhISEKaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGY21saXUlMkZlcGVpdXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMyUyMw==`))} `; } else { if (typeof fetch != 'function') { @@ -792,7 +808,7 @@ ${atob(`dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8v fakeHostName = `${fakeHostName}.xyz` } - let url = `https://${sub}/sub?host=${fakeHostName}&pw=${fakeUserID}&password=${fakeUserID + atob('JmVwZWl1cz1jbWxpdSZwcm94eWlwPQ==') + RproxyIP}`; + let url = `https://${sub}/sub?host=${fakeHostName}&pw=${fakeUserID}&password=${fakeUserID + atob('JmVwZWl1cz1jbWxpdSZwcm94eWlwPQ==') + RproxyIP}&path=${encodeURIComponent(path)}`; let isBase64 = true; let newAddressesapi = []; let newAddressescsv = []; @@ -824,18 +840,18 @@ ${atob(`dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8v newAddressesapi = await getAddressesapi(addressesapi); newAddressescsv = await getAddressescsv('TRUE'); - url = `https://${hostName}/${fakeUserID}`; + url = `https://${hostName}/${fakeUserID + _url.search}`; } if (!userAgent.includes(('CF-Workers-SUB').toLowerCase())){ if ((userAgent.includes('clash') && !userAgent.includes('nekobox')) || ( _url.searchParams.has('clash'))) { - url = `${subProtocol}://${subconverter}/sub?target=clash&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; + url = `${subProtocol}://${subConverter}/sub?target=clash&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subConfig)}&emoji=${subEmoji}&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; isBase64 = false; } else if (userAgent.includes('sing-box') || userAgent.includes('singbox') || _url.searchParams.has('singbox') || _url.searchParams.has('sb')) { - url = `${subProtocol}://${subconverter}/sub?target=singbox&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; + url = `${subProtocol}://${subConverter}/sub?target=singbox&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subConfig)}&emoji=${subEmoji}&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; isBase64 = false; } else if (userAgent.includes('surge') || _url.searchParams.has('surge')) { - url = `${subProtocol}://${subconverter}/sub?target=surge&ver=4&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&xudp=false&udp=false&tfo=false&expand=true&scv=true&fdn=false`; + url = `${subProtocol}://${subConverter}/sub?target=surge&ver=4&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subConfig)}&emoji=${subEmoji}&list=false&xudp=false&udp=false&tfo=false&expand=true&scv=true&fdn=false`; isBase64 = false; } } @@ -1067,7 +1083,6 @@ function isValidIPv4(address) { return ipv4Regex.test(address); } -let proxyIPPool = []; function subAddresses(host,pw,userAgent,newAddressesapi,newAddressescsv) { addresses = addresses.concat(newAddressesapi); addresses = addresses.concat(newAddressescsv); @@ -1117,7 +1132,7 @@ function subAddresses(host,pw,userAgent,newAddressesapi,newAddressescsv) { if (port == "-1") port = "443"; let 伪装域名 = host ; - let 最终路径 = '/?ed=2560' ; + let 最终路径 = path ; let 节点备注 = ''; if(proxyhosts.length > 0 && (伪装域名.includes('.workers.dev'))) { @@ -1296,532 +1311,137 @@ function surge(content, url) { /** * [js-sha256]{@link https://github.com/emn178/js-sha256} - * - * @version 0.11.0 - * @author Chen, Yi-Cyuan [emn178@gmail.com] + * + * @version 0.11.0 (modified by cmliu) + * @description 本代码基于 js-sha256 项目改编,添加了 SHA-224 哈希算法的实现。 + * @author Chen, Yi-Cyuan [emn178@gmail.com], modified by cmliu * @copyright Chen, Yi-Cyuan 2014-2024 * @license MIT + * + * @modifications 重写并实现了 sha224 函数,引用请注明出处。修改日期:2024-12-04,Github:cmliu */ -/*jslint bitwise: true */ -(function () { - 'use strict'; - - var ERROR = 'input is invalid type'; - var WINDOW = typeof window === 'object'; - var root = WINDOW ? window : {}; - if (root.JS_SHA256_NO_WINDOW) { - WINDOW = false; - } - var WEB_WORKER = !WINDOW && typeof self === 'object'; - var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; - if (NODE_JS) { - root = global; - } else if (WEB_WORKER) { - root = self; - } - var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; - var AMD = typeof define === 'function' && define.amd; - var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; - var HEX_CHARS = '0123456789abcdef'.split(''); - var EXTRA = [-2147483648, 8388608, 32768, 128]; - var SHIFT = [24, 16, 8, 0]; - var K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +function sha224(输入字符串) { + // 内部常量和函数 + const 常量K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; - var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; - - var blocks = []; - - if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { - Array.isArray = function (obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; - }; - } - - if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { - ArrayBuffer.isView = function (obj) { - return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; - }; + + function utf8编码(字符串) { + return unescape(encodeURIComponent(字符串)); } - - var createOutputMethod = function (outputType, is224) { - return function (message) { - return new Sha256(is224, true).update(message)[outputType](); - }; - }; - - var createMethod = function (is224) { - var method = createOutputMethod('hex', is224); - if (NODE_JS) { - method = nodeWrap(method, is224); - } - method.create = function () { - return new Sha256(is224); - }; - method.update = function (message) { - return method.create().update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(type, is224); - } - return method; - }; - - var nodeWrap = function (method, is224) { - var crypto = require('node:crypto') - var Buffer = require('node:buffer').Buffer; - var algorithm = is224 ? 'sha224' : 'sha256'; - var bufferFrom; - if (Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM) { - bufferFrom = Buffer.from; - } else { - bufferFrom = function (message) { - return new Buffer(message); - }; - } - var nodeMethod = function (message) { - if (typeof message === 'string') { - return crypto.createHash(algorithm).update(message, 'utf8').digest('hex'); - } else { - if (message === null || message === undefined) { - throw new Error(ERROR); - } else if (message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } - } - if (Array.isArray(message) || ArrayBuffer.isView(message) || - message.constructor === Buffer) { - return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex'); - } else { - return method(message); + + function 字节转十六进制(字节数组) { + let 十六进制 = ''; + for (let i = 0; i < 字节数组.length; i++) { + 十六进制 += ((字节数组[i] >>> 4) & 0x0F).toString(16); + 十六进制 += (字节数组[i] & 0x0F).toString(16); } - }; - return nodeMethod; - }; - - var createHmacOutputMethod = function (outputType, is224) { - return function (key, message) { - return new HmacSha256(key, is224, true).update(message)[outputType](); - }; - }; - - var createHmacMethod = function (is224) { - var method = createHmacOutputMethod('hex', is224); - method.create = function (key) { - return new HmacSha256(key, is224); - }; - method.update = function (key, message) { - return method.create(key).update(message); - }; - for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createHmacOutputMethod(type, is224); - } - return method; - }; - - function Sha256(is224, sharedMemory) { - if (sharedMemory) { - blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - this.blocks = blocks; - } else { - this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - if (is224) { - this.h0 = 0xc1059ed8; - this.h1 = 0x367cd507; - this.h2 = 0x3070dd17; - this.h3 = 0xf70e5939; - this.h4 = 0xffc00b31; - this.h5 = 0x68581511; - this.h6 = 0x64f98fa7; - this.h7 = 0xbefa4fa4; - } else { // 256 - this.h0 = 0x6a09e667; - this.h1 = 0xbb67ae85; - this.h2 = 0x3c6ef372; - this.h3 = 0xa54ff53a; - this.h4 = 0x510e527f; - this.h5 = 0x9b05688c; - this.h6 = 0x1f83d9ab; - this.h7 = 0x5be0cd19; - } - - this.block = this.start = this.bytes = this.hBytes = 0; - this.finalized = this.hashed = false; - this.first = true; - this.is224 = is224; + return 十六进制; } - - Sha256.prototype.update = function (message) { - if (this.finalized) { - return; - } - var notString, type = typeof message; - if (type !== 'string') { - if (type === 'object') { - if (message === null) { - throw new Error(ERROR); - } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } else if (!Array.isArray(message)) { - if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { - throw new Error(ERROR); - } - } - } else { - throw new Error(ERROR); + + function sha224核心(输入字符串) { + // SHA-224的初始哈希值 + let 哈希值 = [ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]; + + // 预处理 + const 消息长度 = 输入字符串.length * 8; + 输入字符串 += String.fromCharCode(0x80); + while ((输入字符串.length * 8) % 512 !== 448) { + 输入字符串 += String.fromCharCode(0); } - notString = true; - } - var code, index = 0, i, length = message.length, blocks = this.blocks; - while (index < length) { - if (this.hashed) { - this.hashed = false; - blocks[0] = this.block; - this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + + // 64位消息长度 + const 消息长度高位 = Math.floor(消息长度 / 0x100000000); + const 消息长度低位 = 消息长度 & 0xFFFFFFFF; + 输入字符串 += String.fromCharCode( + (消息长度高位 >>> 24) & 0xFF, (消息长度高位 >>> 16) & 0xFF, + (消息长度高位 >>> 8) & 0xFF, 消息长度高位 & 0xFF, + (消息长度低位 >>> 24) & 0xFF, (消息长度低位 >>> 16) & 0xFF, + (消息长度低位 >>> 8) & 0xFF, 消息长度低位 & 0xFF + ); + + const 字数组 = []; + for (let i = 0; i < 输入字符串.length; i += 4) { + 字数组.push( + (输入字符串.charCodeAt(i) << 24) | + (输入字符串.charCodeAt(i + 1) << 16) | + (输入字符串.charCodeAt(i + 2) << 8) | + 输入字符串.charCodeAt(i + 3) + ); } - - if (notString) { - for (i = this.start; index < length && i < 64; ++index) { - blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start; index < length && i < 64; ++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >>> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + + // 主要压缩循环 + for (let i = 0; i < 字数组.length; i += 16) { + const w = new Array(64).fill(0); + for (let j = 0; j < 16; j++) { + w[j] = 字数组[i + j]; } - } - } - - this.lastByteIndex = i; - this.bytes += i - this.start; - if (i >= 64) { - this.block = blocks[16]; - this.start = i - 64; - this.hash(); - this.hashed = true; - } else { - this.start = i; - } - } - if (this.bytes > 4294967295) { - this.hBytes += this.bytes / 4294967296 << 0; - this.bytes = this.bytes % 4294967296; - } - return this; - }; - - Sha256.prototype.finalize = function () { - if (this.finalized) { - return; - } - this.finalized = true; - var blocks = this.blocks, i = this.lastByteIndex; - blocks[16] = this.block; - blocks[i >>> 2] |= EXTRA[i & 3]; - this.block = blocks[16]; - if (i >= 56) { - if (!this.hashed) { - this.hash(); - } - blocks[0] = this.block; - blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - blocks[14] = this.hBytes << 3 | this.bytes >>> 29; - blocks[15] = this.bytes << 3; - this.hash(); - }; - - Sha256.prototype.hash = function () { - var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, - h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; - - for (j = 16; j < 64; ++j) { - // rightrotate - t1 = blocks[j - 15]; - s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); - t1 = blocks[j - 2]; - s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); - blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; - } - - bc = b & c; - for (j = 0; j < 64; j += 4) { - if (this.first) { - if (this.is224) { - ab = 300032; - t1 = blocks[0] - 1413257819; - h = t1 - 150054599 << 0; - d = t1 + 24177077 << 0; - } else { - ab = 704751109; - t1 = blocks[0] - 210244248; - h = t1 - 1521486534 << 0; - d = t1 + 143694565 << 0; - } - this.first = false; - } else { - s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); - s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); - ab = a & b; - maj = ab ^ (a & c) ^ bc; - ch = (e & f) ^ (~e & g); - t1 = h + s1 + ch + K[j] + blocks[j]; - t2 = s0 + maj; - h = d + t1 << 0; - d = t1 + t2 << 0; - } - s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); - s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); - da = d & a; - maj = da ^ (d & b) ^ ab; - ch = (h & e) ^ (~h & f); - t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; - t2 = s0 + maj; - g = c + t1 << 0; - c = t1 + t2 << 0; - s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); - s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); - cd = c & d; - maj = cd ^ (c & a) ^ da; - ch = (g & h) ^ (~g & e); - t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; - t2 = s0 + maj; - f = b + t1 << 0; - b = t1 + t2 << 0; - s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); - s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); - bc = b & c; - maj = bc ^ (b & d) ^ cd; - ch = (f & g) ^ (~f & h); - t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; - t2 = s0 + maj; - e = a + t1 << 0; - a = t1 + t2 << 0; - this.chromeBugWorkAround = true; - } - - this.h0 = this.h0 + a << 0; - this.h1 = this.h1 + b << 0; - this.h2 = this.h2 + c << 0; - this.h3 = this.h3 + d << 0; - this.h4 = this.h4 + e << 0; - this.h5 = this.h5 + f << 0; - this.h6 = this.h6 + g << 0; - this.h7 = this.h7 + h << 0; - }; - - Sha256.prototype.hex = function () { - this.finalize(); - - var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, - h6 = this.h6, h7 = this.h7; - - var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] + - HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] + - HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] + - HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + - HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] + - HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] + - HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] + - HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + - HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] + - HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] + - HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] + - HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + - HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] + - HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] + - HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] + - HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + - HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] + - HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] + - HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] + - HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + - HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] + - HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] + - HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] + - HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + - HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] + - HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] + - HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] + - HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; - if (!this.is224) { - hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] + - HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] + - HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] + - HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; - } - return hex; - }; - - Sha256.prototype.toString = Sha256.prototype.hex; - - Sha256.prototype.digest = function () { - this.finalize(); - - var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, - h6 = this.h6, h7 = this.h7; - - var arr = [ - (h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF, - (h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF, - (h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF, - (h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF, - (h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF, - (h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF, - (h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF - ]; - if (!this.is224) { - arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF); - } - return arr; - }; - - Sha256.prototype.array = Sha256.prototype.digest; - - Sha256.prototype.arrayBuffer = function () { - this.finalize(); - - var buffer = new ArrayBuffer(this.is224 ? 28 : 32); - var dataView = new DataView(buffer); - dataView.setUint32(0, this.h0); - dataView.setUint32(4, this.h1); - dataView.setUint32(8, this.h2); - dataView.setUint32(12, this.h3); - dataView.setUint32(16, this.h4); - dataView.setUint32(20, this.h5); - dataView.setUint32(24, this.h6); - if (!this.is224) { - dataView.setUint32(28, this.h7); - } - return buffer; - }; - - function HmacSha256(key, is224, sharedMemory) { - var i, type = typeof key; - if (type === 'string') { - var bytes = [], length = key.length, index = 0, code; - for (i = 0; i < length; ++i) { - code = key.charCodeAt(i); - if (code < 0x80) { - bytes[index++] = code; - } else if (code < 0x800) { - bytes[index++] = (0xc0 | (code >>> 6)); - bytes[index++] = (0x80 | (code & 0x3f)); - } else if (code < 0xd800 || code >= 0xe000) { - bytes[index++] = (0xe0 | (code >>> 12)); - bytes[index++] = (0x80 | ((code >>> 6) & 0x3f)); - bytes[index++] = (0x80 | (code & 0x3f)); - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); - bytes[index++] = (0xf0 | (code >>> 18)); - bytes[index++] = (0x80 | ((code >>> 12) & 0x3f)); - bytes[index++] = (0x80 | ((code >>> 6) & 0x3f)); - bytes[index++] = (0x80 | (code & 0x3f)); - } - } - key = bytes; - } else { - if (type === 'object') { - if (key === null) { - throw new Error(ERROR); - } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { - key = new Uint8Array(key); - } else if (!Array.isArray(key)) { - if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { - throw new Error(ERROR); + + for (let j = 16; j < 64; j++) { + const s0 = 右旋转(w[j-15], 7) ^ 右旋转(w[j-15], 18) ^ (w[j-15] >>> 3); + const s1 = 右旋转(w[j-2], 17) ^ 右旋转(w[j-2], 19) ^ (w[j-2] >>> 10); + w[j] = (w[j-16] + s0 + w[j-7] + s1) >>> 0; } - } - } else { - throw new Error(ERROR); + + let [a, b, c, d, e, f, g, h0] = 哈希值; + + for (let j = 0; j < 64; j++) { + const S1 = 右旋转(e, 6) ^ 右旋转(e, 11) ^ 右旋转(e, 25); + const ch = (e & f) ^ (~e & g); + const temp1 = (h0 + S1 + ch + 常量K[j] + w[j]) >>> 0; + const S0 = 右旋转(a, 2) ^ 右旋转(a, 13) ^ 右旋转(a, 22); + const maj = (a & b) ^ (a & c) ^ (b & c); + const temp2 = (S0 + maj) >>> 0; + + h0 = g; + g = f; + f = e; + e = (d + temp1) >>> 0; + d = c; + c = b; + b = a; + a = (temp1 + temp2) >>> 0; + } + + 哈希值[0] = (哈希值[0] + a) >>> 0; + 哈希值[1] = (哈希值[1] + b) >>> 0; + 哈希值[2] = (哈希值[2] + c) >>> 0; + 哈希值[3] = (哈希值[3] + d) >>> 0; + 哈希值[4] = (哈希值[4] + e) >>> 0; + 哈希值[5] = (哈希值[5] + f) >>> 0; + 哈希值[6] = (哈希值[6] + g) >>> 0; + 哈希值[7] = (哈希值[7] + h0) >>> 0; } - } - - if (key.length > 64) { - key = (new Sha256(is224, true)).update(key).array(); - } - - var oKeyPad = [], iKeyPad = []; - for (i = 0; i < 64; ++i) { - var b = key[i] || 0; - oKeyPad[i] = 0x5c ^ b; - iKeyPad[i] = 0x36 ^ b; - } - - Sha256.call(this, is224, sharedMemory); - - this.update(iKeyPad); - this.oKeyPad = oKeyPad; - this.inner = true; - this.sharedMemory = sharedMemory; + + // 截断到224位 + return 哈希值.slice(0, 7); } - HmacSha256.prototype = new Sha256(); - - HmacSha256.prototype.finalize = function () { - Sha256.prototype.finalize.call(this); - if (this.inner) { - this.inner = false; - var innerHash = this.array(); - Sha256.call(this, this.is224, this.sharedMemory); - this.update(this.oKeyPad); - this.update(innerHash); - Sha256.prototype.finalize.call(this); - } - }; - - function createSha224() { - var sha224 = createMethod(true); - sha224.hmac = createHmacMethod(true); - return sha224; - } - - const sha224 = createSha224(); - - if (COMMON_JS) { - module.exports = { - sha224: sha224 - }; - } else { - root.sha224 = sha224; - if (AMD) { - define(function () { - return { - sha224: sha224 - }; - }); - } - } - })(); \ No newline at end of file + + function 右旋转(数值, 位数) { + return ((数值 >>> 位数) | (数值 << (32 - 位数))) >>> 0; + } + + // 主函数逻辑 + const 编码输入 = utf8编码(输入字符串); + const 哈希结果 = sha224核心(编码输入); + + // 转换为十六进制字符串 + return 字节转十六进制( + 哈希结果.flatMap(h => [ + (h >>> 24) & 0xFF, + (h >>> 16) & 0xFF, + (h >>> 8) & 0xFF, + h & 0xFF + ]) + ); +} \ No newline at end of file