mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-15 11:53:02 +00:00
添加蓝奏云优享解析支持
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
[](https://github.com/qaiu/netdisk-fast-download/releases/tag/0.1.6-releases)
|
||||
|
||||
## 项目介绍
|
||||
网盘直链解析工具能把网盘分享下载链接转化为直链,已支持蓝奏云/奶牛快传/移动云云空间/小飞机盘/亿方云/123云盘等,支持私密分享。
|
||||
网盘直链解析工具能把网盘分享下载链接转化为直链,已支持蓝奏云/蓝奏云优享/奶牛快传/移动云云空间/小飞机盘/亿方云/123云盘等,支持私密分享。
|
||||
|
||||
|
||||
*重要声明:本项目仅供学习参考;请不要将此项目用于任何商业用途,否则可能带来严重的后果。*
|
||||
@@ -24,6 +24,9 @@
|
||||
- [蓝奏云 (lz)](https://pc.woozooo.com/)
|
||||
- [ ] 登录, 上传, 下载, 分享
|
||||
- [X] 直链解析
|
||||
- [蓝奏云优享 (iz)](https://https://www.ilanzou.com/)
|
||||
- [ ] 登录, 上传, 下载, 分享
|
||||
- [X] 直链解析
|
||||
- [奶牛快传 (cow)](https://cowtransfer.com/)
|
||||
- [ ] 登录, 上传, 下载, 分享
|
||||
- [X] 直链解析
|
||||
|
||||
@@ -5,6 +5,7 @@ for /f "delims=X" %%i in ('dir /b %LIB_DIR%\netdisk-fast-download.jar') do (
|
||||
set LAUNCH_JAR=%LIB_DIR%%%i
|
||||
)
|
||||
|
||||
set "JAVA_HOME=D:\App\dragonwell-17.0.3.0.3+7-GA"
|
||||
"%JAVA_HOME%\bin\java.exe" -Xmx512M -Dfile.encoding=utf8 -jar %LAUNCH_JAR% %*
|
||||
|
||||
pause
|
||||
|
||||
@@ -19,6 +19,7 @@ public interface IPanTool {
|
||||
case "le" -> new LeTool(key, pwd);
|
||||
case "ws" -> new WsTool(key, pwd);
|
||||
case "qq" -> new QQTool(key, pwd);
|
||||
case "iz" -> new IzTool(key, pwd);
|
||||
default -> {
|
||||
throw new UnsupportedOperationException("未知分享类型");
|
||||
}
|
||||
@@ -39,6 +40,8 @@ public interface IPanTool {
|
||||
return new YeTool(url, pwd);
|
||||
} else if (url.startsWith(FjTool.SHARE_URL_PREFIX) || url.startsWith(FjTool.SHARE_URL_PREFIX2)) {
|
||||
return new FjTool(url, pwd);
|
||||
} else if (url.startsWith(IzTool.SHARE_URL_PREFIX)) {
|
||||
return new IzTool(url, pwd);
|
||||
} else if (url.contains(LzTool.LINK_KEY)) {
|
||||
return new LzTool(url, pwd);
|
||||
} else if (url.startsWith(LeTool.SHARE_URL_PREFIX)) {
|
||||
|
||||
78
parser/src/main/java/cn/qaiu/parser/impl/IzTool.java
Normal file
78
parser/src/main/java/cn/qaiu/parser/impl/IzTool.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package cn.qaiu.parser.impl;
|
||||
|
||||
import cn.qaiu.parser.IPanTool;
|
||||
import cn.qaiu.parser.PanBase;
|
||||
import cn.qaiu.util.AESUtils;
|
||||
import cn.qaiu.util.CommonUtils;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.MultiMap;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
import io.vertx.uritemplate.UriTemplate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 小飞机网盘
|
||||
*
|
||||
* @version V016_230609
|
||||
*/
|
||||
public class IzTool extends PanBase implements IPanTool {
|
||||
|
||||
public static final String SHARE_URL_PREFIX = "https://www.ilanzou.com/s/";
|
||||
private static final String API_URL_PREFIX = "https://api.ilanzou.com/unproved/";
|
||||
|
||||
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "recommend/list?devType=6&devModel=Chrome&extra" +
|
||||
"=2&shareId={shareId}&type=0&offset=1&limit=60";
|
||||
|
||||
private static final String SECOND_REQUEST_URL = API_URL_PREFIX + "file/redirect?downloadId={fidEncode}&enable=1" +
|
||||
"&devType=6&uuid={uuid}×tamp={ts}&auth={auth}";
|
||||
|
||||
public IzTool(String key, String pwd) {
|
||||
super(key, pwd);
|
||||
}
|
||||
|
||||
public Future<String> parse() {
|
||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
||||
|
||||
WebClient client = clientNoRedirects;
|
||||
String shareId = String.valueOf(AESUtils.idEncryptIz(dataKey));
|
||||
|
||||
// 第一次请求 获取文件信息
|
||||
// POST https://api.feijipan.com/ws/recommend/list?devType=6&devModel=Chrome&extra=2&shareId=146731&type=0&offset=1&limit=60
|
||||
client.postAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("shareId", shareId).send().onSuccess(res -> {
|
||||
JsonObject resJson = res.bodyAsJsonObject();
|
||||
if (resJson.getInteger("code") != 200) {
|
||||
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
||||
return;
|
||||
}
|
||||
if (resJson.getJsonArray("list").size() == 0) {
|
||||
fail(FIRST_REQUEST_URL + " 解析文件列表为空: " + resJson);
|
||||
return;
|
||||
}
|
||||
// 文件Id
|
||||
String fileId = resJson.getJsonArray("list").getJsonObject(0).getString("fileIds");
|
||||
// 其他参数
|
||||
long nowTs = System.currentTimeMillis();
|
||||
String tsEncode = AESUtils.encrypt2HexIz(Long.toString(nowTs));
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String fidEncode = AESUtils.encrypt2HexIz(fileId + "|");
|
||||
String auth = AESUtils.encrypt2HexIz(fileId + "|" + nowTs);
|
||||
// 第二次请求
|
||||
client.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
||||
.setTemplateParam("fidEncode", fidEncode)
|
||||
.setTemplateParam("uuid", uuid)
|
||||
.setTemplateParam("ts", tsEncode)
|
||||
.setTemplateParam("auth", auth).send().onSuccess(res2 -> {
|
||||
MultiMap headers = res2.headers();
|
||||
if (!headers.contains("Location")) {
|
||||
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res.headers());
|
||||
return;
|
||||
}
|
||||
promise.complete(headers.get("Location"));
|
||||
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
||||
}).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,10 @@ public class AESUtils {
|
||||
|
||||
public static final String CIPHER_AES2 = "YbQHZqK/PdQql2+7ATcPQHREAxt0Hn0Ob9v317QirZM=";
|
||||
|
||||
public static final String CIPHER_AES2_IZ = "1uQFS3sNeHd/bCrmrQpflXREAxt0Hn0Ob9v317QirZM=";
|
||||
|
||||
public static final String CIPHER_AES0;
|
||||
public static final String CIPHER_AES0_IZ;
|
||||
|
||||
/**
|
||||
* 秘钥长度
|
||||
@@ -59,6 +62,7 @@ public class AESUtils {
|
||||
static {
|
||||
try {
|
||||
CIPHER_AES0 = decryptByBase64AES(CIPHER_AES2, CIPHER_AES);
|
||||
CIPHER_AES0_IZ = decryptByBase64AES(CIPHER_AES2_IZ, CIPHER_AES);
|
||||
} catch (IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException | NoSuchAlgorithmException |
|
||||
InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -154,6 +158,15 @@ public class AESUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String encrypt2HexIz(String source) {
|
||||
try {
|
||||
return encryptHexByAES(source, CIPHER_AES0_IZ);
|
||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException |
|
||||
BadPaddingException e) {
|
||||
throw new RuntimeException("加密失败: "+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
*
|
||||
@@ -214,10 +227,14 @@ public class AESUtils {
|
||||
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'L', 'R', 'S', 'I',
|
||||
'J', 'K'};
|
||||
|
||||
private static int decodeChar(char c) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (c == array[i]) {
|
||||
private static final char[] arrayIz =
|
||||
{'Y', 'y', '0', 'Z', 'z', 'N', 'n', 'M', 'I', '6', 'm', 'W', 'w', '1', 'X', 'x', 'L', 'l', 'K', '7', 'k',
|
||||
'i', 'U', 'u', '2', 'V', 'v', 'J', 'j', '8', 'G', 'g', 'F', 'S', 's', '3', 'T', 't', 'H', 'h',
|
||||
'f', 'E', 'e', 'D', 'Q', 'q', '4', 'R', 'r', '9', 'd', 'a', 'C', 'c', 'B', 'O', 'o', '5', 'P',
|
||||
'p', 'b', 'A'};
|
||||
private static int decodeChar(char c, char[] keys) {
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
if (c == keys[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -226,21 +243,46 @@ public class AESUtils {
|
||||
|
||||
// id解密
|
||||
public static int idEncrypt(String str) {
|
||||
return idEncrypt0(str, array, 2, 2);
|
||||
}
|
||||
|
||||
// ================================蓝奏优享版Id解密========================================== //
|
||||
public static int idEncryptIz(String str) {
|
||||
// idEncrypt(e) {
|
||||
// let t = 1
|
||||
// , n = 0;
|
||||
// if ("" != e && e.length > 4) {
|
||||
// let r;
|
||||
// e = e.substring(3, e.length - 1);
|
||||
// for (let v = 0; v < e.length; v++)
|
||||
// r = e.charAt(e.length - v - 1),
|
||||
// n += this.decodeChar(r) * t,
|
||||
// t *= 62
|
||||
// }
|
||||
// return n
|
||||
// },
|
||||
|
||||
return idEncrypt0(str, arrayIz, 3, 1);
|
||||
}
|
||||
|
||||
public static int idEncrypt0(String str, char[] keys, int x1, int x2) {
|
||||
// 倍数
|
||||
int multiple = 1;
|
||||
int result = 0;
|
||||
if (StringUtils.isNotEmpty(str) && str.length() > 4) {
|
||||
str = str.substring(2, str.length() - 2);
|
||||
str = str.substring(x1, str.length() - x2);
|
||||
char c;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
c = str.charAt(str.length() - i - 1);
|
||||
result += decodeChar(c) * multiple;
|
||||
result += decodeChar(c, keys) * multiple;
|
||||
multiple = multiple * 62;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ========================== musetransfer加密相关 ===========================
|
||||
|
||||
//length用户要求产生字符串的长度
|
||||
|
||||
@@ -50,6 +50,12 @@ public class TestAESUtil {
|
||||
Assert.assertEquals(146731, AESUtils.idEncrypt("7jy0zlv"));
|
||||
}
|
||||
|
||||
// 蓝奏优享
|
||||
@Test
|
||||
public void testIzIdDecode() {
|
||||
Assert.assertEquals(26216, AESUtils.idEncryptIz("lGFndCM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test00() throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException,
|
||||
NoSuchAlgorithmException, InvalidKeyException {
|
||||
|
||||
18
web-service/src/main/resources/http-tools/pan-iz.http
Normal file
18
web-service/src/main/resources/http-tools/pan-iz.http
Normal file
@@ -0,0 +1,18 @@
|
||||
###
|
||||
POST https://api.ilanzou.com/unproved/recommend/list?shareId=26216
|
||||
|
||||
|
||||
###
|
||||
#@no-redirect
|
||||
https://api.ilanzou.com/unproved/file/redirect?downloadId=DC3D647979EE315935D1687834F05914&enable=1&devType=6&uuid=46vk1ImPHKt1Mr2cRu5wA×tamp=B11E6A597CB93B55D87A338AEDDFBE45&auth=8BF7415F1AA0BB02278336F3C11EBD0B25654EAAB68588D5E8C4974ACAD88935
|
||||
|
||||
###
|
||||
#@no-redirect
|
||||
https://api.ilanzou.com/unproved/file/redirect?downloadId=DC3D647979EE315935D1687834F05914&enable=1&devType=6&uuid=46vk1ImPHKt1Mr2cRu5wA×tamp=90A417B68D70B35311FACC72EEE63291&auth=849E8A34873CA37147A5FE110912FCBF836D8BD5D37626FBCBD8A3F6F42A7A8B
|
||||
|
||||
|
||||
|
||||
###
|
||||
#@no-redirect
|
||||
https://dl.lanosso.com/disk/2024/01/28/9/14733029/1706414002788330.gz?attname=testgles.c&sign=9ef76e9a270dbe5e9401c8f4c2ae0d68&t=65b5f826
|
||||
|
||||
@@ -4,11 +4,14 @@ GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/ia2cntg
|
||||
|
||||
### 蓝奏云
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/iNvid035jgcb
|
||||
GET http://127.0.0.1:6400/json/parser?url=https://wwsd.lanzoue.com/iLany1e9bbbi
|
||||
|
||||
### 蓝奏云
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/lz/i6SqHmp1yfc
|
||||
### 蓝奏云https://acgtools.lanzoui.com/iUr7Qnu3sxc https://wwn.lanzouy.com/tp/ihLkw1gezutg https://wwn.lanzouy.com/ihLkw1gezutg
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/lz/ihLkw1gezutg
|
||||
|
||||
### 蓝奏云
|
||||
# @no-redirect
|
||||
@@ -17,6 +20,12 @@ GET http://127.0.0.1:6400/lz/icBp6qqj82b@QAIU
|
||||
### 蓝奏云
|
||||
GET http://127.0.0.1:6400/json/lz/ia2cntg
|
||||
|
||||
### 蓝奏云优享
|
||||
GET http://127.0.0.1:6400/json/iz/lGFndCM
|
||||
|
||||
###
|
||||
GET http://127.0.0.1:6400/json/parser?url=https://www.ilanzou.com/s/lGFndCM
|
||||
|
||||
### 奶牛
|
||||
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
|
||||
Referer: https://cowtransfer.com/
|
||||
|
||||
Reference in New Issue
Block a user