添加蓝奏云优享解析支持

This commit is contained in:
qaiu
2024-01-28 15:26:22 +08:00
parent 257063bae3
commit 0a296cc937
8 changed files with 168 additions and 8 deletions

View File

@@ -9,7 +9,7 @@
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/qaiu/netdisk-fast-download)](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] 直链解析

View File

@@ -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

View File

@@ -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)) {

View 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}&timestamp={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();
}
}

View File

@@ -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用户要求产生字符串的长度

View File

@@ -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 {

View 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&timestamp=B11E6A597CB93B55D87A338AEDDFBE45&auth=8BF7415F1AA0BB02278336F3C11EBD0B25654EAAB68588D5E8C4974ACAD88935
###
#@no-redirect
https://api.ilanzou.com/unproved/file/redirect?downloadId=DC3D647979EE315935D1687834F05914&enable=1&devType=6&uuid=46vk1ImPHKt1Mr2cRu5wA&timestamp=90A417B68D70B35311FACC72EEE63291&auth=849E8A34873CA37147A5FE110912FCBF836D8BD5D37626FBCBD8A3F6F42A7A8B
###
#@no-redirect
https://dl.lanosso.com/disk/2024/01/28/9/14733029/1706414002788330.gz?attname=testgles.c&sign=9ef76e9a270dbe5e9401c8f4c2ae0d68&t=65b5f826

View File

@@ -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/