登录监控的一些方法

定义一个接口,声明一个方法,返回一个tuple,表示某一项是否存在风险

trait RiskEvaluate {
  /**
    * @param currentValue 当前评估值
    * @param historyValue 历史评估值
    * @return
    */
  def evaluate(currentValue:Any,historyValue:Any):(String,Boolean)
}

写一个类,继承RiskEvaluate接口,覆盖接口方法,表示输入习惯(输入向量)是否存在异常

package com.evaluate.impl

import com.baizhi.evaluate.RiskEvaluate

import scala.collection.mutable.ListBuffer

class InputVectorEvaluate extends RiskEvaluate{
  /**
    *
    * @param currentInputVector:当前输入向量
    * @param historyVector:历史输入向量数组
    * @return
    */
  def doEvaluate(currentInputVector: Array[Double], historyVector: ListBuffer[Array[Double]]): (String, Boolean) = {

    var n=historyVector.length
    if(n<2){
      return ("FORM_INPUT",false)
    }
    //计算平均向量
    var avgVector=new Array[Double](currentInputVector.length)
    for(i <- 0 until  currentInputVector.length ){
      avgVector(i) = historyVector.map(v=>v(i)).reduce(_+_)/historyVector.length
    }
    //n个历史向量间 彼此距离
    var distances=new ListBuffer[Double]
    for(i<- historyVector ;j <- historyVector;if(i!=j)){ //任意两个点坐标的距离
       //必须保证 i!=j 计算 i和j的距离
       var total:Double=0
       for( item<- 0 until avgVector.length){
         total+=  Math.pow((i(item)-j(item)),2)
       }
      //添加距离
       distances += Math.sqrt(total)
      //将向量从historyVector中移除
      historyVector -= i
    }
    //对distances结果进行排序
    distances=distances.sortBy(distance=>distance)

    //计算当前输入向量和平均向量的距离
    var curentDistance:Double=0
    for( item<- 0 until avgVector.length){
      curentDistance+=  Math.pow((avgVector(item)-currentInputVector(item)),2)
    }
    curentDistance=Math.sqrt(curentDistance)
    
	//获取比对阈值
    var  threshold: Double = distances((n * (n - 1))/6)

    println("距离:"+distances.map(t=>t+"").reduce(_+","+_))
    println("avgVector:"+avgVector.map(t=>t+"").reduce(_+","+_))
    println("currentInputVector:"+currentInputVector.map(t=>t+"").reduce(_+","+_))
    println("threshold: "+threshold+" curentDistance: "+curentDistance)

    return  ("FORM_INPUT",curentDistance>threshold)
  }
  override def evaluate(v1: Any, v2: Any): (String, Boolean) = {
    doEvaluate(v1.asInstanceOf[Array[Double]],v2.asInstanceOf[ListBuffer[Array[Double]]])
  }
}

写一个类,继承RiskEvaluate接口,覆盖接口方法,表示密码重试是否存在异常(根据历史密码词袋判断)
通过计算用户当前密码和历史密码做余弦相似度计算,计算出当前向量之间的夹角,通过向量夹角评估用户的输入是否存在异常。
在这里插入图片描述在这里插入图片描述

package com.evaluate.impl

import java.util

import com.baizhi.evaluate.RiskEvaluate

import scala.collection.mutable.ListBuffer

class PasswordEvaluate extends RiskEvaluate{



  /**
    *
    * @param currentPawssword:当前输入向量
    * @param historyPasswords:历史输入向量数组
    * @return
    */
  def doEvaluate(currentPawssword: String, historyPasswords: ListBuffer[String]): (String, Boolean) = {
    val wordBag = historyPasswords.flatMap(password=> password.toCharArray).distinct.toList.sortBy(c=>c)
    println("词袋:"+wordBag.mkString(","))
    var historyPwddwordVectors=new ListBuffer[Array[Int]]
    for(pwd<-historyPasswords){
      val vector = convertString2Vectors(wordBag,pwd)
      historyPwddwordVectors += vector
    }
    val currentVector = convertString2Vectors(wordBag,currentPawssword)
    var simlarity:Double=0.0
    for(v <- historyPwddwordVectors){
      var s:Double=calculateSimlarity(currentVector,v)
      println("s:"+s)
      if(s>simlarity){ //获取自大相似度
        simlarity=s
      }
    }
    if(simlarity < 0.95){
      return  ("PASSWORD_INPUT",true)
    }
    return ("FORM_INPUT",false)
  }
  private  def calculateSimlarity(c: Array[Int], v: Array[Int]): Double = {
       var vectorMutli=0.0
       for(i <- 0 until c.length){
         vectorMutli +=c(i)*v(i)
       }
       return vectorMutli/(Math.sqrt(c.map(item=>item*item).reduce(_+_))* Math.sqrt(v.map(item=>item*item).reduce(_+_)))
  }
  private def convertString2Vectors(wordBag:List[Char],pwd:String):Array[Int]={
      val charMap = new util.HashMap[Char,Int]()
      for(c<-pwd.toCharArray){
        if(charMap.containsKey(c)){
          charMap.put(c,charMap.get(c)+1)
        }else{
          charMap.put(c,1)
        }
      }
      val vector = new Array[Int](wordBag.length)
      for(i <- 0 until wordBag.length){
        var count=0
        if(charMap.containsKey(wordBag(i))){
          count=charMap.get(wordBag(i))
        }else{
          count=0
        }
        vector(i)=count
      }
      vector
  }

  override def evaluate(v1: Any, v2: Any): (String, Boolean) = {
    doEvaluate(v1.asInstanceOf[String],v2.asInstanceOf[ListBuffer[String]])
  }
}

写一个类,继承RiskEvaluate接口,覆盖接口方法,表示登录地是否存在异常

package com.evaluate.impl
import com.baizhi.evaluate.{Location, RiskEvaluate}
class LoginLocationEvaluate extends RiskEvaluate{

  def doEvaluate(currentLogin: Location, lastLogin: Location): (String, Boolean) = {
    var distance=getDistanceOfMeter(currentLogin.latitude,currentLogin.longtitude,lastLogin.latitude,lastLogin.longtitude)
    var speed=distance/((currentLogin.timestamp-lastLogin.timestamp)*1.0/(1000*3600))
    println("speed:"+speed)
    return ("FORM_INPUT",speed>310)
  }

  def getDistanceOfMeter(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double = {
      val a = rad(lat1) - rad(lat2)
      val b = rad(lng1) - rad(lng2)
      println(a+" "+b)
      var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos( rad(lat1)) * Math.cos( rad(lat2)) * Math.pow(Math.sin(b / 2), 2)))
      println(s)
      s = s * EARTH_RADIUS
      s = Math.round(s * 10000) / 10000;
      return s
  }

  private def rad(d: Double) = d * Math.PI / 180.0

  /**
    * 地球半径:6378.137KM
    */
  private val EARTH_RADIUS = 6378.137

  override def evaluate(v1: Any, v2: Any): (String, Boolean) = {
    doEvaluate(v1.asInstanceOf[Location],v2.asInstanceOf[Location])
  }
}

写一个类,继承RiskEvaluate接口,覆盖接口方法,表示登陆设备是否不一致

package com.evaluate.impl

import java.util
import com.baizhi.evaluate.RiskEvaluate
import scala.collection.mutable.ListBuffer

class AgentEvaluate extends RiskEvaluate{
  /**
    *
    * @param lastAgent:当前输入向量
    * @param lastAgents:历史输入向量数组
    * @return
    */
  def doEvaluate(lastAgent: String, lastAgents: ListBuffer[String]): (String, Boolean) = {
    return ("AGENT_INPUT",lastAgents.indexOf(lastAgent) == -1)
  }

  override def evaluate(v1: Any, v2: Any): (String, Boolean) = {
    doEvaluate(v1.asInstanceOf[String],v2.asInstanceOf[ListBuffer[String]])
  }
}

Location类

package com.evaluate

import org.apache.kafka.common.record.TimestampType
// la 纬度 lon经度         //纬度			//经度    //时间              
case class Location(latitude:Double,longtitude:Double,timestamp:Long)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值