<? /*
NoID webkettes URL-rövidítő
Szántó Ádám, 2006
Számból szót, szóból számot csinál - de nem garantálja, hogy a szó
értelmes lesz, csupán azt, hogy relatíve könnyű lesz kimondani egy
magyar embernek, illetve sokkal szebben fog hangzani, mint adott
esetben egy hosszú szám. Másik előnye, hogy egyfajta szabványként is
tud funkcionálni stabilitása miatt (pl. "mikor születtél?" "eragifime.")
Az algoritmus lényege röviden: nyelvi döntésprogram szerint dolgozik,
lásd $dontesprogram változó. Ebben pipe-jel választja el a lehetséges
fonémákat (msh/mgh), amiknek egy szabályszerű szóban felváltva kell
következniük. Vesszővel elválasztva kell az egyes betűket felsorolni.
Ezután az algoritmus a számból maradékos osztás elvével sorsolja ki,
hogy milyen betűnek kell következnie (pl. ha 5 magánhangzó van, a
következő magánhangzó indexe az aktuális szám maradéka modulo 5.) Ez
az eljárás könnyedén visszafordítható.
Viszont magával vonja, hogy kis számokhoz tartoznak a rövid szavak,
nagy számokhoz a hosszúak. Ehhez kell egy nagy prímszám, mivel a modulo
p vett maradékrendszer testet alkot, vagyis minden elemnek van inverze.
Ez egy önmagába menő bijekciót (permutáció) biztosít a nagy prímszámnál
kisebb természetes számok halmazán (magyarán összekavarja ezeket a
számokat).
Így végső soron az algoritmusról elmondhatjuk, hogy kellemesen
véletlenszerű annyiban, hogy viszonylag közeli számok is különböző
szót adnak vissza, viszont eléggé biztos eredményeket tud adni elég
gyorsan.
*/
define("PRIM", 87438685933);
define("SZORZO", 17438);
define("SZORZOINV", 6252783654);
define("KPRIM", 17438699);
define("KSZORZO", 17438);
define("KSZORZOINV", 4241170);
$dontesprogram="a,e,i,o,u|p,t,r,m,c,f,n,l,d,s,z,g,b,v,j,k,h,ny,gy,ly,sl,zs,ty,sz,cs,st";
$dontesek=dontesprogram($dontesprogram);
function szobol_szamot($szo, $dontesek) {
$belso_index=65; $szam=0; $eredeti_szo=$szo=strtolower($szo);
$fonematipusok=count($dontesek);
$forditotabla=array();
$plusz=1;
foreach ($dontesek as $f => $fonema)
foreach ($fonema as $kulcs => $betu) {
if (strlen($betu)>1) {
$szo=str_replace($betu, chr($belso_index), $szo);
$betu=chr($belso_index);
$belso_index++;
}
$forditotabla[$betu]=array("fonema" => $f, "kulcs" => $kulcs);
}
$this_fonema=$forditotabla[substr($szo, -1)]["fonema"];
for ($i=1;$i<=strlen($szo);$i++) {
$betu=substr($szo, -$i, 1);
if (!isset($forditotabla[$betu])) break;
$dontes=$forditotabla[$betu];
if ($dontes["fonema"]!=$this_fonema) break;
$variaciok=count($dontesek[$this_fonema])+$plusz;
dontes_back($szam, $variaciok, $dontes["kulcs"]+$plusz);
$this_fonema--;
if ($this_fonema<0) $this_fonema=$fonematipusok-1;
$plusz=0;
}
if ($i<=strlen($szo)) return 0;
dontes_back($szam, $fonematipusok, ($this_fonema+1) % $fonematipusok);
return permut2($szam);
}
function dontes_back(&$szam, $ennyibol, $ezt) {
$szam=$ennyibol*$szam+$ezt;
}
function szambol_szot($szam, $dontesek, $ertelmezes=0) {
$szam=permut1($szam);
$fonematipusok=count($dontesek);
$eredeti_szam=$szam; $szo=""; $betuk_szama=0;
$this_fonema=dontes($szam, $fonematipusok, $eredeti_szam);
do {
$lehet=$dontesek[$this_fonema];
if ($szam<count($lehet)+$ertelmezes) {
$l=array("");
foreach($lehet as $ertek)
$l[]=$ertek;
$lehet=$l;
}
$betu=dontes($szam, count($lehet), $eredeti_szam);
$szo.=$lehet[$betu];
$betuk_szama++;
$this_fonema=($this_fonema+1) % $fonematipusok;
} while ($szam!=$eredeti_szam);
return $szo;
}
function dontes(&$szam, $lehetosegek, $eredeti_szam) {
$r=$szam % $lehetosegek;
$szam=floor($szam/$lehetosegek);
if ($szam==0) $szam=$eredeti_szam;
return $r;
}
function dontesprogram($p) {
$d=explode("|", $p);
foreach ($d as $k => $opciok)
$d[$k]=explode(",", $opciok);
return $d;
}
function permut1($szam) {
return bcmod(bcmul($szam, SZORZO), PRIM);
}
function permut1($szam) {
if ($szam<KPRIM) {
return bcmod(bcmul($szam, KSZORZO), KPRIM);
} else {
return bcmod(bcmul($szam-KPRIM, SZORZO), PRIM)+KPRIM;
}
}
function permut2($szam) {
if ($szam<KPRIM) {
return bcmod(bcmul($szam, KSZORZOINV), KPRIM);
} else {
return bcmod(bcmul($szam-KPRIM, SZORZOINV), PRIM)+KPRIM;
}
?>