Basic Encryption Modules
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
I have posted 3 sections to this code, the encryption, decryption, and also a 3rd file. While the 3rd is unnecessary, since the value for the next channel to communicate on is changed each time data is sent, i found it annoying that when you edited the code to change the number, or tweak minor things, when it was saved, it reloaded the default values. The third script does nothing more than store the next channel to communicate on and pass it to either the encrypter or decypter when that script is reset. If you choose to use it, it should be placed in both prims that you are using.
This code basically takes a float, converts it to an alpha key, randomizes it, than takes a random channel, converts it to an alpha key, randomizes it, appends it to the string for the float, and shouts it to another prim, which decrypts it and returns the value of the float, as well as change it's listen to the next randomly determined channel. In this incarnation the script is not practical for transferring data, however can be incorporated into your code to do so.
Thank you to whomever took the time to clean it up for easier viewing and made the changes :)
Encrypter
//Simple Alpha Hash for practical floats by Beverly Larkin
//WARNING!!! Before actually using this to transfer any numbers(the principal is the same for strings)
//CHANGE THE ORDER OF THE LETTERS! - don't leave them sequential (a,b,c, etc.)
//it might even be a good idea to perform a simple math function on your number before you send it,
//(before encrypting it obviously). This is not practical for any use by itself, but i present it here
//for those that wish to customize it for their own needs (change the list in the Decrypter to match
//this one too :P
string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoptuvwxyz";
list numbers = [8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384,
8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.75, 0.5, 0.4,
0.2, 0.1, 0.05, 0.04, 0.02, 0.01, 0.005, 0.004, 0.002, 0.001, 0.0005, 0.0004, 0.0002,
0.0001, 0.00005, 0.00004, 0.00002, 0.00001, 0.000005, 0.000004, 0.000002, 0.000001 ];
integer com_channel;
float test_number_to_send = 104.7525; //WARNING FLOATING POINT NUMBERS ARE ROUNDED AUTOMATICALLY
//excessively large numbers will be changed BEFORE they are
//encrypted, sorry no easy change for this, as this is just a
//demo script.
// each pass of data includes an encrypted "next channel command" the channel to be used for the next
// packet of data is determined by:
// integer com_channel = (integer)llFrand((8388608) + 100000) * -1;
// next channel could be lower, but left to a "smaller" range to keep it practical for use with this script
float received_number;
//q = number separator
//r = * -1
//s = channel
string Encrypt(float X)
{
integer negative = (X < 0.0);
if( negative )
X = -X;
string returned;
integer int = 0;
for(; int < 49; ++int)
{
if(X >= llList2Float(numbers, int))
{
returned += llGetSubString(letters, int, int);
X -= llList2Float(numbers, int);
}
}
if( negative )
{
returned += "r";
}
return returned;
}
string Randomized(string X)
{
integer length = llStringLength(X);
integer int;
list randomized;
for(int = 0; int < length; ++int)
{
randomized += llGetSubString(X, int, int);
}
return (string)llListRandomize(randomized, 1);
}
default
{
on_rez(integer X)
{
llResetScript();
}
state_entry()
{
llMessageLinked(LINK_THIS, 0, "retrieve", NULL_KEY);
}
touch_start(integer Z)
{
string encrypted;
string hashed = Encrypt(test_number_to_send);
hashed = Randomized(hashed);
encrypted += hashed;
encrypted += "q";
integer next_com_channel = (integer)llFrand((8388608) + 100000) * -1;
hashed = Encrypt(next_com_channel);
hashed += "s";
hashed = Randomized(hashed);
encrypted += hashed;
llShout(com_channel, encrypted);
com_channel = next_com_channel;
llMessageLinked(LINK_THIS, com_channel, "store", NULL_KEY);
}
link_message(integer SENDER, integer NUM, string STR, key ID)
{
if(STR == "com_channel")
{
com_channel = NUM;
}
}
}
Decrypter
//Simple Alpha Hash for practical floats by Beverly Larkin
list letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoptuvwxyz";
list numbers = [8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384,
8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.75, 0.5, 0.4,
0.2, 0.1, 0.05, 0.04, 0.02, 0.01, 0.005, 0.004, 0.002, 0.001, 0.0005, 0.0004, 0.0002,
0.0001, 0.00005, 0.00004, 0.00002, 0.00001, 0.000005, 0.000004, 0.000002, 0.000001 ];
integer listener;
integer com_channel;
// each pass of data includes an encrypted "next channel command" the channel to be used for the next
// packet of data is determined by:
// integer com_channel = (integer)llFrand((8388608) + 100000) * -1;
// next channel could be lower, but left to a "smaller" range to keep it practical for use with
// this script
float received_number;
//q = number separator
//r = * -1
//s = channel
list Separate_Numbers(string encrypted)
{
integer position = llSubStringIndex(encrypted, "q");
return [llDeleteSubString(encrypted, position, -1), llDeleteSubString(encrypted, 0, position)];
}
float Value(string X)
{
integer position = llSubStringIndex(letters, X);
float returned = llList2Float(numbers, position);
return returned;
}
float Number_Convert(string X)
{
integer negative = FALSE;
integer channel = FALSE;
integer position = llSubStringIndex(X, "r");
if(~position)
{
negative = TRUE;
X = llDeleteSubString(X, position, position);
}
if(~(position = llSubStringIndex(X, "s")))
{
channel = TRUE;
X = llDeleteSubString(X, position, position);
}
integer int;
float returned;
for(int = 0; int < llStringLength(X); ++int)
{
returned += Value(llGetSubString(X, int, int));
}
if(negative)
{
returned = -returned;
}
if(channel)
{
com_channel = (integer)returned;
returned = 0.0;
}
return returned;
}
default
{
on_rez(integer X)
{
llResetScript();
}
state_entry()
{
llMessageLinked(LINK_THIS, 0, "retrieve", NULL_KEY);
}
listen(integer channel, string name, key id, string message)
{
llListenRemove(listener);
llOwnerSay("Message received = " + message); // message received from encryt prim
list BEER = Separate_Numbers(message);
integer int;
for(int = 0; int < llGetListLength(BEER); ++int)
{
float X = Number_Convert(llList2String(BEER, int));
if(X)
{
received_number = X;
}
}
listener = llListen(com_channel, "", "", "");
// next channel to receive data on
llOwnerSay("Next message will be received on channel " +(string)com_channel);
llOwnerSay("Decrypted Number is " + (string)received_number); // decrypted number
llMessageLinked(LINK_THIS, com_channel, "store", NULL_KEY);
}
link_message(integer SENDER, integer NUM, string STR, key ID)
{
if(STR == "com_channel")
{
com_channel = NUM;
listener = llListen(com_channel, "", "", "");
}
}
}
Channel Storage
integer com_channel = -21747232;
default
{
link_message(integer SENDER, integer NUM, string STR, key ID)
{
if(STR == "store")
{
com_channel = NUM;
}
else if(STR == "retrieve")
{
llMessageLinked(LINK_THIS, com_channel, "com_channel", NULL_KEY);
}
}
}