LSL Wiki : LibraryPseudoRandomGenerator

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org

Pseudo-Random Number Generator

One of the big problems in LSL is communication security. It is next to impossible to keep communcations secure if they are on a fixed channel. For this reason, I have writen this function that can be used to generate pseudo-random numbers. They aren't really random, but are difficult to predict without the original algorithm. Using this function to secure your script systems does not compromise them because the range of inputs is so large that it would be impossible to calculate all the solutions in a timely fashion.

The idea is to use a slice of the MD5 hash of a string and convert that to an integer. MD5 does a nice job of shaking up the bits. If this is used for channel hopping (like in the example) it would be very difficult to gather enough information to crunch the numbers to start predicting the channels.

Function:
```integer pseudo_random(string text, integer nonce, integer start, integer end)
return (integer)("0x"+llGetSubString(llMD5String(text, nonce), start, end));
}

integer pseudo_random_float_a(string text, integer nonce, integer start, integer end, float max)
if(text = llGetSubString(llMD5String(text, nonce), start, end))
max *= (float)("0x"+text) /
(float)("0x"+llGetSubString("ffffffffffffffffffffffffffffffff", start, end));
return max * !(text == "");
}//0 <= result <= max

integer pseudo_random_float_b(string text, integer nonce, integer start, integer end, float max)
return max * (float)("0x"+text+"p-"+(string)(llStringLength(text = llGetSubString(llMD5String(text, nonce), start, end))<<2));
}//0 <= result < max

integer pseudo_random_float_c(string text, integer nonce, integer start, integer end, float max)
return iuf((integer)("0x"+llGetSubString(llMD5String(text, nonce), start, end)) & 0x3FFFFFFF) * max;
}//0 <= result < max

float iuf(integer a)
{//union integer to float
return ((float)("0x1p"+(string)((a | !a) - 150))) * ((!!(a = (0xff & (a >> 23))) << 23) | ((a & 0x7fffff))) * (1 | (a >> 31));
}//will crash if the raw exponent == 0xff; reason for crash deviates from float standard; though a crash is warented.```

Example Listen:
```integer pseudo_random(string text, integer nonce, integer start, integer end)
return (integer)("0x"+llGetSubString(llMD5String(text, nonce), start, end));
}

list handles;
integer last;
//Used in the generation of the hash, best to make this at least 64 characters.
string feed = "How much wood would a wood chuck chuck if a wood chuck could chuck wood?";

default
{
state_entry()
{
integer now = 30 * ((integer)llGetGMTclock() / 30);
integer count = 0;
while(count < 2)//number of channels to hold open at any one time.
{//if you have problems with missed message do to a lagged sim increase the number
handles += llListen(pseudo_random(feed, (last = now), 0, 7), "", "", "");
now += 30;
++count
}
llSetTimerEvent(10); //this is so if there is a nasty time dilation
}
state_exit()
{
handles = [];
}
timer()
{
integer next = 30 * ((integer)llGetGMTclock() / 30) + 30;
if(next > last)
{
last = next;
llListenRemove(llList2Integer(handles, 0));
handles = llList2List(handles, 1, -1) +
[llListen(next = pseudo_random(feed, next, 0, 7), "", "", "")];
//            llOwnerSay(llList2CSV([last, next]));
}
}
listen(integer a, string b, key c, string d)
{
b = llGetTimestamp();
float e = (float)llGetSubString(b,17,-1) - (float)llGetSubString(d,17,-1);
if(e < 0.0)
e+=60.0;
llOwnerSay((string)e);
}
}```

Example speak:
```integer pseudo_random(string text, integer nonce, integer start, integer end)
return (integer)("0x"+llGetSubString(llMD5String(text, nonce), start, end));
}

string feed = "How much wood would a wood chuck chuck if a wood chuck could chuck wood?";

default
{
state_entry()
{
}

touch_start(integer next)
{
string time = llGetTimestamp();
next = pseudo_random(feed, 30 * ((integer)llGetGMTclock() / 30), 0, 7);
llSay(next, time);
//        llOwnerSay((string)next);
}
}```

Functions of interest:
```integer Key2Integer(string input, integer start, integer end)
{
return (integer)("0x"+llGetSubString(
(string)llParseString2List(input,["-"],[]),
start, end));
}

integer timestamp_to_unixtime(string timestamp) {
integer year    = (integer) llGetSubString(timestamp,  0,  3);
integer month   = (integer) llGetSubString(timestamp,  5,  6);

return
(
(year - 1970) * 365
+ (year - 1969) / 4 - (year - 2001) / 100 + (year - 2001) / 400
+ llList2Integer(
[ 0, -1,  30, 58, 89, 119, 150, 180,  211, 242, 272, 303, 333 ],
month )
+ (integer) llGetSubString(timestamp,  8,  9)
+ (month>2) * (!(year % 4) - !(year % 100) + !(year % 400))
)
* 86400
+ (integer) llGetSubString(timestamp, 11, 12) * 3600
+ (integer) llGetSubString(timestamp, 14, 15) * 60
+ (integer) llGetSubString(timestamp, 17, 18);
}```