Nhận dạng người dùng không có cookie hoặc bộ nhớ cục bộ


132

Tôi đang xây dựng một công cụ phân tích và hiện tại tôi có thể lấy địa chỉ IP, trình duyệt và hệ điều hành của người dùng từ tác nhân người dùng của họ.

Tôi đang tự hỏi liệu có khả năng phát hiện cùng một người dùng mà không sử dụng cookie hoặc bộ nhớ cục bộ không? Tôi không mong đợi các ví dụ mã ở đây; chỉ là một gợi ý đơn giản về nơi để nhìn xa hơn.

Quên đề cập rằng nó sẽ cần phải tương thích với nhiều trình duyệt nếu nó là cùng một máy tính / thiết bị. Về cơ bản tôi sau khi nhận dạng thiết bị không thực sự là người dùng.


5
Không thực sự - ít nhất là không có cách nào bạn có thể dựa vào để chính xác. Có thể một hàm băm của cả ba kết hợp, tuy nhiên nếu nhiều người trong một nhà sử dụng cùng một trình duyệt và HĐH, thì nó vẫn không hoạt động. Ngoài ra, hầu hết các ISP cung cấp địa chỉ IP động, nghĩa là họ thay đổi thường xuyên và sẽ không thể dựa vào mục đích nhận dạng.
Jon

2
Sau đó, bạn không biết phiên là gì. Trường hợp sử dụng của bạn chính xác là những phiên được thiết kế cho. Phiên không có gì để làm với đăng nhập hoặc xác thực. Máy chủ web của bạn sẽ yêu cầu khách hàng gửi cookie với mã định danh phiên. Bạn xác định khách hàng đó bằng cách sử dụng id phiên họ gửi cho bạn.
Man Vs Code

4
Cookies vẫn sẽ hoạt động? Tại sao bạn tránh sử dụng cookie?
Baba

2
Nó thực sự đơn giản và tôi sử dụng nó mọi lúc, yêu cầu người dùng nhập tên người dùng và mật khẩu !!!
Amit Kriplani

2
Đây là một giải pháp javascript tối thiểu (không phải trình duyệt chéo trong trường hợp này): github.com/carlo/jquery-browser-fingerprint Tôi đề cập đến nó, bởi vì nó đưa tôi đến khái niệm rằng nhiều plugin được cài đặt trình duyệt chéo theo mặc định, không có bất kỳ lựa chọn nào về phía người dùng. Sắp xếp chúng cẩn thận (không phải là một nhiệm vụ nhỏ, nhưng vẫn ...) có thể có khả năng dẫn đến một đặc tính không thể biết của trình duyệt hữu hình của dấu vân tay dựa trên thiết bị lớn hơn.
hexalys

Câu trả lời:


389

Giới thiệu

Nếu tôi hiểu bạn chính xác, bạn cần xác định người dùng mà bạn không có Mã định danh duy nhất, vì vậy bạn muốn tìm ra họ là ai bằng cách khớp Dữ liệu ngẫu nhiên. Bạn không thể lưu trữ danh tính người dùng một cách đáng tin cậy vì:

  • Cookies có thể bị xóa
  • Địa chỉ IP có thể thay đổi
  • Trình duyệt có thể thay đổi
  • Cache của trình duyệt có thể bị xóa

Java Applet hoặc Com Object sẽ là một giải pháp dễ dàng khi sử dụng hàm băm thông tin phần cứng, nhưng ngày nay mọi người nhận thức được bảo mật đến mức khó có thể khiến mọi người cài đặt các loại chương trình này trên hệ thống của họ. Điều này khiến bạn bị mắc kẹt với việc sử dụng Cookies và các công cụ tương tự khác.

Cookies và các công cụ tương tự khác

Bạn có thể xem xét việc xây dựng Hồ sơ dữ liệu, sau đó sử dụng các kiểm tra Xác suất để xác định Người dùng có thể xảy ra . Một hồ sơ hữu ích cho việc này có thể được tạo bởi một số kết hợp sau:

  1. Địa chỉ IP
    • Địa chỉ IP thật
    • Địa chỉ IP proxy (người dùng thường sử dụng cùng một proxy nhiều lần)
  2. Bánh quy
  3. Lỗi web (ít đáng tin cậy hơn vì lỗi đã được sửa nhưng vẫn hữu ích)
    • Lỗi PDF
    • Lỗi flash
    • Lỗi Java
  4. Trình duyệt
    • Nhấp theo dõi (nhiều người dùng truy cập cùng một loạt trang trên mỗi lần truy cập)
    • Trình duyệt Finger Print - Plugin được cài đặt (mọi người thường có các bộ plugin khác nhau, hơi độc đáo)
    • Hình ảnh được lưu trong bộ nhớ cache (đôi khi mọi người xóa cookie của họ nhưng để lại hình ảnh được lưu trong bộ nhớ cache)
    • Sử dụng Blobs
    • (Các) URL (lịch sử trình duyệt hoặc cookie có thể chứa id người dùng duy nhất trong các URL, chẳng hạn như https://stackoverflow.com/users/1226894 hoặc http://www.facebook.com/barackobama?fref=ts )
    • Phát hiện phông chữ hệ thống (đây là một chữ ký khóa ít được biết đến nhưng thường là duy nhất)
  5. HTML5 & Javascript
    • HTML5 LocalStorage
    • API định vị địa lý HTML5 và mã hóa địa lý đảo ngược
    • Kiến trúc, Ngôn ngữ hệ điều hành, Thời gian hệ thống, Độ phân giải màn hình, v.v.
    • API thông tin mạng
    • API trạng thái pin

Tất nhiên, các mục tôi liệt kê chỉ là một vài cách có thể được xác định duy nhất người dùng. Chúng còn nhiều nữa.

Với tập hợp các yếu tố Dữ liệu ngẫu nhiên này để xây dựng Hồ sơ dữ liệu từ đó, tiếp theo là gì?

Bước tiếp theo là phát triển một số Logic mờ , hay tốt hơn là Mạng nơ ron nhân tạo (sử dụng logic mờ). Trong cả hai trường hợp, ý tưởng là đào tạo hệ thống của bạn, và sau đó kết hợp đào tạo của nó với Bayesian Inference để tăng độ chính xác của kết quả của bạn.

Mạng lưới thần kinh nhân tạo

Các NeuralMesh thư viện cho PHP cho phép bạn tạo Artificial Neural Networks. Để thực hiện suy luận Bayes, hãy kiểm tra các liên kết sau:

Tại thời điểm này, bạn có thể nghĩ:

Tại sao rất nhiều toán học và logic cho một nhiệm vụ có vẻ đơn giản?

Về cơ bản, bởi vì nó không phải là một nhiệm vụ đơn giản . Trên thực tế, những gì bạn đang cố gắng đạt được là Xác suất thuần túy . Ví dụ: được cung cấp cho những người dùng đã biết sau:

User1 = A + B + C + D + G + K
User2 = C + D + I + J + K + F

Khi bạn nhận được dữ liệu sau:

B + C + E + G + F + K

Câu hỏi mà bạn chủ yếu hỏi là:

Xác suất mà dữ liệu nhận được (B + C + E + G + F + K) thực sự là User1 hoặc User2 là bao nhiêu? Và trận đấu nào trong hai trận đấu đó có khả năng xảy ra nhất ?

Để trả lời hiệu quả câu hỏi này, bạn cần hiểu Định dạng Tần suất và Xác suất và tại sao Xác suất chung có thể là một cách tiếp cận tốt hơn. Các chi tiết có quá nhiều để vào đây (đó là lý do tại sao tôi cung cấp cho bạn các liên kết), nhưng một ví dụ điển hình là Ứng dụng Thuật sĩ Chẩn đoán Y khoa , sử dụng kết hợp các triệu chứng để xác định các bệnh có thể.

Hãy suy nghĩ một chút về chuỗi các điểm dữ liệu bao gồm Hồ sơ dữ liệu của bạn (B + C + E + G + F + K trong ví dụ trên) dưới dạng Triệu chứng và Người dùng không xác định là Bệnh . Bằng cách xác định bệnh, bạn có thể xác định thêm một phương pháp điều trị thích hợp (coi người dùng này là Người dùng1).

Rõ ràng, một bệnh mà chúng tôi đã xác định được nhiều hơn 1 Triệu chứng dễ xác định hơn. Trên thực tế, càng có nhiều triệu chứng chúng ta có thể xác định, chẩn đoán của chúng ta càng dễ dàng và chính xác hơn.

Còn lựa chọn nào nữa ko?

Tất nhiên. Là một biện pháp thay thế, bạn có thể tạo thuật toán chấm điểm đơn giản của riêng mình và dựa trên các kết quả khớp chính xác. Điều này không hiệu quả như xác suất, nhưng có thể đơn giản hơn để bạn thực hiện.

Ví dụ, xem xét biểu đồ điểm đơn giản này:

+ ------------------------- + -------- + ------------ +
| Tài sản | Cân nặng | Tầm quan trọng |
+ ------------------------- + -------- + ------------ +
| Địa chỉ IP thật | 60 | 5 |
| Địa chỉ IP proxy được sử dụng | 40 | 4 |
| Bánh quy HTTP | 80 | 8 |
| Cookies phiên | 80 | 6 |
| Bánh quy bên thứ 3 | 60 | 4 |
| Flash Cookies | 90 | 7 |
| Lỗi PDF | 20 | 1 |
| Lỗi flash | 20 | 1 |
| Lỗi Java | 20 | 1 |
| Trang thường xuyên | 40 | 1 |
| Trình duyệt Finger Print | 35 | 2 |
| Plugin đã cài đặt | 25 | 1 |
| Hình ảnh lưu trữ | 40 | 3 |
| URL | 60 | 4 |
| Phát hiện phông chữ hệ thống | 70 | 4 |
| Lưu trữ cục bộ | 90 | 8 |
| Định vị địa lý | 70 | 6 |
| AOLTR | 70 | 4 |
| API thông tin mạng | 40 | 3 |
| API trạng thái pin | 20 | 1 |
+ ------------------------- + -------- + ------------ +

Đối với mỗi mẩu thông tin mà bạn có thể thu thập theo một yêu cầu nhất định, hãy trao điểm số liên quan, sau đó sử dụng Tầm quan trọng để giải quyết xung đột khi điểm số giống nhau.

Bằng chứng của khái niệm

Đối với một bằng chứng đơn giản về khái niệm, xin vui lòng xem Perceptron . Perceptron là một Mô hình RNA thường được sử dụng trong các ứng dụng nhận dạng mẫu. Thậm chí còn có một lớp PHP cũ thực hiện nó một cách hoàn hảo, nhưng bạn có thể sẽ cần phải sửa đổi nó cho mục đích của mình.

Mặc dù là một công cụ tuyệt vời, Perceptron vẫn có thể trả về nhiều kết quả (có thể có kết quả trùng khớp), do đó, sử dụng so sánh Điểm và Sự khác biệt vẫn hữu ích để xác định điểm tốt nhất của những trận đấu đó.

Giả định

  • Lưu trữ tất cả thông tin có thể có về mỗi người dùng (IP, cookie, v.v.)
  • Trường hợp kết quả là một trận đấu chính xác, tăng 1 điểm
  • Trong trường hợp kết quả không khớp chính xác, hãy giảm 1 điểm

Sự mong đợi

  1. Tạo nhãn RNA
  2. Tạo người dùng ngẫu nhiên mô phỏng cơ sở dữ liệu
  3. Tạo một người dùng không xác định
  4. Tạo giá trị và giá trị RNA của người dùng không xác định
  5. Hệ thống sẽ hợp nhất thông tin RNA và dạy Perceptron
  6. Sau khi đào tạo Perceptron, hệ thống sẽ có một bộ trọng số
  7. Bây giờ bạn có thể kiểm tra mẫu Người dùng không xác định và Perceptron sẽ tạo ra một tập kết quả.
  8. Lưu trữ tất cả các trận đấu tích cực
  9. Sắp xếp các trận đấu trước theo Điểm, sau đó theo Chênh lệch (như được mô tả ở trên)
  10. Xuất ra hai kết quả khớp gần nhất hoặc, nếu không tìm thấy kết quả khớp nào, xuất kết quả trống

Mã chứng minh khái niệm

$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 ";
}

Đầu ra:

Possible Match D (0.7416|0.16853),C (0.5393|0.2809)

In_r của "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
)

Nếu Debug = true, bạn sẽ có thể thấy Đầu vào (Cảm biến & Mong muốn), Trọng lượng ban đầu, Đầu ra (Cảm biến, Tổng, Mạng), Lỗi, Hiệu chỉnh và Trọng lượng cuối cùng .

+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
| 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 đến x20 đại diện cho các tính năng được chuyển đổi bởi mã.

// Get RNA Labels
$labels = array();
$n = 1;
foreach ( $features as $k => $v ) {
    $labels[$k] = "x" . $n;
    $n ++;
}

Đây là một bản demo trực tuyến

Lớp được sử dụng:

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;
    }
}

Lớp Perceptron đã sửa đổi

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

Phần kết luận

Xác định người dùng không có Mã định danh duy nhất không phải là một nhiệm vụ đơn giản hoặc đơn giản. nó phụ thuộc vào việc thu thập đủ lượng Dữ liệu ngẫu nhiên mà bạn có thể thu thập từ người dùng bằng nhiều phương pháp khác nhau.

Ngay cả khi bạn chọn không sử dụng Mạng thần kinh nhân tạo, tôi khuyên bạn ít nhất nên sử dụng Ma trận xác suất đơn giản với các ưu tiên và khả năng - và tôi hy vọng mã và các ví dụ được cung cấp ở trên cung cấp cho bạn đủ để tiếp tục.


@Baba Ý bạn là gì khi "Sử dụng Blobs" để lấy dấu vân tay trình duyệt?
billmalarky


1
@Baba Làm thế nào một người sẽ sử dụng nó để lấy dấu vân tay trình duyệt? Chỉ cần kiểm tra những gì hiện đang có trong nó tại bất kỳ thời điểm nào?
billmalarky

@Baba công việc tuyệt vời, tôi đã luôn cố gắng có một số chiến lược đa cấp để xác định người dùng, nhưng như bạn nói bộ nhớ cache có thể bị xóa, IP thay đổi, người dùng đằng sau proxy hoặc NAT - đặc biệt là những người đó -, đã xóa cookie, v.v. . nhưng ngay cả với rất nhiều nỗ lực này, đó là một xác suất có vấn đề, cũng như nếu người dùng xấu đang sử dụng trình duyệt Tor chẳng hạn, hầu hết nếu không phải tất cả các chiến lược phát hiện được đề cập sẽ không hoạt động. Tôi thích browserleaks.com nhưng với Tor tất cả đã trở lại không xác định hoặc không xác định
Mi-Creativity

Chỉ là một Lưu ý chỉ nhằm mục đích "loại bỏ một số bụi" khỏi viên ngọc của ấn phẩm này: Danh sách các liên kết bị hỏng kể từ ngày 07/09/17: - Implement Bayesian inference using PHP, tất cả 3 phần. - Frequency vs Probability - Joint Probability -Input (Sensor & Desired), Initial Weights, Output (Sensor, Sum, Network), Error, Correction and Final Weights
Ziezi

28

Kỹ thuật này (để phát hiện cùng người dùng không có cookie - hoặc thậm chí không có địa chỉ IP) được gọi là dấu vân tay trình duyệt . Về cơ bản, bạn thu thập thông tin dưới dạng thông tin về trình duyệt như bạn có thể - có thể đạt được kết quả tốt hơn với javascript, flash hoặc java (ví dụ: cài đặt tiện ích mở rộng, phông chữ, v.v.). Sau đó, bạn có thể lưu trữ các kết quả được băm, nếu bạn muốn.

Nó không phải là không thể sai lầm, nhưng:

83,6% trình duyệt được nhìn thấy có dấu vân tay độc đáo; trong số những người có bật Flash hoặc Java, 94,2%. Điều này không bao gồm cookie!

Thêm thông tin:


Tôi nghĩ, đó vẫn là câu trả lời. nếu bạn cần xác định một thiết bị, bạn chỉ cần lấy những dữ liệu đó - f.ex. Hệ điều hành, tiện ích mở rộng chung (và phiên bản của nó), phông chữ được cài đặt, v.v ...
pozs

Điều này sẽ không hoạt động tốt. Mọi trình duyệt đều hỗ trợ phiên và cookie. Sử dụng các công cụ thích hợp cho công việc.
Man Vs Code

1
@ slash197 còn cache tập tin thì sao? ý tôi là sử dụng phương tiện flash trong suốt 1px x 1px cùng với tệp xml chứa id được tạo duy nhất bên trong (xml nên được tạo một lần trên máy chủ trước khi được tải xuống HD người dùng cục bộ) theo cách này ngay cả khi người dùng xóa cookie hoặc đăng xuất, bạn vẫn có thể có một cây cầu bằng cách sử dụng phương thức sendAndLoad của tập lệnh hành động.
Mbarry

Tối thiểu thay đổi sẽ ảnh hưởng đến kết quả băm. ví dụ phiên bản của máy phát sóng xung kích. giải pháp có thể với tệp bộ nhớ cache xml được lưu trữ cục bộ với khóa duy nhất được tạo + ẩn phương tiện flash 1px x 1px (tập lệnh hành động) trên trình duyệt, theo cách này bạn thoát khỏi cookie, vấn đề hết hạn phiên nếu đó là vấn đề chính. bạn vẫn có thể có cầu nối giữa cơ sở dữ liệu sql của bạn và khóa trên máy cục bộ của người dùng.
Mbarry

@Mbarry Tôi không phải là một fan hâm mộ flash nhưng nếu trong trình duyệt có một tiện ích chặn flash như tôi có phương tiện flash 1x1 pixel sẽ bị vô hiệu hóa, tôi có bị hỏng không?
slash197

7

Các dấu vân tay được đề cập ở trên, nhưng vẫn có thể bị đau bụng.

Một cách là thêm UID vào url của mỗi tương tác với người dùng.

http://someplace.com/12899823/user/profile

Nơi mọi liên kết trong trang web được điều chỉnh với công cụ sửa đổi này. Nó tương tự như cách mà ASP.Net sử dụng để làm việc sử dụng dữ liệu FORM giữa các trang.


Tôi đã nghĩ về điều đó nhưng đó là cách dễ nhất để người dùng sửa đổi nó
slash197

1
không phải của id là một hàm băm tự tham chiếu. Làm cho nó an toàn về mật mã.
Justin Alexander

Ngoài ra, phương pháp này vẫn ổn khi ai đó duyệt trang web nhưng làm thế nào để bạn đề xuất xử lý trường hợp khi người dùng quay lại quay lại sau một tuần và chỉ cần nhập địa chỉ trang web, không có id?
slash197

@ slash197 trong trường hợp đó tại sao bạn không bảo người dùng đăng nhập, điều đó xảy ra ngay cả khi người dùng xóa cookie.
Akash Kava

6

Bạn đã nhìn vào Evercookie ? Nó có thể hoặc không thể hoạt động trên các trình duyệt. Một trích xuất từ ​​trang web của họ.

"Nếu người dùng được nấu ăn trên một trình duyệt và chuyển sang trình duyệt khác, miễn là họ vẫn có cookie Đối tượng chia sẻ cục bộ, cookie sẽ sao chép trong cả hai trình duyệt."


Tôi tự hỏi nếu nó hoạt động với JavaScript bị vô hiệu hóa. Bạn có kinh nghiệm gì không
Voitcus

Nó được gọi là evercookie vì một lý do, nó sẽ hoạt động bất kể là gì. Họ gần như không thể gỡ bỏ cookie.
Alexis Tyler

Nó sẽ không hoạt động bất kể điều gì. Từ dòng đầu tiên của mô tả: 'evercookie là API javascript ...'. Nó sẽ không hoạt động nếu javascript bị vô hiệu hóa.
gdw2

Không cần phải bị vô hiệu hóa js. Ghostery và uBlock giảm evercookie
opengrid

3

Bạn có thể làm điều này với một png được lưu trong bộ nhớ cache, nó sẽ hơi không đáng tin cậy (các trình duyệt khác nhau hoạt động khác nhau và sẽ thất bại nếu người dùng xóa bộ nhớ cache của họ), nhưng đó là một tùy chọn.

1: thiết lập Cơ sở dữ liệu lưu trữ id người dùng duy nhất dưới dạng chuỗi hex

2: tạo tệp genUser.php (hoặc bất kỳ ngôn ngữ nào) để tạo id người dùng, lưu trữ tệp đó trong DB và sau đó tạo màu thật .png ra khỏi các giá trị của chuỗi hex đó (mỗi pixel sẽ là 4 byte) và trả về mà để trình duyệt. Đảm bảo đặt các tiêu đề loại nội dung và bộ đệm.

3: trong HTML hoặc JS tạo một hình ảnh như <img id='user_id' src='genUser.php' />

4: vẽ hình ảnh đó vào khung vẽ ctx.drawImage(document.getElementById('user_id'), 0, 0);

5: đọc các byte của hình ảnh đó bằng cách sử dụng ctx.getImageDatavà chuyển đổi các số nguyên thành chuỗi hex.

6: Đó là id người dùng duy nhất của bạn hiện được lưu trong bộ nhớ cache trên máy tính người dùng của bạn.


Anh ta muốn một cái gì đó có thể theo dõi người dùng "trên các trình duyệt" sẽ không hoạt động ở đây (mỗi trình duyệt có cơ sở dữ liệu bộ đệm riêng).
EricLaw

Bạn đang thấy điều đó ở đâu, câu hỏi của anh ấy chỉ yêu cầu "Quên đề cập rằng nó sẽ cần phải tương thích với nhiều trình duyệt", tức là hoạt động trong bất kỳ trình duyệt nào.
hobberwickey

Câu hỏi của anh ấy được viết kém. I'm after device recognitionlà quà tặng cho những gì anh ấy muốn, và anh ấy xây dựng ở đây: stackoverflow.com/questions/15966812/
Kẻ

2

Dựa trên những gì bạn đã nói:

Về cơ bản tôi sau khi nhận dạng thiết bị không thực sự là người dùng

Cách tốt nhất để làm điều đó là gửi địa chỉ mac là ID ID.

Bạn có thể xem bài đăng này: Làm thế nào tôi có thể lấy MAC và địa chỉ IP của một máy khách được kết nối trong PHP?


Xin lỗi, nhưng ID ID dễ bị giả mạo. Đó chắc chắn không phải là cách tốt nhất.
vào

@asss dấu vân tay trình duyệt sẽ tốt hơn có thể, hoặc theo cách nào là tốt nhất theo ý kiến ​​của bạn?
Mehdi Karamosly

Không có cách tốt nhất, đó là phần buồn về nó. Tuy nhiên, điều đó và FingerPrinting kết hợp với nghiên cứu Xác suất mà Baba đã trình bày ở trên sẽ là tốt nhất theo ý kiến ​​của tôi.
vào

1

Bạn có thể làm điều đó với etags. Mặc dù tôi không chắc chắn nếu điều này hợp pháp như một loạt các vụ kiện đã được đệ trình.

Nếu bạn cảnh báo chính xác người dùng của mình hoặc nếu bạn có một cái gì đó giống như một trang web mạng nội bộ thì có thể sẽ ổn.


Etags không tương thích trình duyệt chéo.
slash197

1
Etags là một phần của thông số HTTP / 1.1. Tất cả các trình duyệt phổ biến đều hỗ trợ etags, bạn sẽ cần phải viết trình duyệt của riêng mình để không hỗ trợ các tiêu đề ETag / If-none-Match.
Brian McGinity

Tôi không nói nó không hỗ trợ, tôi nói nó không tương thích với trình duyệt. Nếu một thẻ được lưu trong Firefox thì nó không có sẵn trong chrome nên nội dung sẽ được tải xuống lại do không có bộ đệm.
slash197

Bây giờ tôi hiểu những gì bạn đang nói. Bạn đúng. Mỗi trình duyệt có kho lưu trữ bộ nhớ cache riêng, do đó etags khác nhau.
Brian McGinity


0

Không hiệu quả, nhưng có thể mang lại cho bạn kết quả mong muốn, sẽ là thăm dò API về phía bạn. Có một quá trình nền ở phía máy khách gửi dữ liệu người dùng theo một khoảng thời gian. Bạn sẽ cần một mã định danh người dùng để gửi tới API của bạn. Khi bạn đã có, bạn có thể gửi bất kỳ thông tin nào liên quan đến số nhận dạng duy nhất đó.

Điều này loại bỏ sự cần thiết cho cookie và lưu trữ cục bộ.


0

Tôi không thể tin, http://browserspy.dk vẫn chưa được đề cập ở đây! Trang web mô tả nhiều tính năng (về nhận dạng mẫu), có thể được sử dụng để xây dựng trình phân loại.

Và vì lý do, để đánh giá các tính năng tôi đề nghị cụ thể là Hỗ trợ Máy Vector và libsvm .


0

Theo dõi chúng trong một phiên hoặc qua các phiên?

Nếu trang web của bạn là HTTPS ở mọi nơi bạn có thể sử dụng ID phiên TLS để theo dõi phiên của người dùng


1
Câu hỏi ở đây là như thế nào?
user455318

-2
  1. tạo một plugin giả đa nền tảng (nsapi) và tạo một tên duy nhất cho tên hoặc phiên bản plugin khi người dùng tải xuống (ví dụ sau khi đăng nhập).
  2. cung cấp trình cài đặt cho plugin / cài đặt nó theo chính sách

điều này sẽ yêu cầu người dùng sẵn sàng cài đặt định danh.

Khi plugin được cài đặt, dấu vân tay của bất kỳ trình duyệt (đã bật plugin) nào sẽ chứa plugin cụ thể này. Để trả lại thông tin cho máy chủ, cần có một thuật toán để phát hiện hiệu quả plugin ở phía máy khách, nếu không, người dùng IE và Firefox> = 28 sẽ cần một bảng xác định hợp lệ có thể.

Điều này đòi hỏi một khoản đầu tư tương đối cao vào một công nghệ có khả năng sẽ bị các nhà cung cấp trình duyệt ngừng hoạt động. Khi bạn có thể thuyết phục người dùng của mình cài đặt plugin, cũng có thể có các tùy chọn như cài đặt proxy cục bộ , sử dụng vpn hoặc vá các trình điều khiển mạng.

Người dùng không muốn được xác định (hoặc máy của họ) sẽ luôn tìm cách ngăn chặn.


Chào mừng bạn đến với chồng tràn. Xin lưu ý; this will require the user to willingly install the identifier.có lẽ không phải là những gì các poster ban đầu (OP) có nghĩa.
Stefan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.