This function has been deprecated in favour of llXorBase64StringsCorrect.

`string llXorBase64Strings(string s1, string s2)`

Performs an xor on two Base64 strings and returns a Base64 string.`s2` repeats if it is shorter than `s1`.

This function is for encrypting data. Put your data in`s1` and your key in `s2` to encrypt or put the encrypted data into `s1` with the same key in `s2` to decrypt again.

Use`llStringToBase64` and `llBase64ToString` for converting to and from Base64 respectively.

While fine for most SL encryption purposes, Xor'ing a string with a password is considered a very weak encryption algorithm. Do not use this for anything that will cost you RL $ if compromised (such as an automated RL - SL currency exchanger). Also, consider carefully how much damage a malicious party might be able to wreak if your encryption is hacked.

This type of encryption is similar to something called a one time pad that is if`s2` is the same length as `s1`, is generated randomly (not pseudo randomly), and `s2` is used only once. When used in this way this function is provably unbreakable. However implementing this function in this way is difficult to say the least. However with a little ingenuity and some creative problem solving we might be able to create different variations of this with acceptable reductions in security with minimal resource requirements(execution time, memory). IE have a new key created for each message maybe based on some universally changing constant like the server timestamp.

And as it turns out the quickest way to weaken xor type encryption is to use the key more than once, either by repeating a small key across a longer message or to use the same key on more than one message. It is only strong if the key is used only once. So this type of encryption when used with the same key over and over is supposedly rather trivial to break.

__Example:__

Note: this example code always produces the same result as llXorBase64StringsCorrect, but only the same result as llXorBase64Strings when s2 is longer than s1 (unless s2 is a multiple of 3 bytes in length -see discussion at end of page).

If you want to exchange data that passed through this function from outside of LSL, the following Python snippet might be helpful to you:

This function does the same thing as the one above, only in PHP:

#### '1.9.0(18)' vs 'pre/post-1.9.0(18)' implementation

The 1.9.0(18) Grid update introducted a new implementation of this function. It was re-written to fix a sim crash bug, however, the output deviates from the original pre-update version. The 1.9.0(18) implementation is simpler. The difference is shown below through pseudo-code. The 1.9.0(21) update reverted this function's behavior to the pre-1.9.0(18) behavior and introduced a new llXorBase64StringsCorrect with the 1.9.0(18) behavior.

#### 1.9.0(18) implementation

1. Decode s1 and s2 from Base64 into byte strings

2. Bit-wise XOR corresponding bytes of s1 and s2 in sequence. If s2 is shorter than s1, it is simply repeated (i.e. the index into s2 is the index into s1 % length of s2).

3. Re-encode the result byte string into Base64 encoding and return as result

#### Pre/Post-1.9.0(18) implementation

This function's original implementation is more efficient, but gives a different result than the new one,**only if s2 is shorter than s1 and s2 isn't a multiple of 3 bytes/chars long**. As of 1.9.0(21), this is the behavior of this function.

1. Convert the Base64 encoding of s1 and s2 into a sequence of 6bit values. (by converting each Base64 character into its 6bit index - see Wikipedia Base64).

2. Bit-wise XOR corresponding 6bit values of s1 and s2 in sequence. If s2 is shorter than s1, it is simply repeated (i.e. the index into s2 is the index into s1 % length of s2).

3. Re-convert the resulting sequence of 6bit values into their Base64 characters (by using the 6bit values as indices into the Base64 character set)

The reason this differs from the new implemenation, is that the length of the byte string represented by s2 may not be a multiple of 3 bytes long. The initial encoding of s2 into Base64 form involves taking each set of 3 bytes (3x8=24bits) 6 bits at a time and converting to 4 Base64 characters (4x6=24bits). However, if not a multiple of 3 bytes there would have been either 2bytes (16bits) or 1byte(8bits) left over at the end. The Base64 encoding scheme dictates padding to a multiple of 6bits with a 0 bit to obtain the final Base64 character. Hence the Base64 encoded form of s2 may have either 4bits (16 - 6x2) or 2 bits (8 - 1x6) of 0 padding at its end.**This padding is included when s2 is repeated above** in the case when s2 is shorter than s1. Hence the different output.

Here is an example of different output.

If you XOR these two strings using llXorBase64Strings:

the 'pre/post-1.9.0(18)' implementation will produce

the '1.9.0(18)' implementation gave:

(which is the same result you'll get from the new llXorBase64StringsCorrect function)

(If you really need code compatible with the current ('pre/post-1.9.0(18)') implementation of llXorBase64Strings, IM Cenji Neutra for a C# implementation)

Functions | DeprecatedFunctions | Crypto | Communications

Performs an xor on two Base64 strings and returns a Base64 string.

This function is for encrypting data. Put your data in

Use

While fine for most SL encryption purposes, Xor'ing a string with a password is considered a very weak encryption algorithm. Do not use this for anything that will cost you RL $ if compromised (such as an automated RL - SL currency exchanger). Also, consider carefully how much damage a malicious party might be able to wreak if your encryption is hacked.

This type of encryption is similar to something called a one time pad that is if

And as it turns out the quickest way to weaken xor type encryption is to use the key more than once, either by repeating a small key across a longer message or to use the same key on more than one message. It is only strong if the key is used only once. So this type of encryption when used with the same key over and over is supposedly rather trivial to break.

Note: this example code always produces the same result as llXorBase64StringsCorrect, but only the same result as llXorBase64Strings when s2 is longer than s1 (unless s2 is a multiple of 3 bytes in length -see discussion at end of page).

default { state_entry() { string data = "I like bananas."; // the data we want to encrypt string pass = "monkey"; // the encryption key string crypt; // for storing the encrypted data // convert both data and key to base64 and encrypt the data with the key // then store the encrypted data in 'crypt' crypt = llXorBase64Strings(llStringToBase64(data), llStringToBase64(pass)); llSay(0, crypt); // this could now be used to email the data around // someone without the correct key wouldn't be able to (easily) get the plaintext // decrypt it again, using the same key, and convert back to plaintext llSay(0, llBase64ToString(llXorBase64Strings(crypt, llStringToBase64(pass)))); // as you can see, applying the same key to encrypted data again decrypts it } }

Tip: If you see an "=" character in the middle of your encrypted string, you probably forgot to first convert your data to Base64. |

If you want to exchange data that passed through this function from outside of LSL, the following Python snippet might be helpful to you:

from base64 import b64encode, b64decode def XorBase64Strings(s1, s2): """Emulates the LSL function llXorBase64Strings: Performs an exclusive or on two Base64 strings and returns a Base64 string. s2 repeats if it is shorter than s1.""" s1 = b64decode(s1) # internally this works with s2 = b64decode(s2) # the decoded strings while len(s2) < len(s1): s2 += s2 # repeat s2 until it's at least as long as s1 out = "" for index in range(len(s1)): # take each character from s1 out += chr( ord(s1[index]) ^ ord(s2[index]) ) # and XOR it with one from s2 return b64encode(out) data = "I like bananas." # the data we want to encrypt ckey = "monkey" # the encryption key crypt = XorBase64Strings(b64encode(data), b64encode(ckey)) # encode & encrypt print crypt # the base64 encoded result decrypt = b64decode(XorBase64Strings(crypt, b64encode(ckey))) # decrypt & decode print decrypt # the decrypted and base64 decoded data # verify if decrypt == data: print "This function seems to work..." # this string is from calling the LSL function with the same parameters if crypt == "JE8CAg4cTQ0PBQQXDBxA": print "... in the same way as the LSL function."

This function does the same thing as the one above, only in PHP:

```
<?php
```

function XorBase64Strings($s1, $s2)

{

$s1 = base64_decode($s1);

$s2 = base64_decode($s2);

while(strlen($s2) < strlen($s1))

$s2 .= $s2;

return base64_encode($s1 ^ $s2);

}

?>

The 1.9.0(18) Grid update introducted a new implementation of this function. It was re-written to fix a sim crash bug, however, the output deviates from the original pre-update version. The 1.9.0(18) implementation is simpler. The difference is shown below through pseudo-code. The 1.9.0(21) update reverted this function's behavior to the pre-1.9.0(18) behavior and introduced a new llXorBase64StringsCorrect with the 1.9.0(18) behavior.

1. Decode s1 and s2 from Base64 into byte strings

2. Bit-wise XOR corresponding bytes of s1 and s2 in sequence. If s2 is shorter than s1, it is simply repeated (i.e. the index into s2 is the index into s1 % length of s2).

3. Re-encode the result byte string into Base64 encoding and return as result

This function's original implementation is more efficient, but gives a different result than the new one,

1. Convert the Base64 encoding of s1 and s2 into a sequence of 6bit values. (by converting each Base64 character into its 6bit index - see Wikipedia Base64).

2. Bit-wise XOR corresponding 6bit values of s1 and s2 in sequence. If s2 is shorter than s1, it is simply repeated (i.e. the index into s2 is the index into s1 % length of s2).

3. Re-convert the resulting sequence of 6bit values into their Base64 characters (by using the 6bit values as indices into the Base64 character set)

The reason this differs from the new implemenation, is that the length of the byte string represented by s2 may not be a multiple of 3 bytes long. The initial encoding of s2 into Base64 form involves taking each set of 3 bytes (3x8=24bits) 6 bits at a time and converting to 4 Base64 characters (4x6=24bits). However, if not a multiple of 3 bytes there would have been either 2bytes (16bits) or 1byte(8bits) left over at the end. The Base64 encoding scheme dictates padding to a multiple of 6bits with a 0 bit to obtain the final Base64 character. Hence the Base64 encoded form of s2 may have either 4bits (16 - 6x2) or 2 bits (8 - 1x6) of 0 padding at its end.

Here is an example of different output.

If you XOR these two strings using llXorBase64Strings:

llXorBase64Strings("OnAxODcyMzRhYmNkZWZnaGkgYWJjZEBlZmdoLmlqa2wubW5v", "QUJDREVGR0hJSktMTQ==")

the 'pre/post-1.9.0(18)' implementation will produce

"ezJyfHJ0dHwoKCgoKGJzTF1kNQYX4NTB0qO4byspLyloKiYm"

the '1.9.0(18)' implementation gave:

"ezJyfHJ0dHwoKCgoKCclKy1lJyUrLQouKiopbCouLippJScl"

(which is the same result you'll get from the new llXorBase64StringsCorrect function)

(If you really need code compatible with the current ('pre/post-1.9.0(18)') implementation of llXorBase64Strings, IM Cenji Neutra for a C# implementation)

Functions | DeprecatedFunctions | Crypto | Communications

There are 9 comments on this page.
[Display comments/form]