Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Php: Uniikki-id perustuen auto increment -arvoon

grandvia [01.02.2010 10:31:13]

#

Pohdin sivustoa johon voivat käyttäjät lisätä tietoa. Tieto tallennetaan MySQL-taulukkoon uudelle riville. Rivi saa auto increment -arvon (+1). Oletetaan, että olemassa olevat rivit ovat id:illä 1 - 1 000 000.

Sitten olisi tiedosto, vaikkapa "nayta.php", jossa $_GET["id"] palauttaa myslistä tuolla id:llä olevan rivin tiedot.

En halua, että rivit ovat suoraan kaikille nähtävissä: nayta.php?id=1, nayta.php?id=2 ...), siksi otan käyttöön Base62-64 enkoodauksen.

Oletetaan vaikka, että id 257 000 on base-koodattuna EQEE (mikä se ei tietenkään ole). Ongelmana on, että id 257 001 on sitten EGEF ja id 257 002 on EGEG tai vastaava. Eli jonot ovat vielä vastaavasti jatkuvia (1, 2, 3 => EQEE, EQEF, EQEG).

Millähän ihmeellä saisin näitä arvoja enkoodattua niin, etteivät peräkkäiset arvot näytä niin samalta? Tähän on oltava jokin keino, mutten itse edes keksi teoriaa. Mm. Youtube käyttää samanlaista järjestelmää ID:n generoinnissa, mutta arvot ovat paljon satunnaisemman näköisiä.

Grez [01.02.2010 12:23:22]

#

grandvia kirjoitti:

Mm. Youtube käyttää samanlaista järjestelmää ID:n generoinnissa, mutta arvot ovat paljon satunnaisemman näköisiä.

Jos kerran tiedät millaista järjestelmää Youtube käyttää, niin mikset käytä samaa?

Itse vastaavan tarpeen yhteydessä generoisin vaan satunnaisen tunnisteen kullekin tietueelle.

Lebe80 [01.02.2010 13:10:26]

#

Miten olisi jokin valmiin hash:n käyttö (sisältäen suolan) id:n lisäksi?

Eli tällöin kukaan ei voisi ainakaan arvata hashia.

Eli vaikkapa ?id=14a801fc3, jossa kahdeksan viimeista merkkiä olisi vaikkapa id:stä (tässä 1) muodostetusta md5:lla luodusta hashista napattuja.

Metabolix [01.02.2010 15:22:44]

#

Tehdään vakiomittainen id eli lisätään etunollat. Lisätään luvun päihin ykköset ja muunnetaan saatu luku 36-järjestelmään. Kas näin:

<?php
function id_encode($id) {
	$id = strrev(sprintf("1%08d1", $id));
	$id = base_convert("$id", 10, 36);
	return $id;
}

function id_decode($id) {
	$id = base_convert("$id", 36, 10);
	if (strlen($id) != 10 || $id[0] != '1' || $id[9] != '1') {
		// Viallinen tunnus!
		return 0;
	}
	$id = substr(strrev($id), 1, 8);
	return $id;
}

Tässä id saa olla enintään kahdeksan numeron mittainen, eli käytössä on satamiljoonaa vaihtoehtoa. Tuloksena on kuuden merkin mittainen tunniste.

grandvia [01.02.2010 15:57:04]

#

Metabolix: Loistava esimerkki, muokkasin tuota hieman base62:ksi ja johan on hieno id-järjestelmä.

Toivottavasti muokkaukseni toimii kuten pitää.

Metabolix [01.02.2010 16:01:18]

#

grandvia kirjoitti:

Toivottavasti muokkaukseni toimii kuten pitää.

Kannattaa testata.

<?php
for ($i = 1; $i < 1000000; ++$i) {
  $e = id_encode($i);
  $d = id_decode($e);
  if ($d != $i) {
    echo "VIRHE! $i = $e = $d\n";
    break;
  }
}

grandvia [02.02.2010 14:27:00]

#

Metabolix kirjoitti:

grandvia kirjoitti:

Toivottavasti muokkaukseni toimii kuten pitää.

Kannattaa testata.

Tämän ajoin läpi ongelmitta, uusi ID-järjestelmä on jo käytössä pienin muokkauksin.

Erittäin suuret kiitokset Metabolix.

Vastaus

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

Tietoa sivustosta