c# - rastrear - tengo una direccion ip quiero saber de donde proviene
Cómo almacenar y buscar una dirección IP (7)
Una dirección IPv6 puede ser un entero sin signo de ocho bytes (un ulong en C #)
Las direcciones IPv6 son de 128 bits (16 bytes), no 8, como se sugiere. Estoy lidiando con este problema en este momento para los rangos de IP.
Estoy buscando probar cadenas rellenas o hexagonales y simplemente hacer <y> comparaciones
Tengo las 4 fuentes de direcciones IP, quiero almacenarlas en SQL Server y permitir que los rangos, que pueden ser categorizados por el código de país de origen, se marquen en una lista de exclusión por país.
Para esto tengo 2 tablas.
IPAddressRange CountryCode
Lo que necesito saber es que si estos datos se devolvieron al cliente y luego se almacenaron en caché para consultas rápidas, ¿cuál es la mejor manera de almacenar los datos devueltos para consultar una dirección IP específica dentro de los rangos? Quiero saber si la dirección IP suministrada está en la lista.
La razón por la que la lista está en el archivo db es para un fácil almacenamiento.
El motivo por el que quiero almacenar en caché y luego utilizar los datos en el cliente es porque he oído que buscar direcciones IP es más rápido en una estructura trie. Entonces, creo que necesito obtener la lista del archivo db, almacenar en el caché en una estructura que es muy rápida de buscar.
Cualquier ayuda en A) La estructura SQL para almacenar las direcciones yb) Código para buscar las direcciones IP.
Conozco una solución de proyecto de código que tiene un algoritmo de código para buscar, no estoy seguro de cómo mezclar esto con el aspecto de almacenamiento.
Idealmente sin el uso de una biblioteca de terceros. El código debe estar en nuestro propio servidor.
He hecho un filtro por país exactamente como lo describes.
Sin embargo, después de experimentar un tiempo, descubrí que no se puede hacer de manera eficiente con SQL. Es por eso que las bases de datos de IP como esta (la que estoy usando) ofrecen una base de datos binaria, que es mucho más rápida porque está optimizada para este tipo de datos.
Incluso dicen explícitamente:
Tenga en cuenta que las consultas realizadas con los datos CSV importados en una base de datos SQL pueden tardar unos segundos. Si el rendimiento es un problema, el formato binario es mucho más rápido y puede manejar miles de búsquedas por segundo.
Además, incluso le dan el código para consultar esta base de datos.
Estoy usando esto en un sitio web de producción con tráfico medio, filtrando cada solicitud, sin problemas de rendimiento.
Nunca lo he intentado, así que tome mi respuesta con un grano de sal, pero creo que un trie no es realmente lo que quiere a menos que tenga la intención de almacenar cada IP que quiera bloquear (en lugar de rangos o subredes / máscaras) . Creo que un btree sería más adecuado, en cuyo caso, simplemente siga adelante y use su base de datos regular (muchas bases de datos se implementan con btrees o estructuras de datos igualmente buenas). Almacenaba cada uno de los 4 bytes de la IP en una columna separada para ayudar en la búsqueda por subredes de clase A / B / C con valores "do not care" igual a NULL, pero no hay ninguna razón por la que no pudiera almacenar como una sola columna entera de 32 bits y crunch los números para averiguar en qué rango debe caer (almacenar valores enmascarados sería marginalmente más complicado en este caso).
Puede hacerlo de manera eficiente siempre que almacene sus direcciones de inicio de IPv4 en el tipo de datos correcto. Un varchar (u otro tipo de cadena) no es correcto; necesita usar un int.
Para IPv4, almacene el número de IP en un unsigned lo suficientemente grande, luego guárdelo como un formato INET_ATON (que es lo suficientemente fácil de generar; no estoy seguro de cómo en C # pero no es difícil).
A continuación, puede buscar de forma fácil y eficiente el rango del que forma parte una dirección IP, haciendo que la base de datos realice un análisis de rango.
Al usar LIMIT (o SELECT TOP 1 en MSSQL) puede hacer que se detenga una vez que encuentra un registro.
SELECT TOP 1 networkidorwhatever, IPNumber, IPNumberUpperBoundOrWhateverYouCallIt
FROM networks
WHERE IPNumber <= IPNUMBERTOQUERY ORDER BY IPNumber DESC
Si encuentra el número de red numerado más alto que es <= el número de IP, entonces es una verificación trivial determinar si esa dirección IP está dentro de él.
Debería ser eficiente siempre que haya un índice convencional en IPNumber.
Para IPv6 los tipos son diferentes pero el principio es el mismo.
Suponiendo que sus direcciones IP son IPV4, puede almacenarlas en un campo entero. Crea 2 campos, uno para el límite inferior del rango y otro para el límite superior. Luego, asegúrese de que estos campos estén indexados. Al buscar valores, solo busca donde el valor es mayor o igual que el límite inferior, y menor o igual que el límite superior. Experimentaría con algo tan simple como esto antes de intentar programar algo más complicado, lo que en realidad no da resultados notablemente más rápidos.
Una dirección IPv4 se puede almacenar como un entero sin signo de cuatro bytes (una uint en C #). Una dirección IPv6 puede ser un entero sin signo de ocho bytes (un ulong en C #). Cree columnas del ancho apropiado en SQL, luego recupérelas y guárdelas en variables. A continuación, usa matemáticas enteras simples para verificar los rangos que desea, suponiendo que los rangos son realmente contiguos.
Una solución más elaborada sería crear una clase IPAddress que le brinde acceso a la estructura más conocida de dot-quad, pero bajo las cubiertas haría exactamente lo mismo que tiene aquí.
Para IPv4, normalmente un DBA recomendaría 4 campos tinyint pero está haciendo rangos, que se prestan más a las soluciones de almacenamiento de números enteros proporcionadas anteriormente. En ese caso, almacenaría una dirección IP inicial y una dirección IP final para el rango. Entonces, es una simple cuestión hacer la comparación.