用户登录风险之表单输入特征评估

概述

用户在填写登陆表单时,每次输入用户名密码或者验证码的所花费的时间是存在一定的规律的。多次正常输入在二维坐标系(用户名,密码),会呈现一个圆形,三维坐标系(用户名,密码,验证码)则会呈现一个球形,多维则亦然。
评估当前用户输入如果不在正常输入范围内,则说明此次登陆存在一定的风险。

计算步骤:

  • 1.计算圆⼼中点
  • 2.计算两两特征距离
  • 3.对距离进⾏排序(升序),取2/3处作为评估距离阈值 - threshold
  • 4.计算当前输⼊的特征距离中⼼点距离d

数学公式

欧氏距离
在这里插入图片描述
n点两两组合

  • n(n-1)/2

数据支持

评估数据

  • 1.用户当前登录的输入特性(每个控件输入时间ms)
  • 2.用户历史输入特性(最多留存最近10条数据)

java代码示例:

/**
 * 用户登陆输入特性
 */
public class FeatureEvaluate {

    /**
     * 1.计算圆⼼中点
     * 2.计算两两特征距离
     * 3.对距离进⾏排序(升序),取2/3处作为评估距离阈值 - threshold
     * 4.计算当前输⼊的特征距离中⼼点距离d
     * @param loginFeature 登陆特性
     * @param historyFeature 历史输入特性
     * @return 有风险,true
     */
    public Boolean doEval(Double[] loginFeature, List<Double[]> historyFeature){
        //保证历史数据至少有两条
        if(historyFeature == null || historyFeature.size() < 2)
            return false;
        //1.计算圆心,所有坐标均值
        List<Double> centerVector = Arrays.stream(historyFeature.stream()
                .reduce((v1, v2) -> {
                    Double[] sum = new Double[v1.length];//历史数据每个维度的总和数组
                    for (int i = 0; i < v1.length; i++) {
                        if (sum[i] == null)
                            sum[i] = 0.0;
                        sum[i] += v1[i] + v2[i];
                    }
                    return sum;
                }).get())//所有坐标值的和
                .map(s -> (s * 1.0) / historyFeature.size())
                .collect(Collectors.toList());
        //圆心字符串形式
        String strCenterVector = String.join(",", centerVector.stream()
                .map(s -> s + "")
                .collect(Collectors.toList()));
        System.out.println("圆心:"+strCenterVector);//展示圆心
        //2.计算两两特性距离
        List<Double> distanceList = new ArrayList<>();
        for (int i = 0; i < historyFeature.size(); i++) {
            for (int j = i + 1; j < historyFeature.size(); j++) {
                distanceList.add(distance(historyFeature.get(i),historyFeature.get(j)));
            }
        }
        System.out.println("两两距离:"+distanceList);//展示距离
        //3.对距离进⾏排序(升序),取2/3处作为评估距离阈值 - threshold
        List<Double> sortedDistanceList = distanceList.stream()
                .sorted()
                .collect(Collectors.toList());
        Double thresholdDistance = sortedDistanceList.get(sortedDistanceList.size() * 2 / 3);
        System.out.println("半径:" + thresholdDistance);
        //4.计算当前输入特性与圆心的距离
        Double distance = distance(loginFeature, centerVector.toArray(new Double[0]));
        System.out.println("当前输入与圆心的距离:" + distance);
        return distance > thresholdDistance;
    }

    /**
     * 计算两点距离
     * @param v1
     * @param v2
     * @return
     */
    public Double distance(Double[] v1,Double[] v2){
        Double sum = 0.0;
        for (int i = 0; i < v1.length; i++) {
            sum += (v1[i] - v2[i]) * (v1[i] - v2[i]);
        }
        return Math.sqrt(sum);
    }

    //测试
    public static void main(String[] args) {
        FeatureEvaluate inputFeatureEvaluate = new FeatureEvaluate();
        ArrayList<Double[]> latestInputFeatures = new ArrayList<>();
        latestInputFeatures.add(new Double[]{1000.0,1100.0,1800.0});
        latestInputFeatures.add(new Double[]{1100.0,1120.0,1750.0});
        latestInputFeatures.add(new Double[]{950.0,1250.0,2000.0});
        latestInputFeatures.add(new Double[]{1200.0,1050.0,1900.0});
        latestInputFeatures.add(new Double[]{1400.0,800.0,2500.0});

        inputFeatureEvaluate.doEval(new Double[]{1100.0,1000.0,1750.0},latestInputFeatures);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值