mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2026-03-17 04:02:36 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0072739f01 | ||
|
|
1bd2f5f643 | ||
|
|
0a31f5d5d7 | ||
|
|
6484edb5db | ||
|
|
c073870f24 | ||
|
|
e93332048e | ||
|
|
4dcb9ae79e | ||
|
|
6ea3575101 |
6
backend/dist/cron-sync-artifacts.min.js
vendored
6
backend/dist/cron-sync-artifacts.min.js
vendored
File diff suppressed because one or more lines are too long
6
backend/dist/sub-store-parser.loon.min.js
vendored
6
backend/dist/sub-store-parser.loon.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sub-store",
|
||||
"version": "2.12.2",
|
||||
"version": "2.12.7",
|
||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
@@ -19,6 +19,7 @@
|
||||
"js-base64": "^3.7.2",
|
||||
"lodash": "^4.17.21",
|
||||
"request": "^2.88.2",
|
||||
"requests": "^0.3.0",
|
||||
"semver": "^7.3.7",
|
||||
"static-js-yaml": "^1.0.0",
|
||||
"uuid": "^8.3.2"
|
||||
|
||||
87
backend/pnpm-lock.yaml
generated
87
backend/pnpm-lock.yaml
generated
@@ -31,6 +31,7 @@ specifiers:
|
||||
prettier: 2.6.2
|
||||
prettier-plugin-sort-imports: ^1.6.1
|
||||
request: ^2.88.2
|
||||
requests: ^0.3.0
|
||||
semver: ^7.3.7
|
||||
static-js-yaml: ^1.0.0
|
||||
tinyify: ^3.0.0
|
||||
@@ -43,6 +44,7 @@ dependencies:
|
||||
js-base64: registry.npmmirror.com/js-base64/3.7.2
|
||||
lodash: registry.npmmirror.com/lodash/4.17.21
|
||||
request: registry.npmmirror.com/request/2.88.2
|
||||
requests: registry.npmmirror.com/requests/0.3.0
|
||||
semver: registry.npmmirror.com/semver/7.3.7
|
||||
static-js-yaml: registry.npmmirror.com/static-js-yaml/1.0.0
|
||||
uuid: registry.npmmirror.com/uuid/8.3.2
|
||||
@@ -2250,6 +2252,12 @@ packages:
|
||||
follow-redirects: registry.npmmirror.com/follow-redirects/1.13.0
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/axo/0.0.2:
|
||||
resolution: {integrity: sha512-8CC4Mb+OhK97UEng0PgiqUDNZjzVcWDsV+G2vLYCQn1jEL7y6VqiRVlZlRu+aA/ckSznmNzW6X1I6nj2As/haQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/axo/-/axo-0.0.2.tgz}
|
||||
name: axo
|
||||
version: 0.0.2
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/babel-plugin-dynamic-import-node/2.3.3:
|
||||
resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz}
|
||||
name: babel-plugin-dynamic-import-node
|
||||
@@ -4296,6 +4304,12 @@ packages:
|
||||
es5-ext: registry.npmmirror.com/es5-ext/0.10.61
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/eventemitter3/4.0.7:
|
||||
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz}
|
||||
name: eventemitter3
|
||||
version: 4.0.7
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/events/3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/events/-/events-3.3.0.tgz}
|
||||
name: events
|
||||
@@ -4410,6 +4424,12 @@ packages:
|
||||
name: extend
|
||||
version: 3.0.2
|
||||
|
||||
registry.npmmirror.com/extendible/0.1.1:
|
||||
resolution: {integrity: sha512-AglckQA0TJV8/ZmhQcNmaaFcFFPXFIoZbfuoQOlGDK7Jh/roWotYzJ7ik1FBBCHBr8n7CgTR8lXXPAN8Rfb7rw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/extendible/-/extendible-0.1.1.tgz}
|
||||
name: extendible
|
||||
version: 0.1.1
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/extglob/2.0.4:
|
||||
resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/extglob/-/extglob-2.0.4.tgz}
|
||||
name: extglob
|
||||
@@ -4435,6 +4455,12 @@ packages:
|
||||
engines: {'0': node >=0.6.0}
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/failure/1.1.1:
|
||||
resolution: {integrity: sha512-lzrrk0NUfjVeU3jLmfU01zP5bfg4XVFxHREYGvgJowaCqHLSQtqIGENH/CU+oSs6yfYObdSM7b9UY/3p2VJOSg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/failure/-/failure-1.1.1.tgz}
|
||||
name: failure
|
||||
version: 1.1.1
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/falafel/2.2.5:
|
||||
resolution: {integrity: sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/falafel/-/falafel-2.2.5.tgz}
|
||||
name: falafel
|
||||
@@ -5219,6 +5245,12 @@ packages:
|
||||
glogg: registry.npmmirror.com/glogg/1.0.2
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/hang/1.0.0:
|
||||
resolution: {integrity: sha512-vtBz98Bt/Tbm03cZO5Ymc7ZL8ead/jIx9T5Wg/xuz+9BXPAJNJSdGQW63LoaesogUQKTpHyal339hxTaTf/APg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/hang/-/hang-1.0.0.tgz}
|
||||
name: hang
|
||||
version: 1.0.0
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/har-schema/2.0.0:
|
||||
resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz}
|
||||
name: har-schema
|
||||
@@ -6336,6 +6368,17 @@ packages:
|
||||
strip-bom: registry.npmmirror.com/strip-bom/2.0.0
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/loads/0.0.4:
|
||||
resolution: {integrity: sha512-XjPzzYIHkuMNqYyvh6AECQAHi682nyKO9TMdMYnaz7QbPDI/KIeSIjRhAlXIbRMPYAgtLUYgPlD3mtKZ4Q8SYA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/loads/-/loads-0.0.4.tgz}
|
||||
name: loads
|
||||
version: 0.0.4
|
||||
dependencies:
|
||||
failure: registry.npmmirror.com/failure/1.1.1
|
||||
one-time: registry.npmmirror.com/one-time/0.0.4
|
||||
xhr-response: registry.npmmirror.com/xhr-response/1.0.1
|
||||
xhr-status: registry.npmmirror.com/xhr-status/1.0.1
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/locate-path/3.0.0:
|
||||
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-3.0.0.tgz}
|
||||
name: locate-path
|
||||
@@ -6876,6 +6919,12 @@ packages:
|
||||
semver: registry.npmmirror.com/semver/5.7.1
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/node-http-xhr/1.3.4:
|
||||
resolution: {integrity: sha512-0bA08/2RKWxw6pMkOVd3KP+0F5+ifQLMMTDxrCgxlgkoU1N8DhCbCSAYEqpgaVYM2smvbVVewiXjW+8AyoLfxQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/node-http-xhr/-/node-http-xhr-1.3.4.tgz}
|
||||
name: node-http-xhr
|
||||
version: 1.3.4
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/node-releases/2.0.4:
|
||||
resolution: {integrity: sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.4.tgz}
|
||||
name: node-releases
|
||||
@@ -7110,6 +7159,12 @@ packages:
|
||||
wrappy: registry.npmmirror.com/wrappy/1.0.2
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/one-time/0.0.4:
|
||||
resolution: {integrity: sha512-qAMrwuk2xLEutlASoiPiAMW3EN3K96Ka/ilSXYr6qR1zSVXw2j7+yDSqGTC4T9apfLYxM3tLLjKvgPdAUK7kYQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/one-time/-/one-time-0.0.4.tgz}
|
||||
name: one-time
|
||||
version: 0.0.4
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/optionator/0.8.3:
|
||||
resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/optionator/-/optionator-0.8.3.tgz}
|
||||
name: optionator
|
||||
@@ -8057,6 +8112,20 @@ packages:
|
||||
uuid: registry.npmmirror.com/uuid/3.4.0
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/requests/0.3.0:
|
||||
resolution: {integrity: sha512-1B6nkiHjC1O1cSgFhEwkc+xd8vuj04h7xSmCg5yI8nmhCIKbPkX47od8erQ2pokBt5qxUO7dwP4jplXD6k6ISA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/requests/-/requests-0.3.0.tgz}
|
||||
name: requests
|
||||
version: 0.3.0
|
||||
dependencies:
|
||||
axo: registry.npmmirror.com/axo/0.0.2
|
||||
eventemitter3: registry.npmmirror.com/eventemitter3/4.0.7
|
||||
extendible: registry.npmmirror.com/extendible/0.1.1
|
||||
hang: registry.npmmirror.com/hang/1.0.0
|
||||
loads: registry.npmmirror.com/loads/0.0.4
|
||||
node-http-xhr: registry.npmmirror.com/node-http-xhr/1.3.4
|
||||
xhr-send: registry.npmmirror.com/xhr-send/1.0.0
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/require-directory/2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz}
|
||||
name: require-directory
|
||||
@@ -9731,6 +9800,24 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/xhr-response/1.0.1:
|
||||
resolution: {integrity: sha512-m2FlVRCl3VqDcpc8UaWZJpwuHpFR2vYeXv6ipXU2Uuu4vNKFYVEFI0emuJN370Fge+JCbiAnS+JJmSoWVmWrjQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xhr-response/-/xhr-response-1.0.1.tgz}
|
||||
name: xhr-response
|
||||
version: 1.0.1
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/xhr-send/1.0.0:
|
||||
resolution: {integrity: sha512-789EG4qW6Z0nPvG74AV3WWQCnBG5HxJXNiBsnEivZ8OpbvVA0amH0+g+MNT99o5kt/XLdRezm5KS1wJzcGJztw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xhr-send/-/xhr-send-1.0.0.tgz}
|
||||
name: xhr-send
|
||||
version: 1.0.0
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/xhr-status/1.0.1:
|
||||
resolution: {integrity: sha512-VF0WSqtmkf56OmF26LCWsWvRb1a+WYGdHDoQnPPCVUQTM8CVUAOBcUDsm7nP7SQcgEEdrvF4DmhEADuXdGieyw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xhr-status/-/xhr-status-1.0.1.tgz}
|
||||
name: xhr-status
|
||||
version: 1.0.1
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/xtend/2.1.2:
|
||||
resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xtend/-/xtend-2.1.2.tgz}
|
||||
name: xtend
|
||||
|
||||
@@ -2,6 +2,8 @@ import { getIfNotBlank, isPresent, isNotBlank, getIfPresent } from '@/utils';
|
||||
import getSurgeParser from './peggy/surge';
|
||||
import getLoonParser from './peggy/loon';
|
||||
import getQXParser from './peggy/qx';
|
||||
import getTrojanURIParser from './peggy/trojan-uri';
|
||||
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
// Parse SS URI format (only supports new SIP002, legacy format is depreciated).
|
||||
@@ -240,39 +242,9 @@ function URI_Trojan() {
|
||||
};
|
||||
|
||||
const parse = (line) => {
|
||||
line = line.split('trojan://')[1];
|
||||
const [server, port] = line.split('@')[1].split('?')[0].split(':');
|
||||
const name = decodeURIComponent(line.split('#')[1].trim());
|
||||
let paramArr = line.split('?');
|
||||
let scert = null;
|
||||
const params = new Map();
|
||||
if (paramArr.length > 1) {
|
||||
paramArr = paramArr[1].split('#')[0].split('&');
|
||||
for (const pair of paramArr) {
|
||||
let [key, val] = pair.split('=');
|
||||
// skip empty values
|
||||
val = val.trim();
|
||||
if (val.length > 0) {
|
||||
params.set(key, val);
|
||||
}
|
||||
}
|
||||
if (
|
||||
params.get('allowInsecure') === '1' ||
|
||||
params.get('allowInsecure') === 'true'
|
||||
) {
|
||||
scert = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: name || `[Trojan] ${server}`, // trojan uri may have no server tag!
|
||||
type: 'trojan',
|
||||
server,
|
||||
port,
|
||||
password: line.split('@')[0],
|
||||
sni: getIfPresent(params.get('sni')),
|
||||
'skip-cert-verify': getIfPresent(scert),
|
||||
};
|
||||
const parser = getTrojanURIParser();
|
||||
const proxy = parser.parse(line);
|
||||
return proxy;
|
||||
};
|
||||
return { name, test, parse };
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ port = digits:[0-9]+ {
|
||||
method = comma cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
}
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"/"auto");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"/"auto");
|
||||
|
||||
username = & {
|
||||
let j = peg$currPos;
|
||||
|
||||
@@ -112,7 +112,7 @@ port = digits:[0-9]+ {
|
||||
method = comma cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
}
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"/"auto");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"/"auto");
|
||||
|
||||
username = & {
|
||||
let j = peg$currPos;
|
||||
|
||||
@@ -142,7 +142,7 @@ uuid = comma "password" equals uuid:[^=,]+ { proxy.uuid = uuid.join("").trim();
|
||||
method = comma "method" equals cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
};
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
aead = comma "aead" equals flag:bool { proxy.aead = flag; }
|
||||
|
||||
udp_relay = comma "udp-relay" equals flag:bool { proxy.udp = flag; }
|
||||
|
||||
@@ -140,7 +140,7 @@ uuid = comma "password" equals uuid:[^=,]+ { proxy.uuid = uuid.join("").trim();
|
||||
method = comma "method" equals cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
};
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
aead = comma "aead" equals flag:bool { proxy.aead = flag; }
|
||||
|
||||
udp_relay = comma "udp-relay" equals flag:bool { proxy.udp = flag; }
|
||||
|
||||
@@ -154,7 +154,7 @@ vmess_aead = comma "vmess-aead" equals flag:bool { proxy.aead = flag; }
|
||||
method = comma "encrypt-method" equals cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
}
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
|
||||
ws = comma "ws" equals flag:bool { obfs.type = "ws"; }
|
||||
ws_headers = comma "ws-headers" equals headers:$[^,]+ {
|
||||
|
||||
@@ -152,7 +152,7 @@ vmess_aead = comma "vmess-aead" equals flag:bool { proxy.aead = flag; }
|
||||
method = comma "encrypt-method" equals cipher:cipher {
|
||||
proxy.cipher = cipher;
|
||||
}
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"xchacha20-ietf-poly1305"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none");
|
||||
|
||||
ws = comma "ws" equals flag:bool { obfs.type = "ws"; }
|
||||
ws_headers = comma "ws-headers" equals headers:$[^,]+ {
|
||||
|
||||
115
backend/src/core/proxy-utils/parsers/peggy/trojan-uri.js
Normal file
115
backend/src/core/proxy-utils/parsers/peggy/trojan-uri.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import * as peggy from 'peggy';
|
||||
const grammars = String.raw`
|
||||
// global initializer
|
||||
{{
|
||||
function $set(obj, path, value) {
|
||||
if (Object(obj) !== obj) return obj;
|
||||
if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
|
||||
path
|
||||
.slice(0, -1)
|
||||
.reduce((a, c, i) => (Object(a[c]) === a[c] ? a[c] : (a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {})), obj)[
|
||||
path[path.length - 1]
|
||||
] = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function toBool(str) {
|
||||
if (typeof str === 'undefined' || str === null) return undefined;
|
||||
return /(TRUE)|1/i.test(str);
|
||||
}
|
||||
}}
|
||||
|
||||
{
|
||||
const proxy = {};
|
||||
const obfs = {};
|
||||
const $ = {};
|
||||
const params = {};
|
||||
}
|
||||
|
||||
start = (trojan) {
|
||||
return proxy
|
||||
}
|
||||
|
||||
trojan = "trojan://" password:password "@" server:server ":" port:port params? name:name?{
|
||||
proxy.type = "trojan";
|
||||
proxy.password = password;
|
||||
proxy.server = server;
|
||||
proxy.port = port;
|
||||
proxy.name = name;
|
||||
|
||||
// name may be empty
|
||||
if (!proxy.name) {
|
||||
proxy.name = server + ":" + port;
|
||||
}
|
||||
};
|
||||
|
||||
password = match:$[^@]+ {
|
||||
return decodeURIComponent(match);
|
||||
};
|
||||
|
||||
server = ip/domain;
|
||||
|
||||
domain = match:[0-9a-zA-z-_.]+ {
|
||||
const domain = match.join("");
|
||||
if (/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/.test(domain)) {
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
ip = & {
|
||||
const start = peg$currPos;
|
||||
let end;
|
||||
let j = start;
|
||||
while (j < input.length) {
|
||||
if (input[j] === ",") break;
|
||||
if (input[j] === ":") end = j;
|
||||
j++;
|
||||
}
|
||||
peg$currPos = end || j;
|
||||
$.ip = input.substring(start, end).trim();
|
||||
return true;
|
||||
} { return $.ip; }
|
||||
|
||||
port = digits:[0-9]+ {
|
||||
const port = parseInt(digits.join(""), 10);
|
||||
if (port >= 80 && port <= 65535) {
|
||||
return port;
|
||||
} else {
|
||||
throw new Error("Invalid port: " + port);
|
||||
}
|
||||
}
|
||||
|
||||
params = "?" head:param tail:("&"@param)* {
|
||||
proxy["skip-cert-verify"] = toBool(params["allowInsecure"]);
|
||||
proxy.sni = params["sni"] || params["peer"];
|
||||
|
||||
if (toBool(params["ws"])) {
|
||||
proxy.network = "ws";
|
||||
$set(proxy, "ws-opts.path", params["wspath"]);
|
||||
}
|
||||
|
||||
proxy.udp = toBool(params["udp"]);
|
||||
proxy.tfo = toBool(params["tfo"]);
|
||||
}
|
||||
|
||||
param = kv/single;
|
||||
|
||||
kv = key:$[a-z]i+ "=" value:$[^&#]i+ {
|
||||
params[key] = value;
|
||||
}
|
||||
|
||||
single = key:$[a-z]i+ {
|
||||
params[key] = true;
|
||||
};
|
||||
|
||||
name = "#" + match:$.* {
|
||||
return decodeURIComponent(match);
|
||||
}
|
||||
`;
|
||||
let parser;
|
||||
export default function getParser() {
|
||||
if (!parser) {
|
||||
parser = peggy.generate(grammars);
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
105
backend/src/core/proxy-utils/parsers/peggy/trojan-uri.peg
Normal file
105
backend/src/core/proxy-utils/parsers/peggy/trojan-uri.peg
Normal file
@@ -0,0 +1,105 @@
|
||||
// global initializer
|
||||
{{
|
||||
function $set(obj, path, value) {
|
||||
if (Object(obj) !== obj) return obj;
|
||||
if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
|
||||
path
|
||||
.slice(0, -1)
|
||||
.reduce((a, c, i) => (Object(a[c]) === a[c] ? a[c] : (a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {})), obj)[
|
||||
path[path.length - 1]
|
||||
] = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function toBool(str) {
|
||||
if (typeof str === 'undefined' || str === null) return undefined;
|
||||
return /(TRUE)|1/i.test(str);
|
||||
}
|
||||
}}
|
||||
|
||||
{
|
||||
const proxy = {};
|
||||
const obfs = {};
|
||||
const $ = {};
|
||||
const params = {};
|
||||
}
|
||||
|
||||
start = (trojan) {
|
||||
return proxy
|
||||
}
|
||||
|
||||
trojan = "trojan://" password:password "@" server:server ":" port:port params? name:name?{
|
||||
proxy.type = "trojan";
|
||||
proxy.password = password;
|
||||
proxy.server = server;
|
||||
proxy.port = port;
|
||||
proxy.name = name;
|
||||
|
||||
// name may be empty
|
||||
if (!proxy.name) {
|
||||
proxy.name = server + ":" + port;
|
||||
}
|
||||
};
|
||||
|
||||
password = match:$[^@]+ {
|
||||
return decodeURIComponent(match);
|
||||
};
|
||||
|
||||
server = ip/domain;
|
||||
|
||||
domain = match:[0-9a-zA-z-_.]+ {
|
||||
const domain = match.join("");
|
||||
if (/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/.test(domain)) {
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
ip = & {
|
||||
const start = peg$currPos;
|
||||
let end;
|
||||
let j = start;
|
||||
while (j < input.length) {
|
||||
if (input[j] === ",") break;
|
||||
if (input[j] === ":") end = j;
|
||||
j++;
|
||||
}
|
||||
peg$currPos = end || j;
|
||||
$.ip = input.substring(start, end).trim();
|
||||
return true;
|
||||
} { return $.ip; }
|
||||
|
||||
port = digits:[0-9]+ {
|
||||
const port = parseInt(digits.join(""), 10);
|
||||
if (port >= 80 && port <= 65535) {
|
||||
return port;
|
||||
} else {
|
||||
throw new Error("Invalid port: " + port);
|
||||
}
|
||||
}
|
||||
|
||||
params = "?" head:param tail:("&"@param)* {
|
||||
proxy["skip-cert-verify"] = toBool(params["allowInsecure"]);
|
||||
proxy.sni = params["sni"] || params["peer"];
|
||||
|
||||
if (toBool(params["ws"])) {
|
||||
proxy.network = "ws";
|
||||
$set(proxy, "ws-opts.path", params["wspath"]);
|
||||
}
|
||||
|
||||
proxy.udp = toBool(params["udp"]);
|
||||
proxy.tfo = toBool(params["tfo"]);
|
||||
}
|
||||
|
||||
param = kv/single;
|
||||
|
||||
kv = key:$[a-z]i+ "=" value:$[^&#]i+ {
|
||||
params[key] = value;
|
||||
}
|
||||
|
||||
single = key:$[a-z]i+ {
|
||||
params[key] = true;
|
||||
};
|
||||
|
||||
name = "#" + match:$.* {
|
||||
return decodeURIComponent(match);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { getFlag } from '@/utils/geo';
|
||||
import lodash from 'lodash';
|
||||
import $ from '@/core/app';
|
||||
import { hex_md5 } from '@/vendor/md5';
|
||||
import { ProxyUtils } from '@/core/proxy-utils';
|
||||
|
||||
/**
|
||||
The rule "(name CONTAINS "🇨🇳") AND (port IN [80, 443])" can be expressed as follows:
|
||||
@@ -631,6 +632,7 @@ function createDynamicFunction(name, script, $arguments) {
|
||||
'$persistentStore',
|
||||
'$httpClient',
|
||||
'$notification',
|
||||
'ProxyUtils',
|
||||
`${script}\n return ${name}`,
|
||||
)(
|
||||
$arguments,
|
||||
@@ -642,13 +644,15 @@ function createDynamicFunction(name, script, $arguments) {
|
||||
$httpClient,
|
||||
// eslint-disable-next-line no-undef
|
||||
$notification,
|
||||
ProxyUtils,
|
||||
);
|
||||
} else {
|
||||
return new Function(
|
||||
'$arguments',
|
||||
'$substore',
|
||||
'lodash',
|
||||
'ProxyUtils',
|
||||
`${script}\n return ${name}`,
|
||||
)($arguments, $, lodash);
|
||||
)($arguments, $, lodash, ProxyUtils);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { deleteByName, findByName, updateByName } from '@/utils/database';
|
||||
import { COLLECTIONS_KEY } from '@/constants';
|
||||
import { COLLECTIONS_KEY, ARTIFACTS_KEY } from '@/constants';
|
||||
import { failed, success } from '@/restful/response';
|
||||
import $ from '@/core/app';
|
||||
import { RequestInvalidError, ResourceNotFoundError } from '@/restful/errors';
|
||||
@@ -67,6 +67,21 @@ function updateCollection(req, res) {
|
||||
...collection,
|
||||
};
|
||||
$.info(`正在更新组合订阅:${name}...`);
|
||||
|
||||
if (name !== newCol.name) {
|
||||
// update all artifacts referring this collection
|
||||
const allArtifacts = $.read(ARTIFACTS_KEY) || [];
|
||||
for (const artifact of allArtifacts) {
|
||||
if (
|
||||
artifact.type === 'collection' &&
|
||||
artifact.source === oldCol.name
|
||||
) {
|
||||
artifact.source = newCol.name;
|
||||
}
|
||||
}
|
||||
$.write(allArtifacts, ARTIFACTS_KEY);
|
||||
}
|
||||
|
||||
updateByName(allCols, name, newCol);
|
||||
$.write(allCols, COLLECTIONS_KEY);
|
||||
success(res, newCol);
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
RequestInvalidError,
|
||||
} from './errors';
|
||||
import { deleteByName, findByName, updateByName } from '@/utils/database';
|
||||
import { SUBS_KEY, COLLECTIONS_KEY } from '@/constants';
|
||||
import { SUBS_KEY, COLLECTIONS_KEY, ARTIFACTS_KEY } from '@/constants';
|
||||
import { getFlowHeaders } from '@/utils/flow';
|
||||
import { success, failed } from './response';
|
||||
import $ from '@/core/app';
|
||||
@@ -137,14 +137,28 @@ function updateSubscription(req, res) {
|
||||
$.info(`正在更新订阅: ${name}`);
|
||||
// allow users to update the subscription name
|
||||
if (name !== sub.name) {
|
||||
// we need to find out all collections refer to this name
|
||||
const allCols = $.read(COLLECTIONS_KEY);
|
||||
// update all collections refer to this name
|
||||
const allCols = $.read(COLLECTIONS_KEY) || [];
|
||||
for (const collection of allCols) {
|
||||
const idx = collection.subscriptions.indexOf(name);
|
||||
if (idx !== -1) {
|
||||
collection.subscriptions[idx] = sub.name;
|
||||
}
|
||||
}
|
||||
|
||||
// update all artifacts referring this subscription
|
||||
const allArtifacts = $.read(ARTIFACTS_KEY) || [];
|
||||
for (const artifact of allArtifacts) {
|
||||
if (
|
||||
artifact.type === 'subscription' &&
|
||||
artifact.source == name
|
||||
) {
|
||||
artifact.source = sub.name;
|
||||
}
|
||||
}
|
||||
|
||||
$.write(allCols, COLLECTIONS_KEY);
|
||||
$.write(allArtifacts, ARTIFACTS_KEY);
|
||||
}
|
||||
updateByName(allSubs, name, newSub);
|
||||
$.write(allSubs, SUBS_KEY);
|
||||
|
||||
@@ -81,7 +81,8 @@ function doMigrationV2() {
|
||||
useless: 'DEFAULT',
|
||||
},
|
||||
};
|
||||
processes.forEach((p) => {
|
||||
for (const p of processes) {
|
||||
if (!p.type) continue;
|
||||
if (p.type === 'Useless Filter') {
|
||||
quickSettingOperator.args.useless = 'ENABLED';
|
||||
} else if (p.type === 'Set Property Operator') {
|
||||
@@ -120,7 +121,7 @@ function doMigrationV2() {
|
||||
} else {
|
||||
newProcesses.push(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
newProcesses.unshift(quickSettingOperator);
|
||||
item.process = newProcesses;
|
||||
}
|
||||
|
||||
11
backend/src/vendor/open-api.js
vendored
11
backend/src/vendor/open-api.js
vendored
@@ -253,6 +253,17 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
|
||||
|
||||
events.onRequest(method, options);
|
||||
|
||||
if (options.node) {
|
||||
// Surge & Loon allow connecting to a server using a specified proxy node
|
||||
if (isSurge) {
|
||||
const build = $environment['surge-build'];
|
||||
if (build && parseInt(build) >= 2407) {
|
||||
options['policy-descriptor'] = options.node;
|
||||
delete options.node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let worker;
|
||||
if (isQX) {
|
||||
worker = $task.fetch({
|
||||
|
||||
6
backend/sub-store.min.js
vendored
6
backend/sub-store.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -10,7 +10,18 @@ http:
|
||||
type: request
|
||||
require-body: true
|
||||
timeout: 120
|
||||
|
||||
cron:
|
||||
script:
|
||||
- name: cron-sync-artifacts
|
||||
cron: "0 0 * * *"
|
||||
timeout: 120
|
||||
|
||||
script-providers:
|
||||
sub-store:
|
||||
url: https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store.min.js
|
||||
interval: 86400
|
||||
|
||||
cron-sync-artifacts:
|
||||
url: https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||
interval: 86400
|
||||
@@ -4,6 +4,6 @@
|
||||
hostname=%APPEND% sub.store
|
||||
|
||||
[Script]
|
||||
Sub-Store = type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store.min.js,requires-body=true,timeout=120,max-size=131072
|
||||
Sub-Store = type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store.min.js,requires-body=true,timeout=120,max-size=131072,ability=http-client-policy
|
||||
|
||||
Sub-Store Sync = type=cron,cronexp=0 0 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||
|
||||
174
scripts/ip-flag.js
Normal file
174
scripts/ip-flag.js
Normal file
@@ -0,0 +1,174 @@
|
||||
const RESOURCE_CACHE_KEY = '#sub-store-cached-resource';
|
||||
const CACHE_EXPIRATION_TIME_MS = 10 * 60 * 1000;
|
||||
const $ = $substore;
|
||||
|
||||
class ResourceCache {
|
||||
constructor(expires) {
|
||||
this.expires = expires;
|
||||
if (!$.read(RESOURCE_CACHE_KEY)) {
|
||||
$.write('{}', RESOURCE_CACHE_KEY);
|
||||
}
|
||||
this.resourceCache = JSON.parse($.read(RESOURCE_CACHE_KEY));
|
||||
this._cleanup();
|
||||
}
|
||||
|
||||
_cleanup() {
|
||||
// clear obsolete cached resource
|
||||
let clear = false;
|
||||
Object.entries(this.resourceCache).forEach((entry) => {
|
||||
const [id, updated] = entry;
|
||||
if (new Date().getTime() - updated > this.expires) {
|
||||
$.delete(`#${id}`);
|
||||
delete this.resourceCache[id];
|
||||
clear = true;
|
||||
}
|
||||
});
|
||||
if (clear) this._persist();
|
||||
}
|
||||
|
||||
revokeAll() {
|
||||
Object.keys(this.resourceCache).forEach((id) => {
|
||||
$.delete(`#${id}`);
|
||||
});
|
||||
this.resourceCache = {};
|
||||
this._persist();
|
||||
}
|
||||
|
||||
_persist() {
|
||||
$.write(JSON.stringify(this.resourceCache), RESOURCE_CACHE_KEY);
|
||||
}
|
||||
|
||||
get(id) {
|
||||
const updated = this.resourceCache[id];
|
||||
if (updated && new Date().getTime() - updated <= this.expires) {
|
||||
return $.read(`#${id}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
set(id, value) {
|
||||
this.resourceCache[id] = new Date().getTime();
|
||||
this._persist();
|
||||
$.write(value, `#${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
const resourceCache = new ResourceCache(CACHE_EXPIRATION_TIME_MS);
|
||||
|
||||
async function operator(proxies) {
|
||||
const { isLoon, isSurge } = $substore.env;
|
||||
let support = false;
|
||||
if (isLoon) {
|
||||
support = true;
|
||||
} else if (isSurge) {
|
||||
const build = $environment['surge-build'];
|
||||
if (build && parseInt(build) >= 2407) {
|
||||
support = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (support) {
|
||||
const batches = [];
|
||||
const BATCH_SIZE = 10;
|
||||
|
||||
let i = 0;
|
||||
while (i < proxies.length) {
|
||||
const batch = proxies.slice(i, i + BATCH_SIZE);
|
||||
await Promise.all(proxies.map(async proxy => {
|
||||
try {
|
||||
// remove the original flag
|
||||
let proxyName = removeFlag(proxy.name);
|
||||
|
||||
// query ip-api
|
||||
const countryCode = await queryIpApi(proxy);
|
||||
|
||||
proxyName = getFlagEmoji(countryCode) + ' ' + proxyName;
|
||||
proxy.name = proxyName;
|
||||
} catch (err) {
|
||||
// TODO:
|
||||
}
|
||||
}));
|
||||
|
||||
await sleep(1000);
|
||||
i += BATCH_SIZE;
|
||||
}
|
||||
} else {
|
||||
$.error(`IP Flag only supports Loon and Surge!`);
|
||||
}
|
||||
return proxies;
|
||||
}
|
||||
|
||||
const tasks = new Map();
|
||||
async function queryIpApi(proxy) {
|
||||
const id = getId(proxy);
|
||||
if (tasks.has(id)) {
|
||||
return tasks.get(id);
|
||||
}
|
||||
|
||||
const ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:78.0) Gecko/20100101 Firefox/78.0";
|
||||
const headers = {
|
||||
"User-Agent": ua
|
||||
};
|
||||
const { isLoon } = $substore.env;
|
||||
const target = isLoon ? "Loon" : "Surge";
|
||||
const result = new Promise((resolve, reject) => {
|
||||
const cached = resourceCache.get(id);
|
||||
if (cached) {
|
||||
resolve(cached);
|
||||
}
|
||||
const url = `http://ip-api.com/json`;
|
||||
let node = ProxyUtils.produce([proxy], target);
|
||||
|
||||
// Loon 需要去掉节点名字
|
||||
if (isLoon) {
|
||||
const s = node.indexOf("=");
|
||||
node = node.substring(s + 1);
|
||||
}
|
||||
|
||||
$.http.get({
|
||||
url,
|
||||
headers,
|
||||
node
|
||||
}).then(resp => {
|
||||
const body = resp.body;
|
||||
const data = JSON.parse(body);
|
||||
if (data.status === "success") {
|
||||
resourceCache.set(id, data.countryCode);
|
||||
resolve(data.countryCode);
|
||||
} else {
|
||||
reject(new Error(data.message));
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
tasks.set(id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getId(proxy) {
|
||||
return MD5(`IP-FLAG-${proxy.server}-${proxy.port}`);
|
||||
}
|
||||
|
||||
function getFlagEmoji(countryCode) {
|
||||
const codePoints = countryCode
|
||||
.toUpperCase()
|
||||
.split('')
|
||||
.map(char => 127397 + char.charCodeAt());
|
||||
return String
|
||||
.fromCodePoint(...codePoints)
|
||||
.replace(/🇹🇼/g, '🇨🇳');
|
||||
}
|
||||
|
||||
function removeFlag(str) {
|
||||
return str
|
||||
.replace(/[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF]/g, '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
var MD5 = function (d) { var r = M(V(Y(X(d), 8 * d.length))); return r.toLowerCase() }; function M(d) { for (var _, m = "0123456789ABCDEF", f = "", r = 0; r < d.length; r++)_ = d.charCodeAt(r), f += m.charAt(_ >>> 4 & 15) + m.charAt(15 & _); return f } function X(d) { for (var _ = Array(d.length >> 2), m = 0; m < _.length; m++)_[m] = 0; for (m = 0; m < 8 * d.length; m += 8)_[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32; return _ } function V(d) { for (var _ = "", m = 0; m < 32 * d.length; m += 8)_ += String.fromCharCode(d[m >> 5] >>> m % 32 & 255); return _ } function Y(d, _) { d[_ >> 5] |= 128 << _ % 32, d[14 + (_ + 64 >>> 9 << 4)] = _; for (var m = 1732584193, f = -271733879, r = -1732584194, i = 271733878, n = 0; n < d.length; n += 16) { var h = m, t = f, g = r, e = i; f = md5_ii(f = md5_ii(f = md5_ii(f = md5_ii(f = md5_hh(f = md5_hh(f = md5_hh(f = md5_hh(f = md5_gg(f = md5_gg(f = md5_gg(f = md5_gg(f = md5_ff(f = md5_ff(f = md5_ff(f = md5_ff(f, r = md5_ff(r, i = md5_ff(i, m = md5_ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = md5_ff(r, i = md5_ff(i, m = md5_ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = md5_ff(r, i = md5_ff(i, m = md5_ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = md5_ff(r, i = md5_ff(i, m = md5_ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = md5_gg(r, i = md5_gg(i, m = md5_gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = md5_gg(r, i = md5_gg(i, m = md5_gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = md5_gg(r, i = md5_gg(i, m = md5_gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = md5_gg(r, i = md5_gg(i, m = md5_gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = md5_hh(r, i = md5_hh(i, m = md5_hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = md5_hh(r, i = md5_hh(i, m = md5_hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = md5_hh(r, i = md5_hh(i, m = md5_hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = md5_hh(r, i = md5_hh(i, m = md5_hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = md5_ii(r, i = md5_ii(i, m = md5_ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = md5_ii(r, i = md5_ii(i, m = md5_ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = md5_ii(r, i = md5_ii(i, m = md5_ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = md5_ii(r, i = md5_ii(i, m = md5_ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = safe_add(m, h), f = safe_add(f, t), r = safe_add(r, g), i = safe_add(i, e) } return Array(m, f, r, i) } function md5_cmn(d, _, m, f, r, i) { return safe_add(bit_rol(safe_add(safe_add(_, d), safe_add(f, i)), r), m) } function md5_ff(d, _, m, f, r, i, n) { return md5_cmn(_ & m | ~_ & f, d, _, r, i, n) } function md5_gg(d, _, m, f, r, i, n) { return md5_cmn(_ & f | m & ~f, d, _, r, i, n) } function md5_hh(d, _, m, f, r, i, n) { return md5_cmn(_ ^ m ^ f, d, _, r, i, n) } function md5_ii(d, _, m, f, r, i, n) { return md5_cmn(m ^ (_ | ~f), d, _, r, i, n) } function safe_add(d, _) { var m = (65535 & d) + (65535 & _); return (d >> 16) + (_ >> 16) + (m >> 16) << 16 | 65535 & m } function bit_rol(d, _) { return d << _ | d >>> 32 - _ }
|
||||
Reference in New Issue
Block a user