분석 도구를 작성 중이며 현재 사용자 에이전트에서 사용자의 IP 주소, 브라우저 및 운영 체제를 가져올 수 있습니다.
쿠키 나 로컬 스토리지를 사용하지 않고 동일한 사용자를 감지 할 수 있는지 궁금합니다. 여기서 코드 예제를 기대하지 않습니다. 더 자세히 살펴볼 간단한 힌트입니다.
동일한 컴퓨터 / 장치 인 경우 브라우저 간 호환이 필요하다는 것을 언급하지 않았습니다. 기본적으로 나는 장치 인식 후에 실제로 사용자가 아닙니다.
분석 도구를 작성 중이며 현재 사용자 에이전트에서 사용자의 IP 주소, 브라우저 및 운영 체제를 가져올 수 있습니다.
쿠키 나 로컬 스토리지를 사용하지 않고 동일한 사용자를 감지 할 수 있는지 궁금합니다. 여기서 코드 예제를 기대하지 않습니다. 더 자세히 살펴볼 간단한 힌트입니다.
동일한 컴퓨터 / 장치 인 경우 브라우저 간 호환이 필요하다는 것을 언급하지 않았습니다. 기본적으로 나는 장치 인식 후에 실제로 사용자가 아닙니다.
답변:
소개
올바르게 이해하면 고유 식별자가없는 사용자를 식별해야하므로 임의 데이터와 일치하여 누구인지 파악해야합니다. 다음과 같은 이유로 사용자의 신원을 안정적으로 저장할 수 없습니다.
Java Applet 또는 Com Object는 하드웨어 정보의 해시를 사용하는 쉬운 솔루션 이었지만 요즘 사람들은 보안을 인식하여 사람들이 시스템에 이러한 종류의 프로그램을 설치하기가 어려울 수 있습니다. 쿠키 및 기타 유사한 도구를 사용하는 데 어려움이 있습니다.
쿠키 및 기타 유사한 도구
데이터 프로파일을 작성한 다음 확률 테스트를 사용하여 가능한 사용자 를 식별 할 수 있습니다. 이에 유용한 프로파일은 다음을 조합하여 생성 할 수 있습니다.
물론 나열된 항목은 사용자를 고유하게 식별 할 수있는 몇 가지 가능한 방법입니다. 더 많은 것이 있습니다.
이 랜덤 데이터 요소 집합을 사용하여 데이터 프로필을 작성하면 다음은 무엇입니까?
다음 단계는 퍼지 로직 또는 인공 신경 네트워크 (퍼지 로직을 사용하는)를 개발하는 것입니다. 두 경우 모두 시스템을 훈련시킨 다음 베이지안 추론 과 훈련을 결합 하여 결과의 정확성을 높이는 것이 좋습니다.
NeuralMesh의 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 일 확률은 얼마입니까? 그리고 그 두 경기 중 가장 가능성이 높은 것은 무엇입니까?
이 질문에 효과적으로 대답하려면 빈도 대 확률 형식 과 왜 공동 확률 이 더 나은 접근 방식 인지 이해해야 합니다. 자세한 내용은 여기에 도달하기에는 너무 많지만 (링크를 제공하는 이유), 좋은 예는 증상의 조합을 사용하여 가능한 질병을 식별 하는 의료 진단 마법사 응용 프로그램 입니다.
데이터 프로필 (위의 예에서 B + C + E + G + F + K)을 증상으로 , 알 수없는 사용자를 질병으로 구성하는 일련의 데이터 포인트를 생각해보십시오 . 질병을 식별하여 적절한 치료법을 추가로 식별 할 수 있습니다 (이 사용자를 User1로 처리).
분명히, 우리가 하나 이상의 증상을 식별 한 질병 은 쉽게 식별 할 수 있습니다. 실제로, 우리가 식별 할 수있는 증상 이 많을수록 진단이 더 쉽고 정확합니다.
다른 대안이 있습니까?
물론이야. 대안 측정으로, 당신은 당신의 자신의 간단한 점수 알고리즘을 생성하고 정확한 일치를 기반으로 할 수 있습니다. 이것은 확률만큼 효율적이지 않지만 구현하기가 더 간단 할 수 있습니다.
예를 들어,이 간단한 스코어 차트를 고려하십시오.
+ ------------------------- + -------- + -------------- + | 부동산 | 무게 | 중요성 | + ------------------------- + -------- + -------------- + | 실제 IP 주소 | 60 | 5 | | 사용 된 프록시 IP 주소 | 40 | 4 | | HTTP 쿠키 | 80 | 8 | | 세션 쿠키 | 80 | 6 | | 타사 쿠키 | 60 | 4 | | 플래시 쿠키 | 90 | 7 | | PDF 버그 | 20 | 1 | | 플래시 버그 | 20 | 1 | | 자바 버그 | 20 | 1 | | 잦은 페이지 | 40 | 1 | | 브라우저 지문 | 35 | 2 | | 설치된 플러그인 | 25 | 1 | | 캐시 된 이미지 | 40 | 3 | | URL | 60 | 4 | | 시스템 글꼴 감지 | 70 | 4 | | 로컬 스토리지 | 90 | 8 | | 지리적 위치 | 70 | 6 | | AOLTR | 70 | 4 | | 네트워크 정보 API | 40 | 3 | | 배터리 상태 API | 20 | 1 | + ------------------------- + -------- + -------------- +
특정 요청에 따라 수집 할 수있는 각 정보에 대해 관련 점수를 부여한 다음 중요도 가 동일하면 점수 를 사용 하여 충돌을 해결하십시오.
개념의 증거
간단한 개념 증명을 보려면 Perceptron을 살펴보십시오 . 퍼셉트론은 일반적으로 패턴 인식 애플리케이션에 사용되는 RNA 모델 입니다. 완벽하게 구현 하는 오래된 PHP 클래스도 있지만 목적에 맞게 수정해야 할 수도 있습니다.
훌륭한 도구 임에도 불구하고 Perceptron은 여전히 여러 결과 (가능한 일치 항목)를 반환 할 수 있으므로 점수 및 차이 비교를 사용하면 해당 일치 항목을 가장 잘 식별 할 수 있습니다 .
가정
기대
개념 증명을위한 코드
$features = array(
'Real IP address' => .5,
'Used proxy IP address' => .4,
'HTTP Cookies' => .9,
'Session Cookies' => .6,
'3rd Party Cookies' => .6,
'Flash Cookies' => .7,
'PDF Bug' => .2,
'Flash Bug' => .2,
'Java Bug' => .2,
'Frequent Pages' => .3,
'Browsers Finger Print' => .3,
'Installed Plugins' => .2,
'URL' => .5,
'Cached PNG' => .4,
'System Fonts Detection' => .6,
'Localstorage' => .8,
'Geolocation' => .6,
'AOLTR' => .4,
'Network Information API' => .3,
'Battery Status API' => .2
);
// Get RNA Lables
$labels = array();
$n = 1;
foreach ($features as $k => $v) {
$labels[$k] = "x" . $n;
$n ++;
}
// Create Users
$users = array();
for($i = 0, $name = "A"; $i < 5; $i ++, $name ++) {
$users[] = new Profile($name, $features);
}
// Generate Unknown User
$unknown = new Profile("Unknown", $features);
// Generate Unknown RNA
$unknownRNA = array(
0 => array("o" => 1),
1 => array("o" => - 1)
);
// Create RNA Values
foreach ($unknown->data as $item => $point) {
$unknownRNA[0][$labels[$item]] = $point;
$unknownRNA[1][$labels[$item]] = (- 1 * $point);
}
// Start Perception Class
$perceptron = new Perceptron();
// Train Results
$trainResult = $perceptron->train($unknownRNA, 1, 1);
// Find matches
foreach ($users as $name => &$profile) {
// Use shorter labels
$data = array_combine($labels, $profile->data);
if ($perceptron->testCase($data, $trainResult) == true) {
$score = $diff = 0;
// Determing the score and diffrennce
foreach ($unknown->data as $item => $found) {
if ($unknown->data[$item] === $profile->data[$item]) {
if ($profile->data[$item] > 0) {
$score += $features[$item];
} else {
$diff += $features[$item];
}
}
}
// Ser score and diff
$profile->setScore($score, $diff);
$matchs[] = $profile;
}
}
// Sort bases on score and Output
if (count($matchs) > 1) {
usort($matchs, function ($a, $b) {
// If score is the same use diffrence
if ($a->score == $b->score) {
// Lower the diffrence the better
return $a->diff == $b->diff ? 0 : ($a->diff > $b->diff ? 1 : - 1);
}
// The higher the score the better
return $a->score > $b->score ? - 1 : 1;
});
echo "<br />Possible Match ", implode(",", array_slice(array_map(function ($v) {
return sprintf(" %s (%0.4f|%0.4f) ", $v->name, $v->score,$v->diff);
}, $matchs), 0, 2));
} else {
echo "<br />No match Found ";
}
Possible Match D (0.7416|0.16853),C (0.5393|0.2809)
"D"의 Print_r :
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
)
Debug = true이면 입력 (센서 및 원하는), 초기 무게, 출력 (센서, 합계, 네트워크), 오류, 수정 및 최종 무게를 볼 수 있습니다.
+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
| 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 |
| -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
x1 ~ x20은 코드로 변환 된 기능을 나타냅니다.
// 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
결론
고유 식별자가없는 사용자를 식별하는 것은 간단하거나 간단한 작업이 아닙니다. 다양한 방법으로 사용자로부터 수집 할 수있는 충분한 양의 임의 데이터를 수집하는 데 달려 있습니다.
인공 신경 네트워크를 사용하지 않더라도 적어도 우선 순위와 가능성을 가진 단순 확률 매트릭스를 사용하는 것이 좋습니다. 위에 제공된 코드와 예제가 충분히 진행되기를 바랍니다.
Implement Bayesian inference using PHP
, 세 부분 모두. - Frequency vs Probability
- Joint Probability
-Input (Sensor & Desired), Initial Weights, Output (Sensor, Sum, Network), Error, Correction and Final Weights
쿠키없이 또는 심지어 IP 주소없이 동일한 사용자를 감지하는이 기술을 브라우저 지문 이라고 합니다 . 기본적으로 브라우저에 대한 정보로 크롤링 할 수 있습니다. javascript, flash 또는 java (f.ex. 설치된 확장 프로그램, 글꼴 등)를 사용하면 더 나은 결과를 얻을 수 있습니다. 그런 다음 원하는 경우 해시 결과를 저장할 수 있습니다.
완벽한 것은 아니지만 :
본 브라우저의 83.6 %는 고유 한 지문을 가지고있었습니다. 플래시 또는 자바를 사용하는 사람들 중 94.2 %. 쿠키는 포함되지 않습니다!
더 많은 정보:
위에서 언급 한 지문은 작동하지만 여전히 문제가 발생할 수 있습니다.
한 가지 방법은 사용자와의 각 상호 작용 URL에 UID를 추가하는 것입니다.
http://someplace.com/12899823/user/profile
사이트의 모든 링크가이 수정자를 사용하는 경우 ASP.Net이 페이지 간 FORM 데이터를 사용하는 방식과 유사합니다.
Evercookie 를 살펴 보셨습니까 ? 브라우저에서 작동하거나 작동하지 않을 수 있습니다. 그들의 사이트에서 추출한 것.
"사용자가 한 브라우저에서 쿠키를 받고 다른 브라우저로 전환하면 여전히 로컬 공유 객체 쿠키가있는 한 쿠키는 두 브라우저에서 모두 재생됩니다."
캐시 된 png 로이 작업을 수행 할 수는 있지만 다소 신뢰할 수는 없지만 (다른 브라우저는 다르게 동작하며 사용자가 캐시를 지우면 실패합니다) 옵션입니다.
1 : 고유 한 사용자 ID를 16 진 문자열로 저장하는 데이터베이스 설정
2 : 사용자 ID를 생성하고 DB에 저장 한 다음 16 진수 문자열 (각 픽셀은 4 바이트)의 값으로 트루 컬러 .png를 생성하는 genUser.php (또는 다른 언어) 파일을 생성 브라우저로 컨텐츠 유형 및 캐시 헤더를 설정하십시오.
3 : HTML 또는 JS에서 다음과 같은 이미지를 만듭니다. <img id='user_id' src='genUser.php' />
4 : 캔버스에 해당 이미지 그리기 ctx.drawImage(document.getElementById('user_id'), 0, 0);
5 :를 사용하여 해당 이미지의 바이트를 읽고 ctx.getImageData
정수를 16 진 문자열로 변환하십시오.
6 : 이제는 사용자 컴퓨터에 캐시 된 고유 한 사용자 ID입니다.
I'm after device recognition
그가 원하는 것에 대한 경품이며, 여기에서 자세히 설명합니다 : stackoverflow.com/questions/15966812/…
당신이 말한 것을 바탕으로 :
기본적으로 나는 사용자가 아닌 장치 인식 후
가장 좋은 방법은 NIC ID 인 mac 주소를 보내는 것입니다.
이 게시물을 살펴볼 수 있습니다 : PHP로 연결된 클라이언트의 MAC 및 IP 주소를 얻는 방법은 무엇입니까?
etags로 할 수 있습니다. 이 소송이 다수의 소송으로 제기되었는지는 확실하지 않습니다.
사용자에게 올바르게 경고하거나 인트라넷 웹 사이트와 같은 것이 있으면 정상일 수 있습니다.
장치 식별자를 저장하기 위해 Blob을 만들 수 있습니다 ...
단점은 브라우저가 파일 시스템에 액세스하여 파일을 직접 저장할 수 없기 때문에 사용자가 블롭을 다운로드해야한다는 것입니다 (다운로드 를 강제 할 수 있음 ).
참고:
https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-22/blobs
믿을 수 없습니다, http://browserspy.dk는 아직 여기에 언급되지 않았습니다! 이 사이트는 분류기를 구축하는 데 사용할 수있는 많은 기능 (패턴 인식 측면에서)을 설명합니다.
그리고 기능의 평가를 위해 특히 Support Vector Machines 및 libsvm 을 제안 합니다.
한 세션 동안 또는 여러 세션에서 추적합니까?
사이트가 HTTPS Everywhere 인 경우 TLS 세션 ID를 사용하여 사용자 세션을 추적 할 수 있습니다.
이를 위해서는 사용자가 기꺼이 식별자를 설치해야합니다.
플러그인이 설치되면 (플러그인 가능) 브라우저 지문 에이 특정 플러그인이 포함됩니다. 정보를 서버로 반환하려면 클라이언트 측에서 플러그인을 효과적으로 감지하는 알고리즘이 필요합니다. 그렇지 않으면 IE 및 Firefox> = 28 사용자는 가능한 유효한 식별 테이블이 필요합니다.
이를 위해서는 브라우저 공급 업체에 의해 종료 될 수있는 기술에 상대적으로 많은 투자가 필요합니다. 사용자가 플러그인을 설치하도록 설득 할 수있는 경우 설치와 같은 옵션이있을 수 있습니다. 로컬 프록시 , vpn 사용 또는 네트워크 드라이버 패치 .
식별되기를 원하지 않는 사용자 (또는 시스템)는 항상이를 방지 할 방법을 찾습니다.
this will require the user to willingly install the identifier.
아마도 원래 포스터 (OP)의 의미가 아닐 수도 있습니다.