Javascript 无Cookie或本地存储的用户识别

Javascript 无Cookie或本地存储的用户识别,javascript,php,http-headers,fingerprinting,Javascript,Php,Http Headers,Fingerprinting,我正在构建一个分析工具,目前我可以从用户代理获取用户的IP地址、浏览器和操作系统 我想知道是否有可能在不使用cookie或本地存储的情况下检测到相同的用户?我不期望这里有代码示例;这只是一个简单的提示,说明在哪里可以进一步查看 忘了提到,如果是同一台计算机/设备,则需要跨浏览器兼容。基本上,我追求的是设备识别,而不是真正的用户。这种技术(在没有cookie的情况下检测相同的用户,甚至没有ip地址)称为浏览器指纹识别。基本上,您可以尽可能地抓取有关浏览器的信息-使用javascript、flash

我正在构建一个分析工具,目前我可以从用户代理获取用户的IP地址、浏览器和操作系统

我想知道是否有可能在不使用cookie或本地存储的情况下检测到相同的用户?我不期望这里有代码示例;这只是一个简单的提示,说明在哪里可以进一步查看

忘了提到,如果是同一台计算机/设备,则需要跨浏览器兼容。基本上,我追求的是设备识别,而不是真正的用户。

这种技术(在没有cookie的情况下检测相同的用户,甚至没有ip地址)称为浏览器指纹识别。基本上,您可以尽可能地抓取有关浏览器的信息-使用javascript、flash或java(f.ex.安装的扩展、字体等)可以获得更好的结果。之后,如果需要,可以存储散列的结果

这不是绝对正确的,但是:

83.6%的浏览者有独特的指纹;在那些启用Flash或Java的用户中,94.2%。这不包括饼干

更多信息:


    • 简介

      如果我理解正确,您需要识别一个没有唯一标识符的用户,因此您希望通过匹配随机数据来确定他们是谁。您无法可靠地存储用户的身份,因为:

      • 可以删除Cookies
      • IP地址可以更改
      • 浏览器可以更改
      • 浏览器缓存可能会被删除
      Java小程序或Com对象本来是一个使用硬件信息散列的简单解决方案,但是现在人们非常安全,很难让人们在他们的系统上安装这些类型的程序。这让你不得不使用cookie和其他类似的工具

      Cookies和其他类似工具

      <>你可以考虑建立一个数据配置文件,然后使用概率测试来识别一个可能的用户。可通过以下组合生成对此有用的配置文件:

    • IP地址
      • 真实IP地址
      • 代理IP地址(用户经常重复使用同一个代理)
    • 饼干
      • HTTP Cookies
      • 会话Cookies
      • 第三方Cookies
      • Flash Cookies()
    • Web Bug(由于Bug得到修复,可靠性较低,但仍然有用)
      • PDF错误
      • 闪光虫
      • Java错误
    • 浏览器
      • 单击跟踪(许多用户每次访问同一系列页面)
      • 浏览器指纹 -已安装的插件(人们通常有各种各样的、有些独特的插件集)
      • 缓存图像(人们有时删除cookie,但保留缓存图像)
      • 使用水滴
      • URL(浏览器历史记录或cookie可能在URL中包含唯一的用户id,例如或)
      • (这是一个鲜为人知但通常是唯一的密钥签名)
    • HTML5和Javascript
      • HTML5地理定位API和反向地理编码
      • 体系结构、操作系统语言、系统时间、屏幕分辨率等
      • 网络信息API
      • 电池状态API
    • 当然,我列出的项目只是唯一识别用户的几种可能方式。还有很多

      使用这组随机数据元素来构建数据配置文件,下一步是什么?

      下一步是开发一些,或者更好的是,开发一个(使用模糊逻辑的)。在任何一种情况下,我们的想法都是训练您的系统,然后将其训练与提高结果的准确性相结合

      PHP库允许您生成人工神经网络。要实现贝叶斯推断,请查看以下链接:

      此时,您可能会想:

      为什么一个看似简单的任务需要这么多数学和逻辑?

      基本上,因为这不是一项简单的任务。事实上,你想要达到的是纯粹的概率。例如,给定以下已知用户:

      User1 = A + B + C + D + G + K
      User2 = C + D + I + J + K + F
      
      当您收到以下数据时:

      B + C + E + G + F + K
      
      你基本上要问的问题是:

      接收到的数据(B+C+E+G+F+K)实际上是User1或User2的概率是多少?这两个匹配中哪一个最有可能

      为了有效地回答这个问题,您需要理解为什么可能是更好的方法。这里的细节太多了(这就是我给你链接的原因),但是一个很好的例子是a,它使用症状的组合来识别可能的疾病

      将一系列数据点作为症状,将未知用户视为疾病,这些数据点构成您的数据配置文件(上例中的B+C+E+G+F+K)。通过识别疾病,您可以进一步确定适当的治疗方法(将此用户视为User1)

      显然,一种我们已经确定了不止一种症状的疾病更容易识别。事实上,我们能识别的症状越多,我们的诊断就越容易和准确

      还有其他选择吗?

      当然。作为一种替代措施,您可以创建自己的简单评分算法,并基于精确匹配。这不如概率效率高,但对您来说实现起来可能更简单

      作为一个例子,考虑这个简单的得分图表:

      +-------------------------+--------+------------+ | Property | Weight | Importance | +-------------------------+--------+------------+ | Real IP address | 60 | 5 | | Used proxy IP address | 40 | 4 | | HTTP Cookies | 80 | 8 | | Session Cookies | 80 | 6 | | 3rd Party Cookies | 60 | 4 | | Flash Cookies | 90 | 7 | | PDF Bug | 20 | 1 | | Flash Bug | 20 | 1 | | Java Bug | 20 | 1 | | Frequent Pages | 40 | 1 | | Browsers Finger Print | 35 | 2 | | Installed Plugins | 25 | 1 | | Cached Images | 40 | 3 | | URL | 60 | 4 | | System Fonts Detection | 70 | 4 | | Localstorage | 90 | 8 | | Geolocation | 70 | 6 | | AOLTR | 70 | 4 | | Network Information API | 40 | 3 | | Battery Status API | 20 | 1 | +-------------------------+--------+------------+ 打印“D”:

      echo "<pre>";
      print_r($matchs[0]);
      
      
      Profile Object(
          [name] => D
          [data] => Array (
              [Real IP address] => -1
              [Used proxy IP address] => -1
              [HTTP Cookies] => 1
              [Session Cookies] => 1
              [3rd Party Cookies] => 1
              [Flash Cookies] => 1
              [PDF Bug] => 1
              [Flash Bug] => 1
              [Java Bug] => -1
              [Frequent Pages] => 1
              [Browsers Finger Print] => -1
              [Installed Plugins] => 1
              [URL] => -1
              [Cached PNG] => 1
              [System Fonts Detection] => 1
              [Localstorage] => -1
              [Geolocation] => -1
              [AOLTR] => 1
              [Network Information API] => -1
              [Battery Status API] => -1
          )
          [score] => 0.74157303370787
          [diff] => 0.1685393258427
          [base] => 8.9
      )
      
      x1到x20表示由代码转换的特征

      class Profile {
          public $name, $data = array(), $score, $diff, $base;
      
          function __construct($name, array $importance) {
              $values = array(-1, 1); // Perception values
              $this->name = $name;
              foreach ($importance as $item => $point) {
                  // Generate Random true/false for real Items
                  $this->data[$item] = $values[mt_rand(0, 1)];
              }
              $this->base = array_sum($importance);
          }
      
          public function setScore($score, $diff) {
              $this->score = $score / $this->base;
              $this->diff = $diff / $this->base;
          }
      }
      
      这是一个

      使用的类:

      class Perceptron {
          private $w = array();
          private $dw = array();
          public $debug = false;
      
          private function initialize($colums) {
              // Initialize perceptron vars
              for($i = 1; $i <= $colums; $i ++) {
                  // weighting vars
                  $this->w[$i] = 0;
                  $this->dw[$i] = 0;
              }
          }
      
          function train($input, $alpha, $teta) {
              $colums = count($input[0]) - 1;
              $weightCache = array_fill(1, $colums, 0);
              $checkpoints = array();
              $keepTrainning = true;
      
              // Initialize RNA vars
              $this->initialize(count($input[0]) - 1);
              $just_started = true;
              $totalRun = 0;
              $yin = 0;
      
              // Trains RNA until it gets stable
              while ($keepTrainning == true) {
                  // Sweeps each row of the input subject
                  foreach ($input as $row_counter => $row_data) {
                      // Finds out the number of columns the input has
                      $n_columns = count($row_data) - 1;
      
                      // Calculates Yin
                      $yin = 0;
                      for($i = 1; $i <= $n_columns; $i ++) {
                          $yin += $row_data["x" . $i] * $weightCache[$i];
                      }
      
                      // Calculates Real Output
                      $Y = ($yin <= 1) ? - 1 : 1;
      
                      // Sweeps columns ...
                      $checkpoints[$row_counter] = 0;
                      for($i = 1; $i <= $n_columns; $i ++) {
                          /** DELTAS **/
                          // Is it the first row?
                          if ($just_started == true) {
                              $this->dw[$i] = $weightCache[$i];
                              $just_started = false;
                              // Found desired output?
                          } elseif ($Y == $row_data["o"]) {
                              $this->dw[$i] = 0;
                              // Calculates Delta Ws
                          } else {
                              $this->dw[$i] = $row_data["x" . $i] * $row_data["o"];
                          }
      
                          /** WEIGHTS **/
                          // Calculate Weights
                          $this->w[$i] = $this->dw[$i] + $weightCache[$i];
                          $weightCache[$i] = $this->w[$i];
      
                          /** CHECK-POINT **/
                          $checkpoints[$row_counter] += $this->w[$i];
                      } // END - for
      
                      foreach ($this->w as $index => $w_item) {
                          $debug_w["W" . $index] = $w_item;
                          $debug_dw["deltaW" . $index] = $this->dw[$index];
                      }
      
                      // Special for script debugging
                      $debug_vars[] = array_merge($row_data, array(
                          "Bias" => 1,
                          "Yin" => $yin,
                          "Y" => $Y
                      ), $debug_dw, $debug_w, array(
                          "deltaBias" => 1
                      ));
                  } // END - foreach
      
                  // Special for script debugging
                   $empty_data_row = array();
                  for($i = 1; $i <= $n_columns; $i ++) {
                      $empty_data_row["x" . $i] = "--";
                      $empty_data_row["W" . $i] = "--";
                      $empty_data_row["deltaW" . $i] = "--";
                  }
                  $debug_vars[] = array_merge($empty_data_row, array(
                      "o" => "--",
                      "Bias" => "--",
                      "Yin" => "--",
                      "Y" => "--",
                      "deltaBias" => "--"
                  ));
      
                  // Counts training times
                  $totalRun ++;
      
                  // Now checks if the RNA is stable already
                  $referer_value = end($checkpoints);
                  // if all rows match the desired output ...
                  $sum = array_sum($checkpoints);
                  $n_rows = count($checkpoints);
                  if ($totalRun > 1 && ($sum / $n_rows) == $referer_value) {
                      $keepTrainning = false;
                  }
              } // END - while
      
              // Prepares the final result
              $result = array();
              for($i = 1; $i <= $n_columns; $i ++) {
                  $result["w" . $i] = $this->w[$i];
              }
      
              $this->debug($this->print_html_table($debug_vars));
      
              return $result;
          } // END - train
          function testCase($input, $results) {
              // Sweeps input columns
              $result = 0;
              $i = 1;
              foreach ($input as $column_value) {
                  // Calculates teste Y
                  $result += $results["w" . $i] * $column_value;
                  $i ++;
              }
              // Checks in each class the test fits
              return ($result > 0) ? true : false;
          } // END - test_class
      
          // Returns the html code of a html table base on a hash array
          function print_html_table($array) {
              $html = "";
              $inner_html = "";
              $table_header_composed = false;
              $table_header = array();
      
              // Builds table contents
              foreach ($array as $array_item) {
                  $inner_html .= "<tr>\n";
                  foreach ( $array_item as $array_col_label => $array_col ) {
                      $inner_html .= "<td>\n";
                      $inner_html .= $array_col;
                      $inner_html .= "</td>\n";
      
                      if ($table_header_composed == false) {
                          $table_header[] = $array_col_label;
                      }
                  }
                  $table_header_composed = true;
                  $inner_html .= "</tr>\n";
              }
      
              // Builds full table
              $html = "<table border=1>\n";
              $html .= "<tr>\n";
              foreach ($table_header as $table_header_item) {
                  $html .= "<td>\n";
                  $html .= "<b>" . $table_header_item . "</b>";
                  $html .= "</td>\n";
              }
              $html .= "</tr>\n";
      
              $html .= $inner_html . "</table>";
      
              return $html;
          } // END - print_html_table
      
          // Debug function
          function debug($message) {
              if ($this->debug == true) {
                  echo "<b>DEBUG:</b> $message";
              }
          } // END - debug
      } // END - class
      
      修改的感知器类

      类感知器{ private$w=array(); private$dw=array(); public$debug=false; 私有函数初始化($colums){ //初始化感知器变量 对于($i=1;$i w[$i]=0; $this->dw[$i]=0; }
      +----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
      | o  | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15 | x16 | x17 | x18 | x19 | x20 | Bias | Yin | Y  | deltaW1 | deltaW2 | deltaW3 | deltaW4 | deltaW5 | deltaW6 | deltaW7 | deltaW8 | deltaW9 | deltaW10 | deltaW11 | deltaW12 | deltaW13 | deltaW14 | deltaW15 | deltaW16 | deltaW17 | deltaW18 | deltaW19 | deltaW20 | W1 | W2 | W3 | W4 | W5 | W6 | W7 | W8 | W9 | W10 | W11 | W12 | W13 | W14 | W15 | W16 | W17 | W18 | W19 | W20 | deltaBias |
      +----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
      | 1  | 1  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1    | 0   | -1 | 0       | -1      | -1      | -1      | -1      | -1      | -1      | 1       | 1       | 1        | 1        | 1        | 1        | 1        | -1       | -1       | -1       | -1       | 1        | 1        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
      | -1 | -1 | 1  | 1  | 1  | 1  | 1  | 1  | -1 | -1 | -1  | -1  | -1  | -1  | -1  | 1   | 1   | 1   | 1   | -1  | -1  | 1    | -19 | -1 | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
      | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --   | --  | -- | --      | --      | --      | --      | --      | --      | --      | --      | --      | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --        |
      | 1  | 1  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1    | 19  | 1  | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
      | -1 | -1 | 1  | 1  | 1  | 1  | 1  | 1  | -1 | -1 | -1  | -1  | -1  | -1  | -1  | 1   | 1   | 1   | 1   | -1  | -1  | 1    | -19 | -1 | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
      | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --   | --  | -- | --      | --      | --      | --      | --      | --      | --      | --      | --      | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --        |
      +----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
      
      // Get RNA Labels
      $labels = array();
      $n = 1;
      foreach ( $features as $k => $v ) {
          $labels[$k] = "x" . $n;
          $n ++;
      }
      
      class Profile {
          public $name, $data = array(), $score, $diff, $base;
      
          function __construct($name, array $importance) {
              $values = array(-1, 1); // Perception values
              $this->name = $name;
              foreach ($importance as $item => $point) {
                  // Generate Random true/false for real Items
                  $this->data[$item] = $values[mt_rand(0, 1)];
              }
              $this->base = array_sum($importance);
          }
      
          public function setScore($score, $diff) {
              $this->score = $score / $this->base;
              $this->diff = $diff / $this->base;
          }
      }
      
      class Perceptron {
          private $w = array();
          private $dw = array();
          public $debug = false;
      
          private function initialize($colums) {
              // Initialize perceptron vars
              for($i = 1; $i <= $colums; $i ++) {
                  // weighting vars
                  $this->w[$i] = 0;
                  $this->dw[$i] = 0;
              }
          }
      
          function train($input, $alpha, $teta) {
              $colums = count($input[0]) - 1;
              $weightCache = array_fill(1, $colums, 0);
              $checkpoints = array();
              $keepTrainning = true;
      
              // Initialize RNA vars
              $this->initialize(count($input[0]) - 1);
              $just_started = true;
              $totalRun = 0;
              $yin = 0;
      
              // Trains RNA until it gets stable
              while ($keepTrainning == true) {
                  // Sweeps each row of the input subject
                  foreach ($input as $row_counter => $row_data) {
                      // Finds out the number of columns the input has
                      $n_columns = count($row_data) - 1;
      
                      // Calculates Yin
                      $yin = 0;
                      for($i = 1; $i <= $n_columns; $i ++) {
                          $yin += $row_data["x" . $i] * $weightCache[$i];
                      }
      
                      // Calculates Real Output
                      $Y = ($yin <= 1) ? - 1 : 1;
      
                      // Sweeps columns ...
                      $checkpoints[$row_counter] = 0;
                      for($i = 1; $i <= $n_columns; $i ++) {
                          /** DELTAS **/
                          // Is it the first row?
                          if ($just_started == true) {
                              $this->dw[$i] = $weightCache[$i];
                              $just_started = false;
                              // Found desired output?
                          } elseif ($Y == $row_data["o"]) {
                              $this->dw[$i] = 0;
                              // Calculates Delta Ws
                          } else {
                              $this->dw[$i] = $row_data["x" . $i] * $row_data["o"];
                          }
      
                          /** WEIGHTS **/
                          // Calculate Weights
                          $this->w[$i] = $this->dw[$i] + $weightCache[$i];
                          $weightCache[$i] = $this->w[$i];
      
                          /** CHECK-POINT **/
                          $checkpoints[$row_counter] += $this->w[$i];
                      } // END - for
      
                      foreach ($this->w as $index => $w_item) {
                          $debug_w["W" . $index] = $w_item;
                          $debug_dw["deltaW" . $index] = $this->dw[$index];
                      }
      
                      // Special for script debugging
                      $debug_vars[] = array_merge($row_data, array(
                          "Bias" => 1,
                          "Yin" => $yin,
                          "Y" => $Y
                      ), $debug_dw, $debug_w, array(
                          "deltaBias" => 1
                      ));
                  } // END - foreach
      
                  // Special for script debugging
                   $empty_data_row = array();
                  for($i = 1; $i <= $n_columns; $i ++) {
                      $empty_data_row["x" . $i] = "--";
                      $empty_data_row["W" . $i] = "--";
                      $empty_data_row["deltaW" . $i] = "--";
                  }
                  $debug_vars[] = array_merge($empty_data_row, array(
                      "o" => "--",
                      "Bias" => "--",
                      "Yin" => "--",
                      "Y" => "--",
                      "deltaBias" => "--"
                  ));
      
                  // Counts training times
                  $totalRun ++;
      
                  // Now checks if the RNA is stable already
                  $referer_value = end($checkpoints);
                  // if all rows match the desired output ...
                  $sum = array_sum($checkpoints);
                  $n_rows = count($checkpoints);
                  if ($totalRun > 1 && ($sum / $n_rows) == $referer_value) {
                      $keepTrainning = false;
                  }
              } // END - while
      
              // Prepares the final result
              $result = array();
              for($i = 1; $i <= $n_columns; $i ++) {
                  $result["w" . $i] = $this->w[$i];
              }
      
              $this->debug($this->print_html_table($debug_vars));
      
              return $result;
          } // END - train
          function testCase($input, $results) {
              // Sweeps input columns
              $result = 0;
              $i = 1;
              foreach ($input as $column_value) {
                  // Calculates teste Y
                  $result += $results["w" . $i] * $column_value;
                  $i ++;
              }
              // Checks in each class the test fits
              return ($result > 0) ? true : false;
          } // END - test_class
      
          // Returns the html code of a html table base on a hash array
          function print_html_table($array) {
              $html = "";
              $inner_html = "";
              $table_header_composed = false;
              $table_header = array();
      
              // Builds table contents
              foreach ($array as $array_item) {
                  $inner_html .= "<tr>\n";
                  foreach ( $array_item as $array_col_label => $array_col ) {
                      $inner_html .= "<td>\n";
                      $inner_html .= $array_col;
                      $inner_html .= "</td>\n";
      
                      if ($table_header_composed == false) {
                          $table_header[] = $array_col_label;
                      }
                  }
                  $table_header_composed = true;
                  $inner_html .= "</tr>\n";
              }
      
              // Builds full table
              $html = "<table border=1>\n";
              $html .= "<tr>\n";
              foreach ($table_header as $table_header_item) {
                  $html .= "<td>\n";
                  $html .= "<b>" . $table_header_item . "</b>";
                  $html .= "</td>\n";
              }
              $html .= "</tr>\n";
      
              $html .= $inner_html . "</table>";
      
              return $html;
          } // END - print_html_table
      
          // Debug function
          function debug($message) {
              if ($this->debug == true) {
                  echo "<b>DEBUG:</b> $message";
              }
          } // END - debug
      } // END - class