Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: IP:n koodaus ja purku

Sivun loppuun

T.M. [18.12.2004 03:03:57]

#

<?php


// Tuottaa tasan 8 merkkiä pitkän IP-osoitteen muotoon: A3107CD3
function short_ip($ip){
	$osa = explode(".", $ip);
	return substr(sprintf("%02X%02X%02X%02X", (int)$osa[0], (int)$osa[1], (int)$osa[2], (int)$osa[3]), 0, 8);
}

// Purkaa koodatun IP-osoitteen muotoon: 163.16.124.211
function decode_short_ip($ip){
	return hexdec(substr($ip, 0, 2)).".".hexdec(substr($ip, 2, 2)).".".hexdec(substr($ip, 4, 2)).".".hexdec(substr($ip, 6, 2));
}


$koodattu = short_ip("163.16.124.211"); // A3107CD3
$purettu = decode_short_ip("A3107CD3"); // 163.16.124.211


?>

coaster [19.12.2004 19:19:30]

#

Mites kun tulee ipv6?

Niko [19.12.2004 22:49:48]

#

no sitten tää taitaa olla hyödytön eikä ipv6 tule vielä YLEISTYMÄÄN pitkään aikaan (=inernet yhteyden mukana tulee oletuksena ipv6 ja sitä tukee suurin osa ohjelmista) eihän aikaisemmat kuin windows 2k ja xp tue?

FooBat [20.12.2004 00:47:48]

#

Mitäköhän hyötyä tästä on? Jos haluat säästää tilaa, käsittele IP-osoitetta 32-bit integerinä mikä se oikeasti on. Tuo heksastringi ei paljon käyttäjälle kerro ja on tuplasti pidempi kuin integer.

Niin ja IPv6 tulee ensi vuonna. On tullut jo monta vuotta :) Toisaalta IPv6 ei tarvita mitään heksamuunnosta, koska muistaakseni sen virallinen kirjoitustapa tapahtui heksoina tyyliin a.4.6.8.f.0.0.0.0.0.0.0.3.d.e.f.c.b.a.0.0.2.3.5.6.7.8.9.0.

T.M. [20.12.2004 13:54:00]

#

Ömm... :D
Tuosta heksastringistä voi tarkastella eri numeroita yksinään, sekä järjestää IP:t helposti. Tai tarkastella vain ensimmäisiä kolmea numeroa.

32-bit integer? mikä lienee, tarkoitatko lukua jonka maksimiarvo on 256*256*256*256 = 4294967296 = 10 merkkiä?
Tiedostoon ei tietääkseni voi tallentaa kuin merkkijonoja? Tai no voihan sen tiedon jollain tapaa koodata sinne, mutta siitä taas ei ole mitään hyötyä kun koko paska pitäs dekoodata jos sieltä jotain haluaa etsiä.

Jos muutan tuon IP:n merkeiksi (4 merkin tilanvienti). Ei siitä paljoa iloa ole, kun myös rivinvaihtomerkki saattaa sotkea tiedostorakenteen.

Nopein tapa tiedon hakemisen kannalta on tallentaa tiedostoon tuo heksa-koodi. Olen testannut :)

ajv [20.12.2004 14:11:57]

#

lainaus:

Mitäköhän hyötyä tästä on?

Niinpä, en kyllä käsitä miksi ip pitää tallettaa hexa-muodossa? Miksi ip-osoitteita pitää järjestellä tai tutkia ip:n kolmea ensimmäistä numeroa? Ja jos joitakin kiinnostaa tutkia ip-osoitteen numeroita, hän varmaan osaa sen ilman tätäkin tehdä ;)
Tilan säästö? Noh ainut peruste, tosin sekin todella löyhä.

T.M. [20.12.2004 14:49:59]

#

Heksamuodossa säästää 4 merkkiä jos tallentaa tiedostoon :)

Oletetaan että tiedostossa on 10000 IP-osoitetta, tilansäästö on 40kt (33%), verrattuna desimaalimuotoiseen: 044124224053 (44.124.224.53)

Jos tallennan tiedostoon pelkät asciimerkit, on niitä hyvin vaikeaa käsitellä; esimerkiksi etsiä tietty IP tiedostosta (hitaampaa)

Niko [20.12.2004 15:04:11]

#

lainaus:

Mitäköhän hyötyä tästä on? Jos haluat säästää tilaa, käsittele IP-osoitetta 32-bit integerinä mikä se oikeasti on. Tuo heksastringi ei paljon käyttäjälle kerro ja on tuplasti pidempi kuin integer.

Niin ja IPv6 tulee ensi vuonna. On tullut jo monta vuotta :) Toisaalta IPv6 ei tarvita mitään heksamuunnosta, koska muistaakseni sen virallinen kirjoitustapa tapahtui heksoina tyyliin a.4.6.8.f.0.0.0.0.0.0.0.3.d.e.f.c.b.a.0.0.2.3.5.6.7.8.9.0.

On ollut ja niitä saa kotikäyttöön jos jaksaa sätää tunnelin mutta en usko vielä ensivuonna yleistyvän

FooBat [20.12.2004 16:53:32]

#

lainaus:

Ömm... :D
Tuosta heksastringistä voi tarkastella eri numeroita yksinään, sekä järjestää IP:t helposti. Tai tarkastella vain ensimmäisiä kolmea numeroa.

Niin voi neljän tavun binäärimuodostakin ja vielä helpommin.

lainaus:

32-bit integer? mikä lienee, tarkoitatko lukua jonka maksimiarvo on 256*256*256*256 = 4294967296 = 10 merkkiä?

En, tarkoitan sitä lukua jonka maksimiarvo on 256*256*256*256-1 = 4294967295 = 32 bittiä = 4 tavua (4 merkkiä vie saman tilan)

lainaus:

Tiedostoon ei tietääkseni voi tallentaa kuin merkkijonoja? Tai no voihan sen tiedon jollain tapaa koodata sinne, mutta siitä taas ei ole mitään hyötyä kun koko paska pitäs dekoodata jos sieltä jotain haluaa etsiä.

Tiedostoon ei voi tallentaa mitään muutaa kuin numeroita tavun kokoisissa (8 bittiä) palasissa. On vain sopimuskysymys, että osa näistä numeroista näytetään tekstieditoreissa aakkosina ja numeroiden merkkeinä. 8 bitillä (1 tavu) voidaan kuvata numeroita 0-255, neljällä tavulla voidaan helposti merkitä neljä lukua väliltä 0-255 (ja kappas IP-osoitetta merkitään juuri neljällä luvulla väliltä 0-255, hmmm).

lainaus:

Nopein tapa tiedon hakemisen kannalta on tallentaa tiedostoon tuo heksa-koodi. Olen testannut :)

Ohjelmallisesti binääridatana olevan numeron löytää tietyssä formaatissa olevasta tiedostosta nopeiten. Tekstieditorin hakutoiminnolla kuvittelisin kuitenkin normaalin kirjoitetun IP-muodon löytyvän nopeiten (ei tarvitse tehdä muunnosta heksaksi vaan voi suoraan näpytellä IP-osoitteen).

T.M. [20.12.2004 17:42:10]

#

Pilkunnussinta sikseen, tässä tehtävä:
- Tallenna tiedostoon 10000 erilaista IP:tä
- Keksi nopein tapa tarkistaa löytyykö tiedostosta jokin sattumanvarainen IP-osoite.
- Tiedostosta haettavaa IP-osoitetta täytyy myös pystyä vertailla vain kolmen ensimmäisen numeron perusteella.

Otan ilomielin käyttööni sellaisen tavan joka on nopeampi kuin tuo minun heksamuotoinen :)

Niin ja kieli on edelleen PHP, ja scriptin täytyy toimia mbnetissä.

Kryil [20.12.2004 17:44:24]

#

lainaus:

On ollut ja niitä saa kotikäyttöön jos jaksaa sätää tunnelin mutta en usko vielä ensivuonna yleistyvän

Häh? Mulla ob ipv6 http-serveri oman adsl:n päässä. Ollu jo runsaan puolen vuotta.

Antti Laaksonen [20.12.2004 17:56:33]

#

Neljän merkin käsittely on takuulla nopeampaa kuin kahdeksan. Kun IP-numero tallennetaan neljätavuisena kokonaislukuna, jokainen "merkki" on yksi numeroista, eli vertailu ei ole mikään ongelma. Siksi FooBatin esittämä tapa on sekä nopein että tilaa säästävin.

Tumpi [20.12.2004 18:19:46]

#

Kyllähän tästä selviää esim. kuinka muuntaa monien weppi-irkkien identtiosa ihan selkeäksi IP-osoitteeksi.

FooBat [20.12.2004 18:26:45]

#

lainaus:

Pilkunnussinta sikseen, tässä tehtävä:
Otan ilomielin käyttööni sellaisen tavan joka on nopeampi kuin tuo minun heksamuotoinen :)

PHP:stä mulla ei ole kovin paljon kokemusta, mutta hiukan C:ta, Javaa ja tuota esimerkkiäsi mukaillen veikkaisin, että tälläinen toimii

<?php

// Tuottaa tasan 4 merkkiä pitkän IP-osoitteen muotoon: XXXX
function short_ip($ip){
    $osa = explode(".", $ip);
    return substr(sprintf("%c%c%c%c", (int)$osa[0], (int)$osa[1], (int)$osa[2], (int)$osa[3]), 0, 4);
}

// Purkaa koodatun IP-osoitteen muotoon: 163.16.124.211
function decode_short_ip($ip){
    return (int)((char)substr($ip, 0, 1)).".".(int)((char)substr($ip, 1, 1)).".".(int)((char)substr($ip, 3, 1)).".".(int)((char)substr($ip, 4, 1));
}


$koodattu = short_ip("163.16.124.211"); // XXXX
$purettu = decode_short_ip("aaaa"); // 97.97.97.97


?>

Decode funktiota pitää varmaan muuttaa, jotta se toimisi. Mula ei ole kokemusta siitä miten fiksusti tai tyhmästi toi PHP tekee tyyppimuunnoksia. Voipi olla, että toi ei toimi ollenkaan :)

T.M. [20.12.2004 19:07:06]

#

Muutama osa tehtävästä unohtui:
- Tallenna tiedostoon 10000 erilaista IP:tä
- Keksi nopein tapa tarkistaa löytyykö tiedostosta jokin sattumanvarainen IP-osoite.
- Tiedostosta haettavaa IP-osoitetta täytyy myös pystyä vertailla vain kolmen ensimmäisen numeron perusteella.

Antamasi scriptin pötkäle tuottaa vain merkkijonon joka on 4 merkkiä pitkä, ei siis sisällä tiedoston lukua tai muuta sellaista (joka oli tehtävän tarkoitus).

Odotan edelleen toimivaa scriptiä joka tekee sen mitä tehtävässäni pyydettiin.

Linkku [20.12.2004 19:31:38]

#

http://en.wikipedia.org/wiki/IPv6
Tuolla tietoa IPv6:sta.
Toi koodi on kyllä ihan käytännöllinen, jos esimerkiksi vieraskirjassa jättää ip:t kaikkien näkyville, niin kaikki ei voi suoraan h4x0r0ida sitä ip:tä.

Antti Laaksonen [20.12.2004 20:00:41]

#

Osa 1 - 10000 erilaista IP:tä tiedostoon

<?php

for ($i = 0; $i < 10000; $i++) {
    $l .= chr($i % 255);
    $l .= chr($i / 255);
    $l .= "IP";
}

$t = fopen("ipt.dat", "w");
fwrite($t, $l);
fclose($t);

?>

Osa 2 - Onko IP tiedostossa?

<?php

// käyttää FooBatin funktiota
$haettava = short_ip("12.34.56.78");

$tiedot = file_get_contents("ipt.dat");

if (substr_count($tiedot, $haettava) > 0) {
    echo "IP on tiedostossa!";
}

?>

Osa 3 - IP:n kolmen ensimmäisen numeron vertailu

<?php

if (ord($haettava{0}) == 12 && ord($haettava{1}) == 34 && ord($haettava{2}) == 56) {
    echo "Kolme ensimmäistä numeroa ovat 12, 34 ja 56.";
}

?>

T.M. [20.12.2004 20:19:35]

#

$etsi1 = substr_count("baabababaaab", "baba"); // 1
$etsi2 = substr_count("baab abab aaab", "baba"); // 0

Sinun tapasi luulee että IP on jo tiedostossa, vaikkei sitä ole siellä :)

Ja tuolla kolmen numeron vertailulla tarkoitin sitä että tiedostosta voidaan etsiä IP:n pätkä tyyliin: "82.122.53.xxx", taikka sitten vaikkapa: "82.122.xxx.xxx" jne...

Antti Laaksonen [20.12.2004 20:32:20]

#

Skriptissä on tosiaan pikku virhe, mutta korjaus on käyttää strpos-funktiota ja tarkistaa, että kohta on neljällä jaollinen. Ja kolmen numeron vertailu onnistuu samalla tavalla - etsit vain kolmen merkin pituista merkkijonoa tiedostosta.

T.M. [20.12.2004 20:40:55]

#

Ei taida onnistua edes tuolla tavalla.
Ongelmana on edelleenkin se että jonkin IP:n alkupää sekottuu jonkin IP:n loppupäähän.

Antti Laaksonen [20.12.2004 20:42:03]

#

No eihän se voi sekoittua, kun IP:t ovat neljän merkein välein tiedostossa ja tarkistetaan, että löydetty IP alkaa rajakohdalta. :)

T.M. [20.12.2004 20:44:57]

#

Entä jos se löytyykin monesta eri kohtaa tiedostosta...
while-silmukka?

Tai no, koodia kehiin mieluiten :)

Antti Laaksonen [20.12.2004 20:56:43]

#

Joo, silmukalla se järjestyy. Koodin osaat tehdä itsekin.

T.M. [20.12.2004 20:58:33]

#

Taitanee mennä hitaammaksi :)

Joten tuo heksatapa on näemmä parempi.

Antti Laaksonen [20.12.2004 21:03:40]

#

No molemmilla menee niin vähän aikaa, että ihminen ei huomaa eroa. Toisaalta tiedostojen kokojen ero on kaksinkertainen.

renni [21.12.2004 18:06:25]

#

Ihme vänkäämistä T.M:llä oman tapansa paremmuudesta, ilman mitään oikeaa perustetta. "Mun on parempi" ei ole perustelu. :)
Optimaalinen muoto IP:lle on neljän tavun mittainen kokonaisluku, sehän se nimittäin alunperinkin on. On erittäin helppoa ja nopeaa tehdä tuon kanssa vertailu jossa tutkitaan vain 3 suurinta tavua, ilman ylimääräisiä stringin käsittelyjä.

Lisäys: Nanosekuntien erolla tällaisen nopeudessa ei kai ole kellekään mitään merkitystä?

T.M. [21.12.2004 18:31:02]

#

No onhan se nyt ihan loogista että yhden kerran stringin läpikäyminen on nopeampaa kuin esimerkiksi neljä kertaa.

Minun tapauksessani ei tarvitse käydä merkkijonoa läpi kuin yhden kerran.
Ja aikaeroa kertyy enemmän kuin nanosekunteja :)

Meitzi [21.12.2004 22:29:32]

#

Nopein tapa vertailla, onko jonkun ip osoitteen tietty osa sama, on tietysti käyttää bittioperaatioita. Sitähän käytetään aina ip liikenteessä. Aliverkon peite, oletusyhdyskäytävä jne. ovat varmaan tuttuja käsitteitä.

renni [23.12.2004 00:03:00]

#

T.M. Ei ole loogista käydä läpi stringejä kun on pienistä kokonaisluvuista kyse. Siinä homman pointti. Stringihän itse asiassa on kokonaislukutaulukko, sinun tapauksessasi siis teet oikeasti kolme kokonaislukuvertailua sekä lisäksi mahdollisia muunnoksia kun stringinä niitä käsittelet, kun voisit selvitä _yhdellä_ vertailulla. Ei pidä tuijotella pelkkää koodia, ota huomioon mitä se kone joutuu oikeasti tekemään.

T.M. [23.12.2004 00:41:39]

#

Ai niinpäs tietenkin! Typerä ajatuskatkos minulla :D
Hyvä että sentään jotkut osaavat ajatella asiat perin pohjin :)

Pitänee kai sitten pyöräyttää jostain se koodi joka toimii tuolla 4 merkin systeemillä, niin saan ainakin hiukan nopeutta lisää omaan systeemiini.

Latska [23.12.2004 21:20:19]

#

Lukihäiriö iski... IE:n koodaus ja purku...

NiLon [19.02.2005 02:34:19]

#

Hmm eikö longip ole myös aika hyvä säilöntätapa? Ainakin niitä on helpompi vertailla kuin hexoja. Ip range on myös helppo tehdä tämän pohjalta.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta