mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-07-12 06:21:15 +00:00
Compare commits
5 Commits
v0.3.6
...
0754fe20f1
| Author | SHA1 | Date | |
|---|---|---|---|
| 0754fe20f1 | |||
| 034fd20d3b | |||
| 24bf98bca9 | |||
| 275f6b9e6d | |||
| 5db9e422f4 |
@@ -6,6 +6,9 @@ QQ交流群:1017480890
|
||||
<a href="https://vertx-china.github.io"><img src="https://img.shields.io/badge/vert.x-4.5.27-blue?style=flat"></a>
|
||||
<a href="https://raw.githubusercontent.com/qaiu/netdisk-fast-download/master/LICENSE"><img src="https://img.shields.io/github/license/qaiu/netdisk-fast-download?style=flat"></a>
|
||||
<a href="https://github.com/qaiu/netdisk-fast-download/releases/"><img src="https://img.shields.io/github/v/release/qaiu/netdisk-fast-download?style=flat"></a>
|
||||
<a href="https://github.com/QAIU/netdisk-fast-download">
|
||||
<img src="https://img.shields.io/github/stars/QAIU/netdisk-fast-download?style=flat&logo=github" alt="GitHub Stars">
|
||||
</a>
|
||||
<a href="https://atomgit.com/QAIU/netdisk-fast-download"><img src="https://atomgit.com/QAIU/netdisk-fast-download/star/badge.svg" alt="AtomGit"></a>
|
||||
<a href="https://oosmetrics.com/repo/qaiu/netdisk-fast-download"><img src="https://api.oosmetrics.com/api/v1/badge/achievement/826aa27a-6e59-4de5-b7fa-cd189f484035.svg"></a>
|
||||
<p align="center">
|
||||
@@ -16,10 +19,6 @@ QQ交流群:1017480890
|
||||

|
||||
|
||||
|
||||
## 国内镜像
|
||||
|
||||
本项目同步托管于 **AtomGit**,国内访问更流畅:👉 [https://atomgit.com/QAIU/netdisk-fast-download](https://atomgit.com/QAIU/netdisk-fast-download)
|
||||
|
||||
|
||||
## 介绍
|
||||
> netdisk-fast-download网盘直链解析可以把云盘分享链接转为直链,可广泛应用于各类下载站,资源站,个人博客,图床,APP下载更新,视频点播等领域。支持市面各大主流云盘的文件分享以及文件夹分享链接,已支持蓝奏云/蓝奏云优享/移动云云空间/小飞机盘/亿方云/123云盘/Cloudreve等,支持加密分享,以及部分网盘文件夹分享。
|
||||
@@ -40,12 +39,12 @@ curl -LOJ "https://lz.qaiu.top/parser?url=https://share.feijipan.com/s/Tk1F2kGQ&
|
||||
```shell
|
||||
wget -O bilibili.mp4 "https://lz.qaiu.top/parser?url=https://share.feijipan.com/s/Tk1F2kGQ&pwd=1234"
|
||||
```
|
||||
或者使用浏览器[直接访问](https://nfd-parser.github.io/nfd-preview/preview.html?src=https%3A%2F%2Flz.qaiu.top%2Fparser%3Furl%3Dhttps%3A%2F%2Fshare.feijipan.com%2Fs%2FTk1F2kGQ&name=bilibili.mp4&ext=mp4):
|
||||
或者使用浏览器[直接访问](https://nfd-parser.github.io/nfd-preview/preview.html?src=https%3A%2F%2Flz.qaiu.top%2Fparser%3Furl%3Dhttps%3A%2F%2Fwww.ilanzou.com%2Fs%2FCDx6xKbT&name=bilibili.mp4&ext=mp4):
|
||||
```
|
||||
### 调用演示站下载:
|
||||
https://lz.qaiu.top/parser?url=https://share.feijipan.com/s/Tk1F2kGQ&pwd=1234
|
||||
https://lz.qaiu.top/parser?url=https://www.ilanzou.com/s/CDx6xKbT&pwd=1234
|
||||
### 调用演示站预览:
|
||||
https://nfd-parser.github.io/nfd-preview/preview.html?src=https%3A%2F%2Flz.qaiu.top%2Fparser%3Furl%3Dhttps%3A%2F%2Fshare.feijipan.com%2Fs%2FTk1F2kGQ&name=bilibili.mp4&ext=mp4
|
||||
https://nfd-parser.github.io/nfd-preview/preview.html?src=https%3A%2F%2Flz.qaiu.top%2Fparser%3Furl%3Dhttps%3A%2F%2Fwww.ilanzou.com%2Fs%2FCDx6xKbT&name=bilibili.mp4&ext=mp4
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ public enum PanDomainTemplate {
|
||||
123795.com
|
||||
*/
|
||||
YE("123网盘",
|
||||
compile("https://www\\.(" +
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)*(" +
|
||||
"123254\\.com|" +
|
||||
"123957\\.com|" +
|
||||
"123295\\.com|" +
|
||||
@@ -232,7 +232,7 @@ public enum PanDomainTemplate {
|
||||
"123635\\.com|" +
|
||||
"123242\\.com|" +
|
||||
"123795\\.com" +
|
||||
")/s/(?<KEY>[a-zA-Z0-9_-]+)(?:\\.html)?"),
|
||||
")/(?:(?:s|123pan)/|(?:[^/?#]+/)+)?(?<KEY>[a-zA-Z0-9]+-[a-zA-Z0-9]+|[a-zA-Z0-9_-]+)(?:\\.html)?(?:\\?.*)?"),
|
||||
"https://www.123pan.com/s/{shareKey}",
|
||||
Ye2Tool.class),
|
||||
// https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={code}&isShare=1
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.qaiu.parser;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Parser token cache keyed by parser type and account identity.
|
||||
*/
|
||||
public final class TokenCache {
|
||||
|
||||
private static final Map<String, String> TOKENS = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Long> EXPIRES = new ConcurrentHashMap<>();
|
||||
|
||||
private TokenCache() {
|
||||
}
|
||||
|
||||
public static String key(String type, String accountId) {
|
||||
return type + ":" + (StringUtils.isBlank(accountId) ? "_default" : accountId);
|
||||
}
|
||||
|
||||
public static void putToken(String key, String token) {
|
||||
if (StringUtils.isBlank(key) || StringUtils.isBlank(token)) {
|
||||
return;
|
||||
}
|
||||
TOKENS.put(key, token);
|
||||
}
|
||||
|
||||
public static String getToken(String key) {
|
||||
if (StringUtils.isBlank(key)) {
|
||||
return null;
|
||||
}
|
||||
if (isExpired(key)) {
|
||||
TOKENS.remove(key);
|
||||
EXPIRES.remove(key);
|
||||
return null;
|
||||
}
|
||||
return TOKENS.get(key);
|
||||
}
|
||||
|
||||
public static void putExpire(String key, long expireTimeMillis) {
|
||||
if (StringUtils.isBlank(key)) {
|
||||
return;
|
||||
}
|
||||
EXPIRES.put(key, expireTimeMillis);
|
||||
}
|
||||
|
||||
public static boolean isExpired(String key) {
|
||||
Long expireTimeMillis = EXPIRES.get(key);
|
||||
return expireTimeMillis != null && System.currentTimeMillis() > expireTimeMillis;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
package cn.qaiu.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 123分享链接子域工具:将分享 key 的前半段解码为数字 uid。
|
||||
*/
|
||||
public final class YeShareHostUtil {
|
||||
|
||||
private static final String CODE62 = "Tvd3hHA9QEkom14xpfaBJIMwgFYGPXn2sWCNORDr80KuUSl7bZcetizL5q6yVj";
|
||||
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
|
||||
private static final Map<Character, Integer> DECODE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (int i = 0; i < CODE62.length(); i++) {
|
||||
DECODE_MAP.put(CODE62.charAt(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
private YeShareHostUtil() {
|
||||
}
|
||||
|
||||
public static String getNumericSubdomainIdByShareKey(String shareKey) {
|
||||
String normalized = normalizeShareKey(shareKey);
|
||||
if (StringUtils.isBlank(normalized)) {
|
||||
return "";
|
||||
}
|
||||
int split = normalized.indexOf('-');
|
||||
if (split <= 0) {
|
||||
return "";
|
||||
}
|
||||
String encodedUid = normalized.substring(0, split);
|
||||
Long uid = decodeBase62LittleEndian(encodedUid);
|
||||
return uid == null ? "" : String.valueOf(uid);
|
||||
}
|
||||
|
||||
public static String normalizeShareKey(String shareKey) {
|
||||
if (StringUtils.isBlank(shareKey)) {
|
||||
return "";
|
||||
}
|
||||
String key = shareKey.trim();
|
||||
int queryIndex = key.indexOf('?');
|
||||
if (queryIndex >= 0) {
|
||||
key = key.substring(0, queryIndex);
|
||||
}
|
||||
int slashIndex = key.lastIndexOf('/');
|
||||
if (slashIndex >= 0 && slashIndex < key.length() - 1) {
|
||||
key = key.substring(slashIndex + 1);
|
||||
}
|
||||
if (key.endsWith(".html")) {
|
||||
key = key.substring(0, key.length() - 5);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private static Long decodeBase62LittleEndian(String value) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return null;
|
||||
}
|
||||
long result = 0L;
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
Integer digit = DECODE_MAP.get(value.charAt(i));
|
||||
if (digit == null) {
|
||||
return null;
|
||||
}
|
||||
double weighted = digit * Math.pow(62, i);
|
||||
if (!Double.isFinite(weighted)) {
|
||||
return null;
|
||||
}
|
||||
long next = result + (long) weighted;
|
||||
if (next <= 0 || next > MAX_SAFE_INTEGER) {
|
||||
return null;
|
||||
}
|
||||
result = next;
|
||||
}
|
||||
if (result <= 0) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.qaiu.parser;
|
||||
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import cn.qaiu.util.YeShareHostUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -157,6 +158,26 @@ public class PanDomainTemplateTest {
|
||||
assertEquals("somekey", m5.group("KEY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testYeRedirectPatternAndUidDecode() {
|
||||
Pattern yePattern = PanDomainTemplate.YE.getPattern();
|
||||
|
||||
Matcher oldUrl = yePattern.matcher("https://www.123pan.com/s/lN7UVv-pbYJ");
|
||||
assertTrue("YE should match old 123pan share URL", oldUrl.find());
|
||||
assertEquals("lN7UVv-pbYJ", oldUrl.group("KEY"));
|
||||
|
||||
Matcher redirectedUrl = yePattern.matcher("https://1813382308.mshare.123pan.cn/123pan/lN7UVv-pbYJ");
|
||||
assertTrue("YE should match redirected mshare URL", redirectedUrl.find());
|
||||
assertEquals("lN7UVv-pbYJ", redirectedUrl.group("KEY"));
|
||||
|
||||
Matcher htmlUrl = yePattern.matcher("https://www.123278.com/s/lN7UVv-pbYJ.html?pwd=abcd");
|
||||
assertTrue("YE should match html URL with query", htmlUrl.find());
|
||||
assertEquals("lN7UVv-pbYJ", htmlUrl.group("KEY"));
|
||||
|
||||
assertEquals("1813382308", YeShareHostUtil.getNumericSubdomainIdByShareKey("lN7UVv-pbYJ"));
|
||||
assertEquals("lN7UVv-pbYJ", YeShareHostUtil.normalizeShareKey("https://1813382308.mshare.123pan.cn/123pan/lN7UVv-pbYJ?pwd=abcd"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLePatternFix() {
|
||||
Pattern lePattern = PanDomainTemplate.LE.getPattern();
|
||||
|
||||
Reference in New Issue
Block a user