localstorage expires encriptar ejemplos cookie check javascript php http-headers fingerprinting

javascript - expires - local storage vs cookies



Reconocimiento de usuario sin cookies o almacenamiento local (12)

Estoy construyendo una herramienta analítica y actualmente puedo obtener la dirección IP del usuario, el navegador y el sistema operativo de su agente de usuario.

Me pregunto si existe la posibilidad de detectar al mismo usuario sin usar cookies o almacenamiento local. No estoy esperando ejemplos de código aquí; solo un simple indicio de dónde buscar más.

Se olvidó de mencionar que necesitaría ser compatible con varios navegadores si se trata de la misma computadora / dispositivo. Básicamente, estoy buscando el reconocimiento del dispositivo que realmente no es el usuario.


  1. cree un complemento ficticio multiplataforma (nsapi) y genere un nombre único para el nombre o la versión del complemento cuando el usuario lo descargue (por ejemplo, después del inicio de sesión).
  2. proporcionar un instalador para el complemento / instalarlo por política

esto requerirá que el usuario instale voluntariamente el identificador.

una vez que se instala el complemento, la fingerprint de cualquier navegador (habilitado para el complemento) contendrá este complemento específico. Para devolver la información a un servidor, se necesita un algoritmo para detectar eficazmente el complemento en el lado del cliente; de ​​lo contrario, los usuarios de IE y Firefox> = 28 necesitarán una tabla de posibles identificaciones válidas.

Esto requiere una inversión relativamente alta en una tecnología que probablemente será cerrada por los proveedores de navegadores. Cuando puede convencer a sus usuarios de que instalen un complemento, también puede haber opciones como instalar un proxy local , usar vpn o parchear los controladores de red.

Los usuarios que no desean ser identificados (o sus máquinas) siempre encontrarán la manera de prevenirlo.


¿Has Evercookie a Evercookie ? Puede funcionar o no en todos los navegadores. Un extracto de su sitio.

"Si un usuario obtiene Cookies en un navegador y cambia a otro navegador, siempre y cuando aún tenga la cookie Local Shared Object, la cookie se reproducirá en ambos buscadores".


¿Seguirlos durante una sesión o durante las sesiones?

Si su sitio es HTTPS en cualquier lugar, puede usar la ID de sesión de TLS para rastrear la sesión del usuario.



Esta técnica (para detectar los mismos usuarios sin cookies, o incluso sin dirección IP) se denomina huella digital del navegador . Básicamente rastrea la información sobre el navegador lo más que pueda: se pueden obtener mejores resultados con javascript, flash o java (por ejemplo, extensiones instaladas, fuentes, etc.). Después de eso, puede almacenar los resultados hash, si lo desea.

No es infalible, pero:

El 83.6% de los navegadores vistos tenían una huella digital única; entre aquellos con Flash o Java habilitados, 94.2%. ¡Esto no incluye cookies!

Más información:


Ineficiente, pero puede darte los resultados deseados, sería sondear una API de tu lado. Tenga un proceso de fondo en el lado del cliente que envíe datos de usuario en un intervalo. Necesitará un identificador de usuario para enviar a su API. Una vez que tenga eso, puede enviar toda la información asociada a ese identificador único.

Esto elimina la necesidad de cookies y almacenamiento local.


La huella digital mencionada anteriormente funciona, pero aún puede sufrir colisiones.

Una forma es agregar UID a la url de cada interacción con el usuario.

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

Donde cada enlace en el sitio se adapta con este modificador. Es similar a la forma en que ASP.Net solía trabajar utilizando datos FORM entre páginas.


No puedo creer que http://browserspy.dk aún no haya sido mencionado aquí! El sitio describe muchas características (en términos de reconocimiento de patrones), que podrían usarse para construir un clasificador.

Y por eso, para evaluar las características, sugeriría Support Vector Machines y libsvm en particular.



Podrías hacer esto con un png almacenado en caché, sería poco confiable (los diferentes navegadores se comportan de manera diferente, y fallará si el usuario borra su caché), pero es una opción.

1: configurar una base de datos que almacena una identificación de usuario única como una cadena hexadecimal

2: crea un archivo genUser.php (o cualquier otro idioma) que genere un ID de usuario, lo almacene en el DB y luego cree un color verdadero .png fuera de los valores de esa cadena hexadecimal (cada píxel será de 4 bytes) y devuelve eso al navegador. Asegúrese de establecer el tipo de contenido y los encabezados de la caché.

3: en el HTML o JS crea una imagen como <img id=''user_id'' src=''genUser.php'' />

4: dibuje esa imagen en un lienzo ctx.drawImage(document.getElementById(''user_id''), 0, 0);

5: lea los bytes de esa imagen usando ctx.getImageData , y convierta los enteros en una cadena hexadecimal.

6: Esa es su identificación de usuario única que ahora está almacenada en caché en la computadora de los usuarios.


Puedes hacerlo con etags. Aunque no estoy seguro de si este legal como un grupo de demandas fueron presentadas.

Si advierte adecuadamente a sus usuarios o si tiene algo así como un sitio web de intranet, podría estar bien.


Introducción

Si te entiendo correctamente, debes identificar a un usuario para el que no tienes un identificador único, por lo que quieres saber quiénes son al hacer coincidir los datos aleatorios. No puede almacenar la identidad del usuario de manera confiable porque:

  • Las cookies se pueden eliminar
  • La dirección IP puede cambiar
  • El navegador puede cambiar
  • La memoria caché del navegador puede ser eliminada

Un applet o un objeto Com de Java habría sido una solución fácil utilizando un hash de información de hardware, pero en estos días las personas son tan conscientes de la seguridad que sería difícil hacer que la gente instale este tipo de programas en su sistema. Esto te deja atrapado con el uso de cookies y otras herramientas similares.

Cookies y otras herramientas similares

Puede considerar construir un perfil de datos y luego usar pruebas de probabilidad para identificar a un usuario probable . Un perfil útil para esto se puede generar mediante una combinación de los siguientes:

  1. Dirección IP
    • Dirección IP real
    • Dirección IP Proxy (los usuarios a menudo usan el mismo proxy repetidamente)
  2. Galletas
  3. Web Bugs (menos confiable porque los errores se solucionan, pero aún son útiles)
    • PDF error
    • Error de Flash
    • Error de Java
  4. Navegadores
    • Haga clic en Seguimiento (muchos usuarios visitan la misma serie de páginas en cada visita)
    • Huellas dactilares de navegadores - Complementos instalados (las personas suelen tener conjuntos de plugins variados y un tanto únicos)
    • Imágenes en caché (a veces las personas eliminan sus cookies pero dejan imágenes en caché)
    • Usando Blobs
    • URL (s) (el historial del navegador o las cookies pueden contener identificadores de usuario únicos en las URL, como https://.com/users/1226894 o http://www.facebook.com/barackobama?fref=ts )
    • Detección de fuentes del sistema (esta es una firma de clave poco conocida pero a menudo única)
  5. HTML5 y Javascript
    • LocalStorage HTML5
    • API de geolocalización HTML5 y geocodificación inversa
    • Arquitectura, lenguaje del sistema operativo, tiempo del sistema, resolución de pantalla, etc.
    • API de información de red
    • API de estado de la batería

Los elementos que enumeré son, por supuesto, solo algunas formas posibles en que un usuario puede identificarse de manera única. Hay muchos más.

Con este conjunto de elementos de datos aleatorios para construir un perfil de datos, ¿qué sigue?

El siguiente paso es desarrollar alguna lógica difusa o, mejor aún, una red neuronal artificial (que usa lógica difusa). En cualquier caso, la idea es entrenar a su sistema, y ​​luego combinar su entrenamiento con Bayesian Inference para aumentar la precisión de sus resultados.

La biblioteca NeuralMesh para PHP le permite generar Redes Neuronales Artificiales. Para implementar la Inferencia Bayesiana, consulte los siguientes enlaces:

En este punto, puedes estar pensando:

¿Por qué tanto matemáticas y lógica para una tarea aparentemente simple?

Básicamente, porque no es una tarea simple . Lo que estás tratando de lograr es, de hecho, la probabilidad pura . Por ejemplo, dados los siguientes usuarios conocidos:

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

Cuando recibe los siguientes datos:

B + C + E + G + F + K

La pregunta que esencialmente estás preguntando es:

¿Cuál es la probabilidad de que los datos recibidos (B + C + E + G + F + K) sean en realidad Usuario1 o Usuario2? ¿Y cuál de esos dos partidos es más probable?

Para responder eficazmente a esta pregunta, debe comprender el formato de frecuencia frente a la probabilidad y por qué la probabilidad conjunta podría ser un mejor enfoque. Los detalles son demasiado para entrar aquí (por eso le doy enlaces), pero un buen ejemplo sería una aplicación de diagnóstico de diagnóstico médico , que utiliza una combinación de síntomas para identificar posibles enfermedades.

Piense por un momento en la serie de puntos de datos que componen su Perfil de Datos (B + C + E + G + F + K en el ejemplo anterior) como Síntomas y Usuarios Desconocidos como Enfermedades . Al identificar la enfermedad, puede identificar aún más un tratamiento adecuado (trate a este usuario como Usuario1).

Obviamente, una enfermedad para la cual hemos identificado más de 1 síntoma es más fácil de identificar. De hecho, cuantos más síntomas podamos identificar, más seguro y sencillo será nuestro diagnóstico.

¿Hay otras alternativas?

Por supuesto. Como medida alternativa, puede crear su propio algoritmo de puntuación simple y basarlo en las coincidencias exactas. Esto no es tan eficiente como la probabilidad, pero puede ser más simple de implementar.

Como ejemplo, considere este cuadro de puntuación simple:

+-------------------------+--------+------------+ | 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 | +-------------------------+--------+------------+

Para cada información que pueda recopilar en una solicitud dada, otorgue el puntaje asociado, luego use Importancia para resolver conflictos cuando los puntajes sean los mismos.

Prueba de concepto

Para una simple prueba de concepto, eche un vistazo a Perceptron . Perceptron es un modelo de ARN que generalmente se usa en aplicaciones de reconocimiento de patrones. Incluso hay una antigua clase de PHP que la implementa a la perfección, pero es probable que necesite modificarla para sus propósitos.

A pesar de ser una gran herramienta, Perceptron aún puede devolver resultados múltiples (posibles coincidencias), por lo que utilizar una comparación de Puntuación y Diferencia aún es útil para identificar la mejor de esas coincidencias.

Suposiciones

  • Almacenar toda la información posible sobre cada usuario (IP, cookies, etc.)
  • Donde el resultado es una coincidencia exacta, aumentar el puntaje en 1
  • Donde el resultado no es una coincidencia exacta, disminuya el puntaje en 1

Expectativa

  1. Generar etiquetas de ARN
  2. Generar usuarios aleatorios emulando una base de datos
  3. Genera un solo usuario desconocido
  4. Generar ARN de usuario desconocido y valores
  5. El sistema fusionará la información de ARN y enseñará el Perceptron
  6. Después de entrenar el Perceptron, el sistema tendrá un conjunto de ponderaciones
  7. Ahora puede probar el patrón del usuario Desconocido y Perceptron producirá un conjunto de resultados.
  8. Almacena todas las coincidencias positivas
  9. Clasifique las coincidencias primero por Puntuación, luego por Diferencia (como se describe arriba)
  10. Muestra las dos coincidencias más cercanas o, si no se encuentran coincidencias, muestra resultados vacíos

Código de prueba de concepto

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

Output:

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

Print_r de "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 )

Si Depuración = verdadero, usted podría ver la Entrada (Sensor y Deseado), Pesos iniciales, Salida (Sensor, Suma, Red), Error, Corrección y Pesos finales .

+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+ | 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 a x20 representan las características convertidas por el código.

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

Aquí hay una demostración en línea

Clase utilizada:

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

Clase de perceptrón modificado

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

Conclusión

La identificación de un usuario sin un Identificador Único no es una tarea sencilla o sencilla. depende de la recopilación de una cantidad suficiente de datos aleatorios que usted puede recopilar del usuario mediante una variedad de métodos.

Incluso si elige no utilizar una Red Neural Artificial, sugiero al menos usar una Matriz de Probabilidad Simple con prioridades y probabilidades, y espero que el código y los ejemplos proporcionados anteriormente le den lo suficiente para continuar.