infostabil > edb.internet.* > edb.internet.webdesign.serverside.php

Arne Vajhøj (16.05.2020, 18:12)
On 5/16/2020 11:38 AM, Jan Hansen wrote:
> Bertel Lund Hansen skrev:
> Der er nu stadigvæk ikke liv, når jeg eller
> [..] prøver.
> Men [..] og
> [..]
> siger der er liv, så jeg må åbenbart være banned på den side.
> Men er deres data så præcise, så det kan bruges? Jeg kan se på
> [..] at der er 2 "Unknown country code"
> Maxmind og ip2location siger samstemmende, at
> 109.232.2.118 = Iran
> 193.36.116.142 = Danmark


Geolocation er aldrig 100% præcis.

For land så er en lav kvalitet database vel
omkring 95% korrekt og en god kvalitet database
vel omkring 99% korrekt.

Lidt lavere procenter for delstat/provins og by.

Arne
Bertel Lund Hansen (16.05.2020, 18:13)
Jan Hansen skrev:

> Jeg har forsøgt at sætte en banned_intervals.inc.php sammen ud
> fra ip2location's data, [..]
> klik på de lande, der skal bannes og tryk på knappen.
> Ligner output din fil?


Nej. Jeg laver min banned-fil i tre trin:

1. Saml alle enkeltfiler i et langt array.

2. Sorter filen (efter ip-numerisk værdi) og komprimer den (så
nabointervaller slås sammen). Format uændret:

5.10.78.16-5.10.78.23
5.32.128.0-5.32.135.255
5.53.128.0-5.53.255.255

3. Omsæt alle ip-adresser til deres numeriske værdi, og gem
arrayet som en include-fil. Format:

<?php
$banned_intervals = [
[16777472,16778239],
[16779264,16809983],
[16842752,16843007],

3-formatet giver den hurtigste søgning, og med binær søgning går
det rigtig tjep.

Derudover laver jeg numeriske filer for hver nations-fil så
statistikprogrammets søgning efter nationalitetskode også kan gå
stærkt. Format:

84561424-84561431
86016000-86018047
87392256-87425023
Bertel Lund Hansen (16.05.2020, 18:44)
Jan Hansen skrev:

> Men er deres data så præcise, så det kan bruges? Jeg kan se på
> [..] at der er 2 "Unknown country code"
> Maxmind og ip2location siger samstemmende, at
> 109.232.2.118 = Iran
> 193.36.116.142 = Danmark


Iran har jeg ikke implementeret endnu. Jeg har kun de
nationaliteter som er dukket op.

Det med Danmark er en fejl. De siger på websiden at de gratis
data opdateres med 90 dages forsinkelse. Når jeg finder et hul
som det du omtaler, slår jeg intervallet op på websiden (det
oplyses når man søger på et enkelt IP-nummer) og tilføjer det
manuelt til min fil.
Jan Hansen (16.05.2020, 18:46)
Bertel Lund Hansen skrev:

> 3. Omsæt alle ip-adresser til deres numeriske værdi, og gem
> arrayet som en include-fil. Format:
> <?php
> $banned_intervals = [
> [16777472,16778239],
> [16779264,16809983],
> [16842752,16843007],
> 3-formatet giver den hurtigste søgning, og med binær søgning går
> det rigtig tjep.

Ups, jeg havde overset, at det ikke skulle skrives som IP. Nu skulle
det gerne være korrekt med de tal, som ip2location lite leverer.
Jan Hansen (16.05.2020, 18:57)
Arne Vajhøj skrev:

> > 109.232.2.118 = Iran
> > 193.36.116.142 = Danmark

> Geolocation er aldrig 100% præcis.
> For land så er en lav kvalitet database vel
> omkring 95% korrekt og en god kvalitet database
> vel omkring 99% korrekt.
> Lidt lavere procenter for delstat/provins og by.


Ja, men de to IP er nu med i de gratis databaser fra Maxmind
og ip2location.
Bertel Lund Hansen (16.05.2020, 19:29)
Jan Hansen skrev:

> Ups, jeg havde overset, at det ikke skulle skrives som IP. Nu skulle
> det gerne være korrekt med de tal, som ip2location lite leverer.


Ja, det er de. Du har lidt flere linjer end der er i mine filer,
men det kan være fordi du har bedre data.
Jan Hansen (16.05.2020, 19:42)
Bertel Lund Hansen skrev:

> Derudover laver jeg numeriske filer for hver nations-fil så
> statistikprogrammets søgning efter nationalitetskode også kan gå
> stærkt.


Det var smart. Når langt de fleste er danskere, er det til at
tjekke dem først. Hvis ikke der er bid, er det til at includere
noget mere omfattende.
Bertel Lund Hansen (17.05.2020, 11:03)
Jan Hansen skrev:

> Det var smart. Når langt de fleste er danskere, er det til at
> tjekke dem først. Hvis ikke der er bid, er det til at includere
> noget mere omfattende.


Sådan kunne man gøre, men jeg tager dem bare i alfabetisk
rækkefølge.
Bertel Lund Hansen (21.05.2020, 16:39)
Bertel Lund Hansen skrev:

[en hel masse]

Nu har jeg lavet en PHP-version. Den ligger her:

Folder: mine efternavne+dk + access_control
Filnavn: ac_ip_utilities + extension
Indsæt selv diverse skilletegn.

Brug evt. 'viskode'.
Bertel Lund Hansen (21.05.2020, 16:45)
Bertel Lund Hansen skrev:

> Nu har jeg lavet en PHP-version. Den ligger her:


Jeg glemte lige:

Den forudsætter at der ligger IP-lister på formen:

5.10.78.16-5.10.78.23
5.32.128.0-5.32.135.255
5.53.128.0-5.53.255.255

i en folder der hedder:

ipdata_files_originals

Resten af filer og mapper kan scriptet selv lave.

Største forbedring er at det nu kan sammenligne alle de
tilgængelige komprimerede IP-filer og finde overlap imellem dem.

Det undrer mig at den kører så stærkt, men når jeg lægger en kopi
af en af filerne ind under et andet navn, så myldrer det med
overlap, så forhåbentlig er den god nok.

Lige nu ligger der som test en kopi af cn-filen - kaldet yy.
Jan Hansen (21.05.2020, 18:25)
Bertel Lund Hansen skrev:

> Bertel Lund Hansen skrev:
> > Nu har jeg lavet en PHP-version. Den ligger her:

> Jeg glemte lige:
> Den forudsætter at der ligger IP-lister på formen:
> 5.10.78.16-5.10.78.23
> 5.32.128.0-5.32.135.255
> 5.53.128.0-5.53.255.255


Jeg har fosøgt at komprimere lidt, og har lavet databasen om
til binær udgave. Hver IP kan jo skrives i 4 bytes, og da de
gratis databaser kun indeholder områder, hvor sidste byte er
ens, er den fjerde byte til at spare væk. Der er under 256
lande, så jeg har sat én byte for landekode ind til hvert
område. Hele databasen er så kommet ned på 692 KB, og ved
hjælp af en liste over landenavne og -koder, kan det stadig
pakkes ud til den 8,1 MB .csv fil, det kommer fra.
Søgerutinen kunne nok laves lidt mere effektiv, hvis jeg
havde forstand på det, men det tager da ikke en evighed at
finde de 50 lande på hver side af for eksempel
[..]

> Største forbedring er at det nu kan sammenligne alle de
> tilgængelige komprimerede IP-filer og finde overlap imellem dem.


Er der overlap? Hvis det er områder i forlængelse af hinanden,
har jeg prøvet at lave noget, der sætter dem sammen til et område.
Når jeg på [..] laver en
liste over USA, kommer der i intervallet imellem 148.59.133.255 og
148.59.135.0 ti forskellige områder. Det samme med Canada.
Hvis jeg derimod laver en liste, hvor både Canada og USA er med,
bliver det sat sammen til ét område,
['148.59.134.0','148.59.134.255'],
Jan Hansen (21.05.2020, 18:53)
Jan Hansen skrev:

> Hvis jeg derimod laver en liste, hvor både Canada og USA er med,
> bliver det sat sammen til ét område,
> ['148.59.134.0','148.59.134.255'],


Det var vist noget sludder,
i intervallet imellem 148.59.133.255 og 148.60.0.0
kommer 10 områder fra enten USA eller Canada, de bliver
slået sammen til
['148.59.133.0','148.59.255.255'],
Bertel Lund Hansen (21.05.2020, 20:25)
Jan Hansen skrev:

> Søgerutinen kunne nok laves lidt mere effektiv, hvis jeg
> havde forstand på det,


Kender du binær søgning? Det er den mest effektive metode jeg
kender, og den er nem at forstå og implementere.

>> Største forbedring er at det nu kan sammenligne alle de
>> tilgængelige komprimerede IP-filer og finde overlap imellem dem.


> Er der overlap?


Det var der da jeg tog en fil fra Nirsoft der angiveligt skulle
svare til tld gb - men der var mange sammenfald med den uk-fil
jeg havde i forvejen. Det var derfor jeg lavede tjekrutinen.

> Hvis det er områder i forlængelse af hinanden, har jeg prøvet
> at lave noget, der sætter dem sammen til et område.


Det er det jeg kalder at komprimere filerne.
Jan Hansen (22.05.2020, 13:24)
Bertel Lund Hansen skrev:

> Kender du binær søgning? Det er den mest effektive metode jeg
> kender, og den er nem at forstå og implementere.


Jeg har forsøgt, men der må være noget, jeg har misforstået.
Det er for det meste lidt hurtigere på
[..]
hvor jeg finder 100 tilfældige IP, først med det jeg har brugt
hidtil, og bagefter med noget, der skulle ligne binær søgning.
Det sjove er, at når jeg bytter om, så jeg først søger binært,
er den hidtige metode generelt hurtigere,
[..]

Jeg søger i en streng - i stumper af 4 bytes - den stump, hvor
de første 3 bytes er mindre end eller lig søgestrengen, og
første 3 bytes i næste stump er større end søgestrengen.
Bertel Lund Hansen (23.05.2020, 11:46)
Jan Hansen skrev:

> Jeg har forsøgt, men der må være noget, jeg har misforstået.


Ja. Hvis du skal finde et element i et array, så kan du starte
forfra og sammenligne til der er en træffer. Worst case er at man
skal søge på alle elementerne.

Ved binær søgning sørger man først for at sortere det array der
skal søges på, og derefter sammenligner man med det midterste
element. Hvis det er for lille, søger man i den del der går fra
midten og op. Hvis det er for stort, søger man i den nederste
halvdel.

På samme måde opdeler man det nye afsnit der skal søges i og
bliver ved til elementet er fundet.

Hvis der er 1 mio. elementer, tager det højst
log2(1000000)=~19.93 søgninger, altså max 20. Det er noget andet
end den halve million man ellers skulle regne med i snit.

> Det er for det meste lidt hurtigere på
> [..]
> hvor jeg finder 100 tilfældige IP, først med det jeg har brugt
> hidtil, og bagefter med noget, der skulle ligne binær søgning.
> Det sjove er, at når jeg bytter om, så jeg først søger binært,
> er den hidtige metode generelt hurtigere,
> [..]


Den hurtigste måde at søge på som jeg har fundet, forudsætter at
man har ip-numrene konverteret til rene tal. Fra:

2.104.0.0-2.104.127.255

omregnes til

40370176-40894463

Hvis man så én gang omregner den IP man vil søge på til
decimaltal, så kan en sammenligning gå hurtigt.

Her er den rutine hvor jeg tjekker om en given IP ligger indenfor
et af de intervaller jeg vil udelukke:

function ip2int ($ip) {
$num=0;
foreach (explode('.',$ip) as $unit)
$num=$num*256+$unit;
return $num;
}

// IP check
$ip=$_SERVER['REMOTE_ADDR'];
$ip_value=ip2int($ip);
$low=0;
$high=count($banned_intervals);
while ($high-$low>1) {
$point=intdiv($low+$high,2);
list($pointbot)=$banned_intervals[$point];
if ($ip_value<$pointbot)
$high=$point;
else
$low=$point;
}
list($bot,$top)=$banned_intervals[$low];
if ($bot<=$ip_value && $ip_value<=$top)
exit();