Pseudoslumptal i ASP
Ihopknåpat av Tom Stone en onsdag i december, 2008
Till Kent Izakssons personliga rekommendationsbrev som jag skrev om i föregÃ¥ende artikel, sÃ¥ tänkte jag att det kunde vara fiffigt att utgÃ¥ ifrÃ¥n besökarens namn och göra sÃ¥ varje besökare fick en unik version av brevet. För att Ã¥stadkomma det, sÃ¥ beslöt jag mig för att addera ihop ASCII-värdena av varje bokstav i besökarens namn, och använda den summan som ett “seed”-värde i en pseudo-slumptalsgenerator (dvs. att varje “seed”-värde alltid resulterar i samma sekvens slumptal).
Oturligt nog ligger Håkan Bergs sida på en Windows-server, så jag kunde inte skriva programkoden i PHP som vanligt, utan i ASP som jag aldrig någonsin sysslat med innan. Och efter en del googlande, så verkade det som att det inte fanns någon, redan färdig, slumptalsgenerator. Så vad gör man då? Fixar det själv, såklart!
SÃ¥ istället googlade jag pÃ¥ teorierna bakom en pseudorandom generator, och till min förfäran var matematiken i de flesta fallen lÃ¥ngt över mitt huvud… tills jag fann noteringar om Park-Millers linjärt kongruenta pseudoslumptalsgenerator. Vilken är som lyder:
Xk+1=Xk*g MOD n
Där n är ett primtal och g är en primitiv rot modulo n.
Som n valde jag först ett s.k. Mersenne primtal, men det gav frekventa “overflow errors”, vilket betydde att ekvationen kom upp i sÃ¥ höga tal att servern inte klarade av det. Efter mer googlande, sÃ¥ fann jag istället Fermats primtal, och med det ordnade problemet upp sig.
Så resultatet i ASP-kod blev alltså såhär:
< % 'Baserat på Park Miller linear congruential pseudo-random number generator. Från 1988 Function gen() seed = (seed * 75) mod 65537 gen=seed End Function %>
För att kunna använda det smidigare, så skrev jag även följande funktioner:
< % 'För att få ett slumpmässigt heltal Function nextInt() nextInt=gen() End Function 'För att få ett slumptal av decimaler mellan 0,0 och 1,0 Function nextDouble() '0 till ett nextDouble=(gen()/ 65537 ) 'Fermats tal End Function 'För att få ett heltals-slumptal mellan två värden, t.ex. mellan 10 och 20 Function nextIntRange(Min, Max) 'mellan Min och Max Min=Min-0.49999 Max=Max+0.49999 nextIntRange=Round(Min + ( (Max - Min) * nextDouble() )) End Function 'För att få slumptal med decimaler mellan två värden Function nextDoubleRange(Min, Max) 'mellan Min och Max nextDoubleRange=Min + ( (Max - Min) * nextDouble() ) End Function 'För att få ett booleanskt binärt slumptal Function coinToss() If Round(nextDouble() )=1 Then coinToss = True Else coinToss = False End If End Function %>
Och så här används funktionerna
< % Dim seed seed=37 'vilket tal som helst funkar. Jag utgick ifrån ASCII-värdena av besökarnas namn Response.Write nextIntRange(100,500) 'Skriver ut ett heltal mellan 100 och 500 %>
Inte så illa för att vara ett första försök, eller hur?
Skriv gärna en kommentar
Ämne: kodning
