Çerezler veya yerel depolama olmadan kullanıcı tanıma


132

Bir analitik araç oluşturuyorum ve şu anda kullanıcının IP adresini, tarayıcısını ve işletim sistemini kullanıcı aracısından alabiliyorum.

Çerezler veya yerel depolama kullanmadan aynı kullanıcıyı tespit etme olasılığı olup olmadığını merak ediyorum. Burada kod örnekleri beklemiyorum; daha fazla nereye bakacağınıza dair basit bir ipucu.

Aynı bilgisayar / cihazsa, tarayıcılar arası uyumlu olması gerektiğini söylemeyi unuttum. Temelde ben cihaz tanımanın peşindeyim, aslında kullanıcı değil.


5
Gerçekten değil - en azından doğru olacağına güvenebileceğiniz herhangi bir yol. Belki üçünün de bir karması, ancak bir evde birden fazla kişi aynı tarayıcıyı ve işletim sistemini kullanıyorsa, yine de işe yaramaz. Ayrıca, çoğu ISS, Dinamik IP adresleri sağlar; bu, her zaman değiştikleri ve tanımlama amacıyla da güvenilemeyecekleri anlamına gelir.
Jon

2
O zaman seansların ne olduğunu bilmiyorsun. Kullanım durumunuz, tam olarak oturumların tasarlandığı şeydir. Oturumların oturum açma veya kimlik doğrulama ile hiçbir ilgisi yoktur. Web sunucunuz bir istemciye oturum tanımlayıcılı bir tanımlama bilgisi göndermesini söyleyecektir. Bu müşteriyi size gönderdikleri oturum kimliğini kullanarak tanımlarsınız.
Man Vs Code

4
Çerezler yine de çalışır mı? Çerezleri kullanmaktan neden kaçınıyorsunuz?
Baba

2
Gerçekten basit ve her zaman kullanıyorum, kullanıcıdan bir kullanıcı adı ve şifre girmesini istiyorum !!!
Amit Kriplani

2
İşte minimal bir javascript çözümü (bu durumda tarayıcılar arası olmayan): github.com/carlo/jquery-browser-fingerprint Bundan bahsediyorum, çünkü bu bana birçok eklentinin varsayılan olarak tarayıcılar arası yüklü olduğu fikrine götürdü. kullanıcı tarafında herhangi bir seçim. Bunları dikkatlice sıralamak (ki bu küçük bir görev değil, ancak yine de ...), daha büyük bir cihaz tabanlı parmak izinin somut bir tarayıcıdan bağımsız özelliğine yol açabilir.
hexalys

Yanıtlar:


390

Giriş

Sizi doğru anlarsam, Benzersiz Tanımlayıcınız olmayan bir kullanıcıyı belirlemeniz gerekir, bu nedenle Rastgele Verileri eşleştirerek kim olduklarını bulmak istersiniz. Kullanıcının kimliğini güvenilir şekilde saklayamazsınız çünkü:

  • Çerezler silinebilir
  • IP adresi değişebilir
  • Tarayıcı Değiştirebilir
  • Tarayıcı Önbelleği silinebilir

Bir Java Uygulaması veya Com Nesnesi, bir donanım bilgisi karması kullanarak kolay bir çözüm olabilirdi, ancak günümüzde insanlar o kadar güvenlik bilincindedir ki, bu tür programları sistemlerine kurmaları zor olacaktır. Bu, sizi Çerezleri ve diğer benzer araçları kullanmaya mecbur bırakır.

Çerezler ve diğer benzer araçlar

Bir Veri Profili oluşturmayı ve ardından bir Olası Kullanıcıyı belirlemek için Olasılık testlerini kullanmayı düşünebilirsiniz . Bunun için yararlı bir profil, aşağıdakilerin bir kombinasyonu ile oluşturulabilir:

  1. IP adresi
    • Gerçek IP Adresi
    • Proxy IP Adresi (kullanıcılar genellikle aynı proxy'yi tekrar tekrar kullanır)
  2. Kurabiye
  3. Web Hataları (daha az güvenilir çünkü hatalar giderilir, ancak yine de yararlıdır)
    • PDF Hatası
    • Flaş Hata
    • Java Hatası
  4. Tarayıcılar
    • Tıklama İzleme (birçok kullanıcı her ziyarette aynı sayfa serisini ziyaret eder)
    • Tarayıcılar Parmak İzi - Yüklü Eklentiler (insanlar genellikle çeşitli, biraz benzersiz eklenti setlerine sahiptir)
    • Önbelleğe Alınmış Görüntüler (insanlar bazen çerezlerini siler ancak önbelleğe alınmış görüntüleri bırakır)
    • Blobları Kullanma
    • URL (ler) (tarayıcı geçmişi veya çerezler, https://stackoverflow.com/users/1226894 veya http://www.facebook.com/barackobama?fref=ts gibi URL'lerde benzersiz kullanıcı kimlikleri içerebilir )
    • Sistem Yazı Tipleri Algılama (bu, az bilinen ancak genellikle benzersiz bir anahtar imzasıdır)
  5. HTML5 ve Javascript
    • HTML5 LocalStorage
    • HTML5 Geolocation API ve Ters Coğrafi Kodlama
    • Mimari, İşletim Sistemi Dili, Sistem Saati, Ekran Çözünürlüğü vb.
    • Network Information API
    • Pil Durumu API

Listelediğim öğeler, elbette, bir kullanıcının benzersiz bir şekilde tanımlanmasının yalnızca birkaç olası yolu. Daha çok var.

Veri Profili oluşturmak için bu Rastgele Veri öğeleri kümesiyle, sırada ne var?

Bir sonraki adım, biraz Bulanık Mantık veya daha iyisi Yapay Sinir Ağı (bulanık mantık kullanan) geliştirmektir. Her iki durumda da fikir, sisteminizi eğitmek ve ardından sonuçlarınızın doğruluğunu artırmak için eğitimini Bayesian Çıkarımı ile birleştirmektir .

Yapay Sinir Ağı

NeuralMesh PHP için kütüphane size Yapay Sinir Ağları oluşturmasına olanak sağlar. Bayes Çıkarımını uygulamak için aşağıdaki bağlantılara göz atın:

Bu noktada şunları düşünüyor olabilirsiniz:

Görünüşte basit bir görev için neden bu kadar Matematik ve Mantık?

Temel olarak, çünkü bu basit bir görev değil . Başarmaya çalıştığınız şey aslında Saf Olasılıktır . Örneğin, aşağıdaki bilinen kullanıcılar verildiğinde:

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

Aşağıdaki verileri aldığınızda:

B + C + E + G + F + K

Esasen sorduğunuz soru şudur:

Alınan verilerin (B + C + E + G + F + K) gerçekte Kullanıcı1 veya Kullanıcı2 olma olasılığı nedir? Ve bu iki maçtan hangisi en olası?

Bu soruyu etkili bir şekilde yanıtlayabilmek için, Frekansa karşı Olasılık Biçimini ve Ortak Olasılığın neden daha iyi bir yaklaşım olabileceğini anlamanız gerekir . Ayrıntılar buraya girmek için çok fazla (bu yüzden size bağlantılar veriyorum), ancak buna iyi bir örnek Tıbbi Teşhis Sihirbazı Başvurusu olabilir. olası hastalıkları tanımlamak için semptomların bir kombinasyonunu kullanan bir olabilir.

Veri Profilinizi (yukarıdaki örnekte B + C + E + G + F + K) Semptomlar ve Hastalık Olarak Bilinmeyen Kullanıcılar olarak oluşturan veri noktaları serisini bir an için düşünün . Hastalığı tanımlayarak, uygun bir tedaviyi daha da tanımlayabilirsiniz (bu kullanıcıyı Kullanıcı1 olarak ele alın).

Açıkçası, 1'den fazla Semptom belirlediğimiz bir Hastalığın tanımlanması daha kolaydır. Aslında, daha fazla Semptom belirledikçe, teşhisimizin daha kolay ve daha doğru olacağı neredeyse kesindir.

Başka alternatif var mı?

Elbette. Alternatif bir önlem olarak, kendi basit puanlama algoritmanızı oluşturabilir ve bunu tam eşleşmelere dayandırabilirsiniz. Bu, olasılık kadar verimli değildir, ancak uygulaması sizin için daha basit olabilir.

Örnek olarak, şu basit puan çizelgesini düşünün:

+ ------------------------- + -------- + ------------ +
| Emlak | Ağırlık | Önemi |
+ ------------------------- + -------- + ------------ +
| Gerçek IP adresi | 60 | 5 |
| Kullanılan proxy IP adresi | 40 | 4 |
| HTTP Çerezleri | 80 | 8 |
| Oturum Çerezleri | 80 | 6 |
| 3. Taraf Çerezleri | 60 | 4 |
| Flash Çerezler | 90 | 7 |
| PDF Hatası | 20 | 1 |
| Flaş Hata | 20 | 1 |
| Java Hatası | 20 | 1 |
| Sık Sayfalar | 40 | 1 |
| Tarayıcılar Parmak İzi | 35 | 2 |
| Yüklü Eklentiler | 25 | 1 |
| Önbelleğe Alınan Resimler | 40 | 3 |
| URL | 60 | 4 |
| Sistem Yazı Tipleri Algılama | 70 | 4 |
| Yerel depolama | 90 | 8 |
| Coğrafi Konum | 70 | 6 |
| AOLTR | 70 | 4 |
| Ağ Bilgileri API | 40 | 3 |
| Pil Durumu API | 20 | 1 |
+ ------------------------- + -------- + ------------ +

Belirli bir talep üzerine toplamak bilgi her parça için, ödül ilişkili puanı, daha sonra kullanmak Önemi puanları aynı olduğunda çözmek çatışmalar.

Kavramın ispatı

Basit bir kavram kanıtı için lütfen Perceptron'a bir göz atın . Perceptron, genellikle örüntü tanıma uygulamalarında kullanılan bir RNA Modelidir . Hatta onu mükemmel bir şekilde uygulayan eski bir PHP Sınıfı vardır, ancak muhtemelen amaçlarınız için onu değiştirmeniz gerekecektir.

Harika bir araç olmasına rağmen, Perceptron yine de birden fazla sonuç (olası eşleşmeler) döndürebilir, bu nedenle bir Puan ve Fark karşılaştırması kullanmak , bu eşleşmelerin en iyisini belirlemek için yine de yararlıdır .

Varsayımlar

  • Her kullanıcıyla ilgili olası tüm bilgileri (IP, çerezler vb.) Saklayın.
  • Sonuç tam bir eşleşme olduğunda, puanı 1 artırın
  • Sonucun tam eşleşme olmadığı durumlarda, puanı 1 azaltın

beklenti

  1. RNA etiketleri oluşturun
  2. Veritabanını taklit eden rastgele kullanıcılar oluşturun
  3. Tek bir Bilinmeyen kullanıcı oluşturun
  4. Bilinmeyen Kullanıcı RNA'sı ve Değerleri Oluşturun
  5. Sistem, RNA bilgilerini birleştirecek ve Perceptron'u öğretecektir.
  6. Perceptron'u eğittikten sonra, sistem bir dizi ağırlığa sahip olacaktır.
  7. Artık Bilinmeyen kullanıcının modelini test edebilirsiniz ve Perceptron bir sonuç kümesi oluşturacaktır.
  8. Tüm Pozitif eşleşmeleri sakla
  9. Eşleşmeleri önce Skor'a, ardından Farka göre sıralayın (yukarıda açıklandığı gibi)
  10. En yakın iki eşleşmenin çıktısını alın veya hiçbir eşleşme bulunamazsa boş sonuçlar verir

Kavram Kanıtı Kodu

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

Çıktı:

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

"D" için 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
)

Hata Ayıklama = true ise Giriş (Sensör ve İstenen), Başlangıç ​​Ağırlıkları, Çıktı (Sensör, Toplam, Ağ), Hata, Düzeltme ve Son Ağırlıkları görebilirsiniz .

+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
| 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, kod tarafından dönüştürülen özellikleri temsil eder.

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

İşte çevrimiçi bir demo

Kullanılan Sınıf:

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

Değiştirilmiş Perceptron Sınıfı

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

Sonuç

Benzersiz Tanımlayıcı olmadan bir kullanıcıyı tanımlamak, basit veya basit bir iş değildir. kullanıcıdan çeşitli yöntemlerle toplayabileceğiniz yeterli miktarda Rastgele Verinin toplanmasına bağlıdır.

Yapay Sinir Ağını kullanmamayı seçseniz bile, en azından öncelikleri ve olasılıkları olan Basit Olasılık Matrisi kullanmanızı öneririm - umarım yukarıda verilen kod ve örnekler size devam etmek için yeterince verir.


@Baba Bir tarayıcının parmak izini almak için "Blobları Kullanmak" ile ne demek istiyorsun?
billmalarky


1
@Baba Bir tarayıcının parmak izini almak için nasıl kullanılır? Herhangi bir zamanda içinde şu anda ne olduğunu kontrol edin.
billmalarky

@Baba harika bir iş, bir kullanıcıyı tanımlamak için her zaman çok seviyeli bir stratejiye sahip olmaya çalıştım, ancak dediğiniz gibi önbellek temizlenebilir, IP'ler değiştirilebilir, proxy'lerin veya NAT'ın arkasındaki kullanıcılar - özellikle bu insanlar -, çerezler silindi, vb. . ama tüm bu kadar çabayla bile, mesela kötü kullanıcı Tor tarayıcısını kullanıyorsa , bahsedilen tespit stratejilerinin tümü olmasa da çoğu işe yaramayacaktır. Browserleaks.com'u sevdim ama Tor ile hepsi tanımsız veya bilinmeyen geri döndü
Mi-Creativity

Sadece bir yayının bu cevherinden "biraz toz çıkarmak" için tasarlanmış bir Not : 07.09.17 itibariyle bozuk bağlantıların listesi: - Implement Bayesian inference using PHP, 3 bölümün tümü. - Frequency vs Probability - Joint Probability -Input (Sensor & Desired), Initial Weights, Output (Sensor, Sum, Network), Error, Correction and Final Weights
Ziezi

28

Bu teknik (aynı kullanıcıları çerezler olmadan veya hatta ip adresi olmadan tespit etmek için), tarayıcı parmak izi olarak adlandırılır . Temel olarak, tarayıcı hakkında olabildiğince bilgi olarak tararsınız - javascript, flash veya java (ör. Yüklü uzantılar, yazı tipleri vb.) İle daha iyi sonuçlar elde edilebilir. Bundan sonra, isterseniz sonuçları hashlenmiş olarak saklayabilirsiniz.

Hatasız değil ama:

Görülen tarayıcıların% 83,6'sının benzersiz bir parmak izi vardı; Flash veya Java etkin olanlar arasında% 94,2. Bu çerezleri içermez!

Daha fazla bilgi:


bence hala cevap bu. Bir cihazı tanımlamanız gerekiyorsa, yalnızca bu verileri almanız gerekir - f.ex. İşletim sistemi, genel uzantılar (ve sürümleri), yüklü yazı tipleri, vb.
pozs

Bu pek işe yaramayacak. Her tarayıcı, oturumları ve çerezleri destekler. İş için doğru aracı kullanın.
Man Vs Code

1
@ slash197 dosya önbelleği ne olacak? 1px x 1px şeffaf flash ortamı ve içinde benzersiz bir oluşturulmuş kimliği tutan bir xml dosyası (xml, kullanıcı yerel HD'ye indirilmeden önce sunucuda bir kez oluşturulmalıdır) bu şekilde, kullanıcı çerezleri silse veya oturumu kapatsa bile, sendAndLoad eylem betiğini kullanarak hala bir köprünüz olabilir.
Mbarry

Minimum değişiklik, karma sonucunu etkileyecektir. örneğin şok dalgası oynatıcısının versiyonu. Yerel olarak depolanan xml önbellek dosyası ile benzersiz anahtar oluşturulmuş + tarayıcıda gizli 1px x 1px flash medyası (eylem betiği) ile olası çözüm, bu şekilde çerezlerden kurtulursunuz, ana sorun buysa oturum sona erme sorunu. Hala sql veritabanınız ile kullanıcının yerel makinesindeki anahtar arasında köprü kurabilirsiniz.
Mbarry

@Mbarry Pek bir flash hayranı değilim ama tarayıcıda 1x1 piksel flash medyam devre dışı bırakılacakmış gibi bir flash engelleme eklentisi varsa, acaba acaba?
slash197

7

Yukarıda bahsedilen parmak izi işe yarar, ancak yine de çarpışmalara maruz kalabilir.

Bir yol, kullanıcıyla her etkileşimin url'sine UID eklemektir.

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

Sitedeki her bağlantının bu değiştiriciyle uyarlandığı yer. Sayfalar arasında FORM verilerini kullanarak çalışmak için ASP.Net'in kullandığı yönteme benzer.


Bunu düşündüm ama bir kullanıcının onu değiştirmesinin en kolay yolu bu
slash197

1
kimliğin değil, kendine referans veren bir karmadır. Kriptografik olarak güvenli hale getirir.
Justin Alexander

Ayrıca, birileri siteye göz atarken bu yöntem uygundur, ancak geri dönen bir kullanıcı bir hafta sonra geri döndüğünde ve web sitesi adresini id olmadan basitçe yazdığında durumu nasıl ele almanızı önerirsiniz?
slash197

1
@ slash197 bu durumda neden kullanıcıya oturum açmasını söylemiyorsunuz, kullanıcı çerezleri silse bile ne olur?
Akash Kava

6

Baktın mı Evercookie ? Tarayıcılar arasında çalışabilir veya çalışmayabilir. Sitelerinden bir alıntı.

"Bir kullanıcı bir tarayıcıda pişirilir ve başka bir tarayıcıya geçerse, Yerel Paylaşılan Nesne tanımlama bilgisine sahip olduğu sürece, tanımlama bilgisi her iki tarayıcıda da çoğalacaktır."


JavaScript devre dışıyken çalışıp çalışmadığını merak ediyorum. Hiç tecrüben var mı?
Voitcus

Bir sebepten dolayı buna evercookie denir, ne olursa olsun işe yarayacak. Çerezi kaldırmaları neredeyse imkansızdır.
Alexis Tyler

Ne olursa olsun işe yaramayacak. Açıklamanın ilk satırından: 'evercookie bir javascript API'sidir ...'. Javascript devre dışı bırakılırsa çalışmaz.
gdw2

Hatta js'nin devre dışı bırakılması gerekmez. Ghostery ve uBlock evercookie'yi düşürüyor
opengrid

3

Bunu önbelleğe alınmış bir png ile yapabilirsiniz, biraz güvenilmez olacaktır (farklı tarayıcılar farklı davranır ve kullanıcı önbelleğini temizlerse başarısız olur), ancak bu bir seçenek.

1: Benzersiz bir kullanıcı kimliğini onaltılık bir dize olarak depolayan bir Veritabanı kurun

2: bir kullanıcı kimliği oluşturan bir genUser.php (veya herhangi bir dil) dosyası oluşturun, bunu DB'de saklar ve ardından bu hex dizesinin değerlerinden gerçek bir renk .png oluşturur (her piksel 4 bayt olacaktır) ve geri dönün bu tarayıcıya. İçerik türünü ve önbellek başlıklarını ayarladığınızdan emin olun.

3: HTML veya JS'de aşağıdaki gibi bir görüntü oluşturun <img id='user_id' src='genUser.php' />

4: Bu görüntüyü bir tuvale çizin ctx.drawImage(document.getElementById('user_id'), 0, 0);

5: bu görüntünün baytlarını kullanarak ctx.getImageData tam sayıları bir onaltılık dizeye dönüştürün.

6: Bu, artık kullanıcılarınızın bilgisayarında önbelleğe alınan benzersiz kullanıcı kimliğinizdir.


Kullanıcıyı "tarayıcılar arasında" izleyebilen ve burada çalışmayacak bir şey istiyor (her tarayıcının kendi önbellek veritabanı vardır).
EricLaw

Bunu nerede görüyorsunuz, sorusu yalnızca "Tarayıcılar arası uyumlu olması gerektiğini söylemeyi unuttum", yani herhangi bir tarayıcıda çalışmanızı ister.
hobberwickey

Sorusu kötü yazılmış. I'm after device recognitionistediği şeyin eşantiyonudur ve burada ayrıntılarını açıklamaktadır: stackoverflow.com/questions/15966812/…
EricLaw

2

Söylediklerinize göre:

Temelde ben cihaz tanımanın peşindeyim, aslında kullanıcı değil

Bunu yapmanın en iyi yolu, NIC Kimliği olan mac adresini göndermektir.

Şu gönderiye bir göz atabilirsiniz: PHP'de bağlı bir istemcinin MAC ve IP adresini nasıl alabilirim?


Üzgünüz, ancak NIC ID kolay sahteciliktir. Kesinlikle en iyi yol değil.
asgs

@asgs tarayıcı parmak izi belki daha iyi olabilir ya da size göre en iyi yol nedir?
Mehdi Karamosly

En iyi yolu yok, işin üzücü kısmı bu. Bununla birlikte, Baba'nın yukarıda sunduğu Olasılık çalışmasıyla birlikte bu ve Tarayıcı Parmak İzi baskısı bence en iyisi olacaktır.
asgs

1

Bunu etags ile yapabilirsiniz. Bununla birlikte, bu yasal olarak bir grup dava açılmış mı emin değilim.

Kullanıcılarınızı gerektiği gibi uyarırsanız veya intranet web sitesi gibi bir şeyiniz varsa sorun olmayabilir.


Etag'ler tarayıcılar arası uyumlu değildir.
slash197

1
Etag'ler, HTTP / 1.1 spesifikasyonunun bir parçasıdır. Tüm popüler tarayıcılar etag'leri destekler, ETag / If-None-Match başlıklarını desteklememek için kendi tarayıcınızı yazmanız gerekir.
Brian McGinity

Desteklemediğini söylemedim, tarayıcılar arası uyumlu olmadığını söyledim. Firefox'ta bir etiket kaydedilirse, Chrome'da mevcut değildir, bu nedenle önbellek olmadığı için içerik yeniden indirilir.
slash197

Şimdi ne dediğini anlıyorum. Haklısın. Her tarayıcının kendi önbellek deposu, dolayısıyla farklı etag'ler vardır.
Brian McGinity


0

Verimsizdir, ancak size istenen sonuçları verebilir, sizin tarafınızdan bir API yoklamak olacaktır. İstemci tarafında, kullanıcı verilerini belirli aralıklarla gönderen bir arka plan işlemine sahip olun. API'nize göndermek için bir kullanıcı tanımlayıcıya ihtiyacınız olacak. Bunu aldıktan sonra, bu benzersiz tanımlayıcıyla ilişkili herhangi bir bilgiyi gönderebilirsiniz.

Bu, tanımlama bilgileri ve yerel depolama ihtiyacını ortadan kaldırır.


0

İnanamıyorum, http://browserspy.dk hala burada bahsedilmemiştir! Site, bir sınıflandırıcı oluşturmak için kullanılabilecek birçok özelliği (örüntü tanıma açısından) açıklamaktadır.

Ve bu nedenle, özellikleri değerlendirmek için, Destek Vektör Makinelerini ve özellikle libsvm'yi öneririm .


0

Onları bir oturum sırasında mı yoksa oturumlar arasında mı takip ediyorsunuz?

Siteniz HTTPS Everywhere ise, kullanıcının oturumunu izlemek için TLS Oturum Kimliğini kullanabilirsiniz.


1
buradaki soru nasıl?
user455318

-2
  1. bir çapraz platform kukla (nsapi) eklentisi oluşturun ve eklenti adı veya sürümü için kullanıcı onu indirdiğinde (örneğin oturum açtıktan sonra) benzersiz bir ad oluşturun.
  2. eklenti için bir yükleyici sağlayın / politikaya göre kurun

bu, kullanıcının tanımlayıcıyı isteyerek yüklemesini gerektirir.

Eklenti yüklendikten sonra , herhangi bir (eklenti etkin) tarayıcının parmak izi bu belirli eklentiyi içerecektir. Bilgiyi bir sunucuya döndürmek için, eklentiyi istemci tarafında etkili bir şekilde tespit etmek için bir algoritma gereklidir, aksi takdirde IE ve Firefox> = 28 kullanıcıları, olası geçerli tanımlamalar tablosuna ihtiyaç duyacaktır.

Bu, tarayıcı satıcıları tarafından muhtemelen kapatılacak olan bir teknolojiye nispeten yüksek bir yatırım gerektirir. Kullanıcılarınızı bir eklenti yüklemeye ikna edebildiğinizde, yerel bir proxy yükleme , vpn kullanma veya ağ sürücülerini yama gibi seçenekler de olabilir .

Tanımlanmak istemeyen kullanıcılar (veya makineleri) her zaman bunu engellemenin bir yolunu bulacaktır.


Merhaba, taşma yığınına hoş geldiniz. Lütfen aklınızda bulundurun; this will require the user to willingly install the identifier.muhtemelen orijinal afişin (OP) kastettiği şey değildir.
Stefan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.