feat:zlb接口
This commit is contained in:
117
src/main/java/com/xiang/common/utils/ZlbCaptchaTrackUtil.java
Normal file
117
src/main/java/com/xiang/common/utils/ZlbCaptchaTrackUtil.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.xiang.common.utils;
|
||||
|
||||
import com.xiang.common.pojo.jntyzx.zlb.ZlbOrderInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 浙里办验证码轨迹生成工具。
|
||||
*/
|
||||
public class ZlbCaptchaTrackUtil {
|
||||
|
||||
private ZlbCaptchaTrackUtil() {
|
||||
}
|
||||
|
||||
public static List<ZlbOrderInfo.ZlbData.TrackList> generateBezierTrackList(List<String> trackList) {
|
||||
List<ZlbOrderInfo.ZlbData.TrackList> result = new ArrayList<>();
|
||||
if (trackList == null || trackList.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 0; i < trackList.size(); i++) {
|
||||
int[] currentPoint = parseTrackCoordinate(trackList.get(i));
|
||||
int clickTime = result.isEmpty()
|
||||
? randomBetween(1800, 2200)
|
||||
: result.get(result.size() - 1).getT() + randomBetween(25, 60);
|
||||
result.add(buildTrackPoint(currentPoint[0], currentPoint[1], clickTime, "click"));
|
||||
|
||||
if (i < trackList.size() - 1) {
|
||||
int[] nextPoint = parseTrackCoordinate(trackList.get(i + 1));
|
||||
int moveStartTime = result.get(result.size() - 1).getT();
|
||||
int moveDuration = randomBetween(800, 1200);
|
||||
List<int[]> movePoints = buildBezierMovePoints(currentPoint[0], currentPoint[1], nextPoint[0], nextPoint[1]);
|
||||
for (int moveIndex = 0; moveIndex < movePoints.size(); moveIndex++) {
|
||||
int[] movePoint = movePoints.get(moveIndex);
|
||||
int moveTime = moveStartTime + (int) Math.round((double) moveDuration * (moveIndex + 1) / (movePoints.size() + 1));
|
||||
result.add(buildTrackPoint(movePoint[0], movePoint[1], moveTime, "move"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> parseCoordinateText(String coordinateText) {
|
||||
if (coordinateText == null || coordinateText.trim().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String normalized = coordinateText.replace("\n", "|").replace(";", "|");
|
||||
String[] parts = normalized.split("\\|");
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String part : parts) {
|
||||
if (part != null && !part.trim().isEmpty()) {
|
||||
result.add(part.trim());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] parseTrackCoordinate(String track) {
|
||||
String[] coordinateArr = track.split(",");
|
||||
return new int[]{
|
||||
Integer.parseInt(coordinateArr[0].trim()),
|
||||
Integer.parseInt(coordinateArr[1].trim())
|
||||
};
|
||||
}
|
||||
|
||||
private static List<int[]> buildBezierMovePoints(int fromX, int fromY, int toX, int toY) {
|
||||
int movePointCount = randomBetween(3, 5);
|
||||
double dx = toX - fromX;
|
||||
double dy = toY - fromY;
|
||||
double distance = Math.max(1d, Math.hypot(dx, dy));
|
||||
double normalX = -dy / distance;
|
||||
double normalY = dx / distance;
|
||||
double direction = ThreadLocalRandom.current().nextBoolean() ? 1d : -1d;
|
||||
double offset = Math.min(28d, Math.max(6d, distance * ThreadLocalRandom.current().nextDouble(0.08d, 0.22d))) * direction;
|
||||
double controlX = (fromX + toX) / 2d + normalX * offset;
|
||||
double controlY = (fromY + toY) / 2d + normalY * offset;
|
||||
|
||||
List<int[]> movePoints = new ArrayList<>(movePointCount);
|
||||
for (int i = 1; i <= movePointCount; i++) {
|
||||
double progress = easeInOutCubic((double) i / (movePointCount + 1));
|
||||
int x = (int) Math.round(
|
||||
Math.pow(1 - progress, 2) * fromX
|
||||
+ 2 * (1 - progress) * progress * controlX
|
||||
+ Math.pow(progress, 2) * toX
|
||||
);
|
||||
int y = (int) Math.round(
|
||||
Math.pow(1 - progress, 2) * fromY
|
||||
+ 2 * (1 - progress) * progress * controlY
|
||||
+ Math.pow(progress, 2) * toY
|
||||
);
|
||||
movePoints.add(new int[]{x, y});
|
||||
}
|
||||
return movePoints;
|
||||
}
|
||||
|
||||
private static double easeInOutCubic(double value) {
|
||||
return value < 0.5d
|
||||
? 4d * value * value * value
|
||||
: 1d - Math.pow(-2d * value + 2d, 3d) / 2d;
|
||||
}
|
||||
|
||||
private static ZlbOrderInfo.ZlbData.TrackList buildTrackPoint(int x, int y, int t, String type) {
|
||||
ZlbOrderInfo.ZlbData.TrackList data = new ZlbOrderInfo.ZlbData.TrackList();
|
||||
data.setX(x);
|
||||
data.setY(y);
|
||||
data.setT(t);
|
||||
data.setType(type);
|
||||
return data;
|
||||
}
|
||||
|
||||
private static int randomBetween(int minInclusive, int maxInclusive) {
|
||||
return ThreadLocalRandom.current().nextInt(minInclusive, maxInclusive + 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user