<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=New+Spore</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=New+Spore"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/New_Spore"/>
	<updated>2026-07-27T06:02:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:SignpostMarv_Martin/Webmap_API_Examples&amp;diff=1032292</id>
		<title>User:SignpostMarv Martin/Webmap API Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:SignpostMarv_Martin/Webmap_API_Examples&amp;diff=1032292"/>
		<updated>2010-09-10T06:38:32Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;font-size:2.0em;&amp;quot;&amp;gt;Note: see [http://agni.sl.mapapi.net agni.sl.mapapi.net] for a production example of the refactored JavaScript.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article covers the refactored javascript for the SLURL [[Map API]] made by {{User2|SignpostMarv Martin}} for Open Hack 2009.&lt;br /&gt;
&lt;br /&gt;
Automated documentation is [http://static.marvulous.co.uk/js/slurl/docs/ available], along with a [http://static.marvulous.co.uk/%C2%B5/js/slurl/mapapi-min.js minified version] of the [http://static.marvulous.co.uk/%C2%B5/js/slurl/mapapi.js Pluggable SLurl Javascript].&lt;br /&gt;
&lt;br /&gt;
== Summary of modifications ==&lt;br /&gt;
* All functions were moved into a SLURL object, e.g. SLMap becomes SLURL.map&lt;br /&gt;
* Some functions became pluggable&lt;br /&gt;
* Some functions were improved for ease of use&lt;br /&gt;
&lt;br /&gt;
== Base HTML ==&lt;br /&gt;
Live Example: http://dev.signpostmarv.name/pub/secondlife/slurl.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html4strict&amp;gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.1//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Hack Day &#039;09: Pluggable SLurl!&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;application/xhtml+xml;charset=UTF-8&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key=[YOUR GOOGLE MAP API KEY HERE]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://www.google.com/jsapi?key=[YOUR GOOGLE SEARCH API KEY HERE]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://static.marvulous.co.uk/%C2%B5/js/slurl/mapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
/*&amp;lt;![CDATA[*/&lt;br /&gt;
$(function() {&lt;br /&gt;
	mapInstance = new SLURL.map(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
	mapInstance.gotoRegion(&#039;Hippotropolis&#039;);&lt;br /&gt;
});&lt;br /&gt;
$(document).unload(function() { &lt;br /&gt;
// Google script that helps prevent memory leaks &lt;br /&gt;
// (we&#039;re looking at you when we say that IE!)&lt;br /&gt;
	GUnload();&lt;br /&gt;
/*]]&amp;gt;*/&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding a Plugin ==&lt;br /&gt;
The key feature of the refactoring (aside from shifting everything into a SLURL object) was to make the SLURL JS &amp;quot;pluggable&amp;quot;- making it easier to extend a SLURL map without needing to create &amp;amp; edit a duplicate of the javascript (which would become difficult to maintain over time the more customisations were made).&lt;br /&gt;
&lt;br /&gt;
Currently, two functions can have callbacks registered with them:&lt;br /&gt;
# gotoRegion&lt;br /&gt;
# gotoSLURL&lt;br /&gt;
&lt;br /&gt;
The internals of a plugin can be coded however you want them to, but the callback function for the plugin must be structured along these lines:&lt;br /&gt;
&lt;br /&gt;
=== gotoSLURL,gotoRegion ===&lt;br /&gt;
&amp;lt;javascript&amp;gt;function my_callBack(slRegionName,x,y,SLMap)&lt;br /&gt;
{&lt;br /&gt;
// do stuff here&lt;br /&gt;
}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Registering a callback ===&lt;br /&gt;
Callback functions are registered to a particular instance of a SLURL map, enabling multiple maps to be used on the same page with different plugins.&lt;br /&gt;
&lt;br /&gt;
* A [http://dev.signpostmarv.name/pub/secondlife/slurl-flickr.html live example of the flickr] is available for demonstration purposes.&lt;br /&gt;
* A [http://dev.signpostmarv.name/pub/secondlife/slurl-hacks.html demonstration of multiple plugins] working in tandem is also available.&lt;br /&gt;
&lt;br /&gt;
For example, to enable Marv&#039;s Flickr plugin, the following modifications are made to the base HTML;&lt;br /&gt;
&lt;br /&gt;
1) The Flickr plugin is added below mapapi.js: &amp;lt;span&amp;gt;&amp;lt;html4strict&amp;gt;&amp;lt;script src=&amp;quot;http://static.marvulous.co.uk/%C2%B5/js/slurl/plugins/flickr.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
2) Some extra CSS is added below MAIN.css: &amp;lt;html4strict&amp;gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://dev.signpostmarv.name/pub/secondlife/slurl-hacks.css&amp;quot; /&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
3) The Flickr plugin is configured: &amp;lt;javascript&amp;gt;SLURL_flickr.apiKey = whatever_your_api_key_is;&lt;br /&gt;
SLURL_flickr.groupId = &#039;51035802764@N01&#039;; // Second Life flickr group ID- the same one linked from the official blog. change to suit.&lt;br /&gt;
SLURL_flickr.searchMode = &#039;group&#039;; // the plugin defaults to &#039;global&#039;- e.g. searching all flickr photos.&lt;br /&gt;
SLURL_flickr.resultsPerPage = 32; // the number of thumbnails to display&lt;br /&gt;
SLURL_flickr.prependResultsHTML = &#039;&#039;; // Useful for adding a header in before the results.&amp;lt;/javascript&amp;gt;&lt;br /&gt;
4) The callbacks are registered after the mapInstance has been declared: &amp;lt;javascript&amp;gt;	SLURL.addCallBack.gotoSLURL(mapInstance,SLURL_flickr.searchRegion);&lt;br /&gt;
	SLURL.addCallBack.gotoRegion(mapInstance,SLURL_flickr.searchRegion);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
5) Finally, some extra HTML for containing the flickr results is added to the body:&amp;lt;html4strict&amp;gt;&amp;lt;ul id=&amp;quot;slurl-hacks&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;slurl-hack&amp;quot; id=&amp;quot;flickr-search&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ease-of-use Improvements ==&lt;br /&gt;
=== SLURL.map.panTo ===&lt;br /&gt;
A wrapper method has been added to map instances allowing you to safely use SLURL.XYPoint instances to specify co-ordinates.&lt;br /&gt;
&amp;lt;javascript&amp;gt;mapInstance.panTo(new SLURL.XYPoint(x,y));&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding multiple scripts ===&lt;br /&gt;
* SLURL.addScript has been modified to accept an array for the scriptURL argument. Doing so will call SLURL.addScript for each item.&lt;br /&gt;
* The load handler function will be called for all scripts, though load order cannot of course be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Pluggable SLURL uses this ease-of-use modification when loading the information sources for the &#039;&#039;&#039;Events&#039;&#039;&#039; &amp;amp; &#039;&#039;&#039;Poly Info&#039;&#039;&#039; plugins:&lt;br /&gt;
&amp;lt;javascript&amp;gt;SLURL.addScript([&lt;br /&gt;
	&#039;http://svc.sl.marvulous.co.uk/sl-event-transposer.php&#039;,&lt;br /&gt;
	&#039;http://svc.sl.marvulous.co.uk/sl-mapapi-office-hours.php&#039;,&lt;br /&gt;
	&#039;http://svc.sl.marvulous.co.uk/old-grid-size.js&#039;,&lt;br /&gt;
	&#039;http://svc.sl.marvulous.co.uk/roads.js&#039;&lt;br /&gt;
]);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding GPolyline &amp;amp; GPolygon ===&lt;br /&gt;
Two new methods have been added to the SLURL namespace:&lt;br /&gt;
# SLURL.Polygon&lt;br /&gt;
# SLURL.Polyline&lt;br /&gt;
&lt;br /&gt;
Both methods will have property &#039;&#039;&#039;GPoly&#039;&#039;&#039; when instantiated, allowing them to be added to &amp;amp; removed from a map with ease.&lt;br /&gt;
&lt;br /&gt;
The first argument (used to specify the Poly points) should be an array of SLURL.XYPoint objects.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Poly Info&#039;&#039;&#039; plugin uses these methods thusly:&lt;br /&gt;
&lt;br /&gt;
==== SLURL.Polygon ====&lt;br /&gt;
&amp;lt;javascript&amp;gt;new SLURL.Polygon(info.points,info.stroke[zoom],info.fill,{},func);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
==== SLURL.Polyline ====&lt;br /&gt;
&amp;lt;javascript&amp;gt;new SLURL.Polyline(info.points,info.stroke[zoom],{},func);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding a Marker ===&lt;br /&gt;
&#039;&#039;&#039;Key Namespace Alterations&#039;&#039;&#039;&lt;br /&gt;
# SLURL.map.addMarker (previously SLMap.addMarker)&lt;br /&gt;
# SLURL.Img (previously Img)&lt;br /&gt;
# SLURL.Icon (previously Icon)&lt;br /&gt;
# SLURL.Marker (previously Marker)&lt;br /&gt;
# SLURL.XYPoint (previously XYPoint)&lt;br /&gt;
&lt;br /&gt;
SLURL.map.addMarker has been altered for ease of use- the [[Webmap API Examples#Removing a marker|previous syntax]] for adding a single image as a marker required superfluous variables:&lt;br /&gt;
&amp;lt;javascript&amp;gt;  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;,9,9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  marker = new Marker(all_images, new XYPoint(997,1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function has been modified in two ways:&lt;br /&gt;
# A single string can be passed instead of an array&lt;br /&gt;
# Arrays with fewer than 6 items have the first item padded&lt;br /&gt;
&lt;br /&gt;
These two minor alterations simplify things, making the previous example:&lt;br /&gt;
&amp;lt;javascript&amp;gt;  var yellow_dot_image = new SLURL.Img(&amp;quot;b_map_yellow.gif&amp;quot;,9,9);&lt;br /&gt;
  var yellow_icon = new SLURL.Icon(yellow_dot_image);&lt;br /&gt;
  marker = new Marker(yellow_icon,new SLURL.XYPoint(997,1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multi-Grid Support ==&lt;br /&gt;
Some significant modifications were made to allow one core Javascript file to service maps for multiple grids.&lt;br /&gt;
&lt;br /&gt;
Currently the same type of tiles as the Agni map must be used (e.g. multiple regions shrunk and composited into a single image dependant upon zoom level).&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;really&#039;&#039;&#039; under-powered demo of gridConfig is available on [http://dev.signpostmarv.name/pub/secondlife/slurl/gridConfig-demo.html Marv&#039;s dev server]- it only changes the background color and starting region (to highlight the background color change).&lt;br /&gt;
&lt;br /&gt;
=== Structure of gridConfig ===&lt;br /&gt;
&amp;lt;javascript&amp;gt;&lt;br /&gt;
// This is based on the gridConfig for Agni&lt;br /&gt;
{&lt;br /&gt;
	oceanColor : &#039;#1d475f&#039;, // background color of the &amp;quot;ocean&amp;quot; (only displayed when no image is available)&lt;br /&gt;
	defaultRegion : &#039;Ahern&#039;, // default region to direct the map to if none is specified&lt;br /&gt;
	defaultCoords : // default parcel co-ordinates for use when none are specified or some are missing.&lt;br /&gt;
	{&lt;br /&gt;
		x : 128,&lt;br /&gt;
		y : 128,&lt;br /&gt;
		z : 20&lt;br /&gt;
	},&lt;br /&gt;
	init : function(SLMap) // Called during the instantiation of a map object&lt;br /&gt;
	{&lt;br /&gt;
		// do stuff here&lt;br /&gt;
	},&lt;br /&gt;
	getTileURL : function(pos, zoom) // function for returning the grid map images&lt;br /&gt;
	{&lt;br /&gt;
		// should return an appropriate URL for the specified position &amp;amp; zoom level&lt;br /&gt;
	},&lt;br /&gt;
	gotoRegion : function(SLMap,regionName,onLoadHandler) // Should poke external web-service or hard-coded array&lt;br /&gt;
	{&lt;br /&gt;
		// do stuff here&lt;br /&gt;
	},&lt;br /&gt;
	gotoCoords : function(SLMap,x,y,z) // Should poke external web-service or hard-coded array&lt;br /&gt;
	{&lt;br /&gt;
		// do stuff here&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Specifying a gridConfig ===&lt;br /&gt;
The gridConfig object is passed as the third argument when instantiating a map object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;javascript&amp;gt;	m = new SLURL.map(&lt;br /&gt;
		document.getElementById(&#039;map-container&#039;),&lt;br /&gt;
		{},&lt;br /&gt;
		gridConfig&lt;br /&gt;
	);&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If no gridConfig is specified, the map instance will default to the gridConfig for Agni:&lt;br /&gt;
&amp;lt;javascript&amp;gt;//partial snippet from Pluggable SLurl&lt;br /&gt;
SLURL.map = function(map_element, map_options,gridConfig)&lt;br /&gt;
{&lt;br /&gt;
	if(gridConfig == undefined)&lt;br /&gt;
	{&lt;br /&gt;
		this.gridConfig = SLURL.gridConfig[&#039;com.lindenlab.agni&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		this.gridConfig = gridConfig;&lt;br /&gt;
	}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: because Agni&#039;s grid config is stored in the SLURL object, plugins could be used to replace variables or methods, removing the need to modify the core Javascript when working on new features.&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Service APIs|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Template_dictionary_python&amp;diff=997452</id>
		<title>Template dictionary python</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Template_dictionary_python&amp;diff=997452"/>
		<updated>2010-08-10T07:27:29Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;name this file makepacketdict.py in order to use it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
# uses the client&#039;s message_template.msg file to create a dictionary of name and other relevant packet info...&lt;br /&gt;
# make sure that message_template.msg has had all leading spaces removed and replaced with the correct number of  tabs --I was exceedingly lazy when I wrote this and assumed a consistent tabbing scheme in the template&lt;br /&gt;
&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def makepacketdict():&lt;br /&gt;
    dict = {}&lt;br /&gt;
    for line in open(&amp;quot;message_template.msg&amp;quot;):&lt;br /&gt;
        results = re.match(&amp;quot;^\t([^\t{}]+.+)&amp;quot;,line)&lt;br /&gt;
        if results:&lt;br /&gt;
            aline = results.group(1)&lt;br /&gt;
            aline = aline.split()&lt;br /&gt;
            if aline[1] == &amp;quot;Fixed&amp;quot;: &lt;br /&gt;
                dict[(aline[1],int(aline[2][8:],16))] = (aline[0],aline[3], aline[4])&lt;br /&gt;
            else:&lt;br /&gt;
                dict[(aline[1],int(aline[2]))] = (aline[0],aline[3], aline[4])&lt;br /&gt;
    return dict&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: AW Groupies]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Presence_Code_Python_cmd_line&amp;diff=996442</id>
		<title>Presence Code Python cmd line</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Presence_Code_Python_cmd_line&amp;diff=996442"/>
		<updated>2010-08-09T05:45:35Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a variation of the login presence code that parses the argument list for name, password and eventually url, and uses those if they exist. This allows for automated testing. The URL will eventually be used by a micro-http-server that will accept POST messages from the controlling script and parse them as commands, and return the result of that command in the http response. These could be command line style commands, or some more formal list designed for use with a GUI. This strategy allows for extremely loose coupling of a distributed test harness.&lt;br /&gt;
&lt;br /&gt;
This [[Presence_Code_Python_cmd_line_controller| sample control script]] currently only starts the login script with avatar name and password.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
from struct import *&lt;br /&gt;
from zerocode import  *&lt;br /&gt;
import md5&lt;br /&gt;
import xmlrpclib&lt;br /&gt;
import sys &lt;br /&gt;
&lt;br /&gt;
import re&lt;br /&gt;
import httplib, urllib        &lt;br /&gt;
from urlparse import urlparse    &lt;br /&gt;
import socket, sys, time&lt;br /&gt;
import uuid&lt;br /&gt;
from makepacketdict import makepacketdict&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mypacketdictionary = {}&lt;br /&gt;
outputstring = &#039;&#039;&lt;br /&gt;
ack_need_list = []&lt;br /&gt;
&lt;br /&gt;
logoutputflag = False&lt;br /&gt;
&lt;br /&gt;
if logoutputflag:&lt;br /&gt;
    temp = sys.stdout&lt;br /&gt;
    sys.stdout =open(&#039;alog.txt&#039;,&#039;w&#039;)&lt;br /&gt;
&lt;br /&gt;
def login(first, last, passwd, mac):&lt;br /&gt;
  passwd_md5 = &#039;$1$&#039; + md5.new(passwd).hexdigest()&lt;br /&gt;
 &lt;br /&gt;
  uri = &#039;http://127.0.0.1&#039;&lt;br /&gt;
  uri = &#039;https://login.agni.lindenlab.com/cgi-bin/login.cgi&#039;&lt;br /&gt;
  #uri = &#039;https://login.aditi.lindenlab.com/cgi-bin/login.cgi&#039;&lt;br /&gt;
  s = xmlrpclib.ServerProxy(uri)&lt;br /&gt;
 &lt;br /&gt;
  login_details = {&lt;br /&gt;
    &#039;first&#039;: first,&lt;br /&gt;
    &#039;last&#039;: last,&lt;br /&gt;
    &#039;passwd&#039;: passwd_md5,&lt;br /&gt;
    #&#039;start&#039;: &#039;uri:Sandbox Goguen MONO&amp;amp;133&amp;amp;111&amp;amp;21&#039;,&lt;br /&gt;
    &#039;start&#039;: &#039;uri:Stadt&amp;amp;203&amp;amp;78&amp;amp;23&#039;,&lt;br /&gt;
    &#039;major&#039;: &#039;1&#039;,&lt;br /&gt;
    #&#039;minor&#039;: &#039;20&#039;,&lt;br /&gt;
    #&#039;patch&#039;: &#039;0&#039;,&lt;br /&gt;
    #&#039;build&#039;: &#039;86489&#039;,&lt;br /&gt;
    &#039;minor&#039;: &#039;19&#039;,&lt;br /&gt;
    &#039;patch&#039;: &#039;1&#039;,&lt;br /&gt;
    &#039;build&#039;: &#039;4&#039;,&lt;br /&gt;
    &#039;platform&#039;: &#039;Win&#039;,&lt;br /&gt;
    &#039;mac&#039;: mac,&lt;br /&gt;
    &#039;options&#039;: [],&lt;br /&gt;
    &#039;user-agent&#039;: &#039;&#039;,&lt;br /&gt;
    &#039;id0&#039;: &#039;&#039;,&lt;br /&gt;
    &#039;agree_to_tos&#039;: &#039;Yes&#039;,&lt;br /&gt;
    &#039;viewer_digest&#039;: &#039;09d93740-8f37-c418-fbf2-2a78c7b0d1ea&#039;&lt;br /&gt;
  }&lt;br /&gt;
  results = s.login_to_simulator(login_details)&lt;br /&gt;
  print results&lt;br /&gt;
  &lt;br /&gt;
  return results&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def get_caps(results,cap_key, request_keys):&lt;br /&gt;
&lt;br /&gt;
  _, netloc, path, _, _, _ = urlparse(results[cap_key])&lt;br /&gt;
&lt;br /&gt;
  params = &amp;quot;&amp;lt;llsd&amp;gt;&amp;lt;array&amp;gt;&amp;lt;string&amp;gt;&amp;quot;+ request_keys[0]+&amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/array&amp;gt;&amp;lt;/llsd&amp;gt;&amp;quot;&lt;br /&gt;
  headers = {&amp;quot;content-type&amp;quot;: &amp;quot;application/xml&amp;quot;}&lt;br /&gt;
  conn = httplib.HTTPSConnection(netloc)&lt;br /&gt;
&lt;br /&gt;
  conn.request(&amp;quot;POST&amp;quot;, path, params, headers)&lt;br /&gt;
  response = conn.getresponse()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  data = response.read()&lt;br /&gt;
  conn.close()&lt;br /&gt;
  return data&lt;br /&gt;
  &lt;br /&gt;
def ExtractCap(cap_result):&lt;br /&gt;
  return re.search(r&amp;quot;&amp;lt;key&amp;gt;([a-zA-Z_]+)&amp;lt;/key&amp;gt;&amp;lt;string&amp;gt;([a-zA-Z_:/0-9-.]+)&amp;lt;/string&amp;gt;&amp;quot;, cap_result).groups()&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
def scheduleacknowledgemessage(data):&lt;br /&gt;
    if not (ord(data[0])&amp;amp;0x40):&lt;br /&gt;
        print &amp;quot;OOOPS! Got asked to ack a message that shouldn&#039;t be acked&amp;quot;&lt;br /&gt;
    else:&lt;br /&gt;
        ID = data[1:5]&lt;br /&gt;
        #if (ord(data[0])&amp;amp;0x40) &amp;amp; 0x80: ID = zero_decode_ID(ID)&lt;br /&gt;
        ack_need_list.append(unpack(&amp;quot;&amp;gt;L&amp;quot;,ID)[0])&lt;br /&gt;
        #ack_need_list.append(unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])[0])&lt;br /&gt;
        #print &amp;quot;ack needed&amp;quot;,&amp;quot;insdie schedule ack_need_list&amp;quot;, ack_need_list&lt;br /&gt;
&lt;br /&gt;
def packacks():&lt;br /&gt;
    return &amp;quot;&amp;quot;.join(pack(&amp;quot;&amp;lt;L&amp;quot;, msgnum) for msgnum in ack_need_list)&lt;br /&gt;
        &lt;br /&gt;
#def sendacks():&lt;br /&gt;
 #   if len(ack_need_list)&amp;gt;0:&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
#===============================================================================&lt;br /&gt;
# {&lt;br /&gt;
#    UUIDNameRequest Low NotTrusted Unencoded&lt;br /&gt;
#    {&lt;br /&gt;
#        UUIDNameBlock    Variable&lt;br /&gt;
#        {    ID            LLUUID    }&lt;br /&gt;
#    }&lt;br /&gt;
# }&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
def sendUUIDNameRequest(sock, port, host, currentsequence,aUUID):&lt;br /&gt;
    &lt;br /&gt;
    fix_ID = 0xffff0000 + 235&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00) &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    packed_data = &amp;quot;&amp;quot;.join(uuid.UUID(x).bytes for x in aUUID)&lt;br /&gt;
        &lt;br /&gt;
    packed_data = data_header + pack(&amp;quot;L&amp;quot;,fix_ID) + pack(&amp;quot;&amp;gt;B&amp;quot;,len(aUUID)) + packed_data&lt;br /&gt;
        &lt;br /&gt;
    sock.sendto(packed_data, (host, port)) &lt;br /&gt;
   &lt;br /&gt;
def sendRegionHandshakeReply(sock, port, host, currentsequence,agentUUID,sessionUUID):&lt;br /&gt;
    &lt;br /&gt;
    low_ID = 0xffff0000 + 149&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00)&lt;br /&gt;
    packed_data = uuid.UUID(agentUUID).bytes+uuid.UUID(sessionUUID).bytes+ pack(&amp;quot;&amp;gt;L&amp;quot;,0x00)&lt;br /&gt;
    packed_data = data_header + pack(&amp;quot;&amp;gt;L&amp;quot;,int(low_ID,16))+packed_data&lt;br /&gt;
    sock.sendto(packed_data, (host, port)) &lt;br /&gt;
    #print &amp;quot;RegionHandshakeReply&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
    return&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
        &lt;br /&gt;
def sendAgentUpdate(sock, port, host, currentsequence, result):&lt;br /&gt;
&lt;br /&gt;
#AgentUpdate&lt;br /&gt;
&lt;br /&gt;
    tempacks = packacks()&lt;br /&gt;
    del ack_need_list[:]&lt;br /&gt;
    if tempacks == &amp;quot;&amp;quot;: &lt;br /&gt;
        flags = 0x00&lt;br /&gt;
    else:&lt;br /&gt;
        flags = 0x10&lt;br /&gt;
&lt;br /&gt;
    #print &amp;quot;tempacks is:&amp;quot;, ByteToHex(tempacks)  &lt;br /&gt;
        &lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, flags,currentsequence,0x00)&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;B&#039;,0x04)&lt;br /&gt;
    packed_data_ID = uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes&lt;br /&gt;
    packed_data_QuatRots = pack(&#039;&amp;lt;ffff&#039;, 0.0,0.0,0.0,0.0)+pack(&#039;&amp;lt;ffff&#039;, 0.0,0.0,0.0,0.0)  &lt;br /&gt;
    packed_data_State = pack(&#039;&amp;lt;B&#039;, 0x00)&lt;br /&gt;
    packed_data_Camera = pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)&lt;br /&gt;
    packed_data_Flags = pack(&#039;&amp;lt;fLB&#039;, 0.0,0x00,0x00)&lt;br /&gt;
&lt;br /&gt;
    encoded_packed_data = zero_encode(packed_data_message_ID+packed_data_ID+packed_data_QuatRots+packed_data_State+packed_data_Camera+packed_data_Flags)&lt;br /&gt;
&lt;br /&gt;
    packed_data = data_header + encoded_packed_data+tempacks&lt;br /&gt;
&lt;br /&gt;
   # print &amp;quot;sending AgentUpdate to server&amp;quot;,ByteToHex(packed_data_header+zero_decode(encoded_packed_data)+ tempacks)&lt;br /&gt;
    &lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
&lt;br /&gt;
def sendCompletePingCheck(sock, port, host, currentsequence,data,lastPingSent):&lt;br /&gt;
#    print &amp;quot;data from PingCHeck&amp;quot;, ByteToHex(data)&lt;br /&gt;
    &lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00)&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;B&#039;,0x02)&lt;br /&gt;
    packed_data = data_header + packed_data_message_ID+pack(&#039;&amp;gt;B&#039;, lastPingSent)&lt;br /&gt;
    print &amp;quot;CompletePingCheck packet sent:&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
    &lt;br /&gt;
def sendPacketAck(sock, port, host,currentsequence):&lt;br /&gt;
&lt;br /&gt;
    tempacks = packacks()&lt;br /&gt;
    templen = len(ack_need_list)&lt;br /&gt;
    del ack_need_list[:]&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;,0x00,currentsequence,0x00) &lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;L&#039;,0xFFFFFFFB)&lt;br /&gt;
    packed_ack_len = pack(&#039;&amp;gt;B&#039;,templen)&lt;br /&gt;
    &lt;br /&gt;
    packed_data = data_header + packed_data_message_ID + packed_ack_len + tempacks&lt;br /&gt;
#===============================================================================&lt;br /&gt;
#    t = datetime.now()&lt;br /&gt;
#    t.strftime(&amp;quot;%H:%M:%S&amp;quot;)&lt;br /&gt;
#    ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
#    print ti, &amp;quot;PacketAck packet sent:&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
#===============================================================================&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
&lt;br /&gt;
def sendLogoutRequest(sock, port, host,seqnum,aUUID,sUUID):&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;L&#039;,0xffff00fc)&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,seqnum,0x00)&lt;br /&gt;
    packed_data = uuid.UUID(aUUID).bytes+uuid.UUID(sUUID).bytes+ pack(&amp;quot;&amp;gt;L&amp;quot;,0x00)&lt;br /&gt;
    &lt;br /&gt;
    packed_data = data_header + packed_data_message_ID + packed_data&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def establishpresence(host, port, circuit_code, result):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
    &lt;br /&gt;
       &lt;br /&gt;
    myAgentID = result[&amp;quot;agent_id&amp;quot;]&lt;br /&gt;
    mySessionID = result[&amp;quot;session_id&amp;quot;]&lt;br /&gt;
    &lt;br /&gt;
#Sending packet UseCircuitCode &amp;lt;-- Inits the connection to the sim.&lt;br /&gt;
    data = pack(&#039;&amp;gt;BLBL&#039;,0x00,0x01,00,0xffff0003) + pack(&#039;&amp;lt;L&#039;,circuit_code) + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes+uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes&lt;br /&gt;
    sock.sendto(data, (host, port))&lt;br /&gt;
&lt;br /&gt;
#ISending packet CompleteAgentMovement &amp;lt;-- establishes the agent&#039;s presence&lt;br /&gt;
    data = pack(&#039;&amp;gt;BLBL&#039;,0x00,0x02,00,0xffff00f9) + uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes + pack(&#039;&amp;lt;L&#039;, circuit_code)&lt;br /&gt;
    sock.sendto(data, (host, port))&lt;br /&gt;
&lt;br /&gt;
    sendAgentUpdate(sock, port, host, 3, result)&lt;br /&gt;
    aUUID = [result[&amp;quot;agent_id&amp;quot;]]&lt;br /&gt;
    #sendUUIDNameRequest(sock, port, host, 4,aUUID)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
    buf = 100&lt;br /&gt;
    i = 0&lt;br /&gt;
    trusted_count = 0&lt;br /&gt;
    ackable = 0&lt;br /&gt;
    trusted_and_ackable = 0&lt;br /&gt;
    ack_need_list_changed = False&lt;br /&gt;
    seqnum = 5&lt;br /&gt;
    lastPingSent = 0 &lt;br /&gt;
    trusted = 0&lt;br /&gt;
    while i&amp;lt;300:&lt;br /&gt;
        if ack_need_list_changed:&lt;br /&gt;
            ack_need_list_changed = False&lt;br /&gt;
            seqnum += 1&lt;br /&gt;
            sendPacketAck(sock, port, host,seqnum)&lt;br /&gt;
            #sendAgentUpdate(sock, port, host, seqnum, result)&lt;br /&gt;
            seqnum += 1&lt;br /&gt;
        #sendacks()&lt;br /&gt;
        i += 1&lt;br /&gt;
        data,addr = sock.recvfrom(buf)&lt;br /&gt;
        t = datetime.now()&lt;br /&gt;
        t.strftime(&amp;quot;%H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if not data:&lt;br /&gt;
            print &amp;quot;Client has exited!&amp;quot;&lt;br /&gt;
            &lt;br /&gt;
            break&lt;br /&gt;
        else:&lt;br /&gt;
            test =  ByteToHex(data).split()&lt;br /&gt;
            #print test&lt;br /&gt;
            ID = data[6:12]&lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, ByteToHex(ID) &lt;br /&gt;
            if ord(data[0])&amp;amp;0x80: &lt;br /&gt;
                ID = zero_decode_ID(data[6:12])&lt;br /&gt;
                &lt;br /&gt;
            if ord(data[0])&amp;amp;0x40: &lt;br /&gt;
                scheduleacknowledgemessage(data); &lt;br /&gt;
                ack_need_list_changed = True&lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, ByteToHex(ID) &lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;, ID[:4])&lt;br /&gt;
            if ID[0] == &#039;\xFF&#039;:&lt;br /&gt;
                if ID[1] == &#039;\xFF&#039;:&lt;br /&gt;
                    if ID[2] == &#039;\xFF&#039;:&lt;br /&gt;
                        myentry = mypacketdictionary[(&amp;quot;Fixed&amp;quot; , int(ByteToHex(ID[0:4]).replace(&#039; &#039;, &#039;&#039;),16))]&lt;br /&gt;
                        if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                            trusted += 1;&lt;br /&gt;
                        ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                        print ti, &amp;quot;Message #&amp;quot;, i, &amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,  &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                            &lt;br /&gt;
                        #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
                    else:&lt;br /&gt;
                        myentry = mypacketdictionary[(&amp;quot;Low&amp;quot;,int(ByteToHex(ID[2:4]).replace(&#039; &#039;, &#039;&#039;),16))]&lt;br /&gt;
                        if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                            trusted += 1;&lt;br /&gt;
                        ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                        print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,   &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                        if myentry[0] == &amp;quot;UUIDNameReply&amp;quot;:&lt;br /&gt;
                            pass&lt;br /&gt;
                            #print ByteToHex(data)&lt;br /&gt;
                            #print data[:28]&lt;br /&gt;
                            #print data[28:36],data[38:45]&lt;br /&gt;
                        elif myentry[0] == &amp;quot;RegionHandshake&amp;quot;:&lt;br /&gt;
                            sendRegionHandshakeReply(sock, port, host, seqnum,result[&amp;quot;agent_id&amp;quot;],result[&amp;quot;session_id&amp;quot;])&lt;br /&gt;
                            seqnum += 1&lt;br /&gt;
                        &lt;br /&gt;
                        #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
                else:&lt;br /&gt;
                    myentry = mypacketdictionary[(&amp;quot;Medium&amp;quot;, int(ByteToHex(ID[1:2]).replace(&#039; &#039;, &#039;&#039;),16))]&lt;br /&gt;
                    if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                        trusted += 1;&lt;br /&gt;
                    ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                    print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,  &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                    &lt;br /&gt;
                    &lt;br /&gt;
                    #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                    #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                    #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
            else:&lt;br /&gt;
                myentry = mypacketdictionary[(&amp;quot;High&amp;quot;, int(ByteToHex(ID[0]), 16))]&lt;br /&gt;
                if myentry[0] == &amp;quot;StartPingCheck&amp;quot;: &lt;br /&gt;
                    print &amp;quot;data from StartPingCheck&amp;quot;, test&lt;br /&gt;
                    sendCompletePingCheck(sock, port, host, seqnum,data,lastPingSent)&lt;br /&gt;
                    lastPingSent += 1&lt;br /&gt;
                    seqnum += 1&lt;br /&gt;
                    &lt;br /&gt;
                if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                    trusted += 1;   &lt;br /&gt;
                ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                &lt;br /&gt;
                print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,   &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                &lt;br /&gt;
                #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;,  trusted_and_ackable&lt;br /&gt;
                #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
    &lt;br /&gt;
    sendLogoutRequest(sock, port, host,seqnum,myAgentID,mySessionID)&lt;br /&gt;
    sock.close()&lt;br /&gt;
    print &amp;quot;final number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
argsList = sys.argv  &lt;br /&gt;
&lt;br /&gt;
if len(argsList) == 4:     # POST handler not implemented yet&lt;br /&gt;
    myResult = login(argsList[1], argsList[2], argsList[3], &amp;quot;01:02:03:04:05:06&amp;quot;)&lt;br /&gt;
else:                       #simple hard-coded startup&lt;br /&gt;
    myResult = login(&amp;quot;first&amp;quot;, &amp;quot;last&amp;quot;, &amp;quot;password&amp;quot;, &amp;quot;01:02:03:04:05:06&amp;quot;)    #note fake MAC&lt;br /&gt;
mypacketdictionary = makepacketdict()&lt;br /&gt;
&lt;br /&gt;
myhost = myResult[&amp;quot;sim_ip&amp;quot;]&lt;br /&gt;
myport = myResult[&amp;quot;sim_port&amp;quot;]&lt;br /&gt;
mycircuit_code = myResult[&amp;quot;circuit_code&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
establishpresence(myhost, myport, mycircuit_code, myResult)&lt;br /&gt;
&lt;br /&gt;
#cap_out = get_caps(result,&amp;quot;seed_capability&amp;quot;, [&amp;quot;ChatSessionRequest&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
[[Category: AW Groupies]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Makepacketdict&amp;diff=996432</id>
		<title>Makepacketdict</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Makepacketdict&amp;diff=996432"/>
		<updated>2010-08-09T02:42:34Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;brain-dead import. While it should work as-is for testing, the parsing requires you eliminate all extraneous spaces in the white space in &amp;quot;message_template.msg&amp;quot; before the &amp;quot;{&amp;quot; and replace it with tabs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
def makepacketdict():&lt;br /&gt;
    dict = {}&lt;br /&gt;
    for line in open(&amp;quot;message_template.msg&amp;quot;):&lt;br /&gt;
        results = re.match(&amp;quot;^\t([^\t{}]+.+)&amp;quot;,line)&lt;br /&gt;
        if results:&lt;br /&gt;
            aline = results.group(1)&lt;br /&gt;
            aline = aline.split()&lt;br /&gt;
            if aline[1] == &amp;quot;Fixed&amp;quot;: &lt;br /&gt;
                dict[(aline[1],aline[2])] = (aline[0],aline[3], aline[4])&lt;br /&gt;
                &lt;br /&gt;
                #print (aline[1],aline[2]) &lt;br /&gt;
                #print (aline[1],&amp;quot;0x&amp;quot;+aline[2]), dict[(aline[1],&amp;quot;0x&amp;quot;+aline[2])] &lt;br /&gt;
                #dict[(aline[1],int(aline[2][8:],16))] = (aline[0],aline[3], aline[4])&lt;br /&gt;
            else:&lt;br /&gt;
                dict[(aline[1],int(aline[2]))] = (aline[0],aline[3], aline[4])&lt;br /&gt;
    return dict&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
[[Category: AW Groupies]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=XTEA_Strong_Encryption_Implementation&amp;diff=957123</id>
		<title>XTEA Strong Encryption Implementation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=XTEA_Strong_Encryption_Implementation&amp;diff=957123"/>
		<updated>2010-07-06T00:10:37Z</updated>

		<summary type="html">&lt;p&gt;New Spore: /* XTEA LSL  PHP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}{{RightToc}}&lt;br /&gt;
&lt;br /&gt;
XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
Version 1.0&lt;br /&gt;
&lt;br /&gt;
= Contributors =&lt;br /&gt;
*[http://morsedillon.com/ Morse Dillon], Author, (morseATmorsedillon.com)&lt;br /&gt;
*{{User|Strife Onizuka}} (blindwandererATgmail.com)&lt;br /&gt;
*[http://dedricmauriac.wordpress.com/ Dedric Mauriac], Contributor (dedric.mauriacATgmail.com)&lt;br /&gt;
*{{User|JB_Kraft}} (php 5 class)&lt;br /&gt;
&lt;br /&gt;
= License =&lt;br /&gt;
This work is licensed under a [http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution-Share Alike 3.0 Unported License]&lt;br /&gt;
&lt;br /&gt;
You are free:&lt;br /&gt;
*&#039;&#039;&#039;to Share&#039;&#039;&#039; — to copy, distribute and transmit the work&lt;br /&gt;
*&#039;&#039;&#039;to Remix&#039;&#039;&#039; — to adapt the work&lt;br /&gt;
&lt;br /&gt;
Under the following conditions&lt;br /&gt;
*&#039;&#039;&#039;Attribution.&#039;&#039;&#039; You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).&lt;br /&gt;
&lt;br /&gt;
# For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with [http://creativecommons.org/licenses/by/3.0/ a link to this web page].&lt;br /&gt;
# Any of the above conditions can be waived if you get permission from the copyright holder.&lt;br /&gt;
# Nothing in this license impairs or restricts the author&#039;s moral rights.&lt;br /&gt;
&lt;br /&gt;
= Disclaimer =&lt;br /&gt;
This program is distributed in the hope that it will be useful, but &#039;&#039;&#039;WITHOUT ANY WARRANTY&#039;&#039;&#039;; without even the implied warranty of &#039;&#039;&#039;MERCHANTABILITY&#039;&#039;&#039; or &#039;&#039;&#039;FITNESS FOR A PARTICULAR PURPOSE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IF YOU READ ONE THING IN HERE, READ THIS&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is VERY important to remember that there is no such thing as &#039;&#039;cookbook cryptography&#039;&#039;!  Simply using this cypher does not guarantee security.  Security is an end-to-end concern and responsibility lies with you to thoroughly examine your project from all possible angles if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d rather break into your house - futzing about with picking a high-security deadbolt on the front door or walking in through the back door that you left open.&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
Included at the end of this source listing is a small bit of example  code that shows the usage.  If you wish to include this implementation in your own work, just replace the example code with your own.  Also, please do not reuse or redistribute this work without including the above text attributing this code to its author Morse Dillon, the above GPL statement, and this documentation.&lt;br /&gt;
&lt;br /&gt;
This is an implementation of the XTEA (eXtended Tiny Encryption Algorithm) block cypher.  (X)TEA is a very good choice of cipher when security is important but computational power is limited.  Although I did a lot of work on this implementation, enormous amounts of credit must be given to the creators of the algorithm and those who came before me to implement it in other languages and computing environments.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you do decide to use this code in a project, I&#039;d appreciate hearing about it.  You can reach me by e-mail at: morseATmorsedillon.com&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== About TEA ==&lt;br /&gt;
&lt;br /&gt;
The Tiny Encryption Algorithm ([http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm TEA]), was originally designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory.  The [http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html algorithm] itself is not subject to any patents.  While the original TEA was found to have some minor weaknesses, the eXtended Tiny Encryption Algorithm ([http://en.wikipedia.org/wiki/XTEA XTEA]) implemented herein addresses these.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;NOTE: XTEA has been superseded by Corrected Block TEA ([http://en.wikipedia.org/wiki/XXTEA XXTEA])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TEA and its derivatives consist of 64-bit block [http://en.wikipedia.org/wiki/Feistel_cipher Feistel network] with a 128-bit key.  This implementation uses six cycles, or rounds, which is less than one would like but still provides a reasonable level of security (16 is sufficient while 8 is enough for most applications).  Six is said to achieve theoretically good dispersion, but should more security be desired the number of cycles can easily be modified by changing the CYCLES global variable.  Due to the low execution speed of LSL scripts, it&#039;s suggested to make this as low as your comfort level allows.  Encryption time scales linearly with the number of cycles.&lt;br /&gt;
&lt;br /&gt;
== About this implementation ==&lt;br /&gt;
This is a bare bones implementation, and is meant to be included in the body of the script needing encryption facilities or wrapped in a link message handler.  If the latter approach is desired, care should be taken to only send link messages to the prim containing this implementation.  If ALL_PRIMS is used as the destination, one could link a link message listener to the object and intercept clear-text communications.  &lt;br /&gt;
&lt;br /&gt;
If you plan to place this code into the same script as that needing encryption facilities, you need only call the following functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string Encrypt(string clearText)&lt;br /&gt;
string Decrypt(string cypherText)&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple as that.&lt;br /&gt;
&lt;br /&gt;
This implementation does not provide any secure key exchange, so in terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
&lt;br /&gt;
The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3, and KEY4.  These are global variables at the beginning of the source and can be set using a method that works for you.&lt;br /&gt;
&lt;br /&gt;
==Changes==&lt;br /&gt;
&lt;br /&gt;
===Version 1.1===&lt;br /&gt;
*Changed to treat [[Right Shift]] as if integers were unsigned&lt;br /&gt;
&lt;br /&gt;
===Version 1.0a - Alpha===&lt;br /&gt;
*General optimization to run faster and use less bytecode.&lt;br /&gt;
*Encrypt: Pad works differently, no longer extra characters appended to the output.&lt;br /&gt;
*TEAEncrypt: Changed the return type&lt;br /&gt;
*ord: Added null support.&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
*Initial Release&lt;br /&gt;
&lt;br /&gt;
== Future Recommendations ==&lt;br /&gt;
*Support [[UTF-8]]&lt;br /&gt;
*Output to [[Base64]] instead of [[Hex]] strings&lt;br /&gt;
*Append hash to the message to verify integrity of data&lt;br /&gt;
*Hash clear-text passwords into 128 bit keys&lt;br /&gt;
*Upgrade to XXTEA&lt;br /&gt;
&lt;br /&gt;
= Code =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Original ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
//Version 1.0&lt;br /&gt;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)&lt;br /&gt;
//&lt;br /&gt;
//This program is free software; you can redistribute it and/or&lt;br /&gt;
//modify it under the terms of the GNU General Public License&lt;br /&gt;
//as published by the Free Software Foundation; either version 2&lt;br /&gt;
//of the License, or (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
//This program is distributed in the hope that it will be useful,&lt;br /&gt;
//but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
//GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
//You should have received a copy of the GNU General Public License&lt;br /&gt;
//along with this program; if not, write to the Free Software&lt;br /&gt;
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA&lt;br /&gt;
//02110-1301, USA.&lt;br /&gt;
//========================================================================&lt;br /&gt;
//&lt;br /&gt;
//Included at the end of this source listing is a small bit of example &lt;br /&gt;
//code that shows the usage.  If you wish to include this implementation &lt;br /&gt;
//in your own work, just replace the example code with your own.  Also, &lt;br /&gt;
//please do not reuse or redistribute this work without including the &lt;br /&gt;
//above text attributing this code to its author Morse Dillon, the above&lt;br /&gt;
//GPL statement, and this documentation.&lt;br /&gt;
//&lt;br /&gt;
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) &lt;br /&gt;
//block cypher.  (X)TEA is a very good choice of cipher when security&lt;br /&gt;
//is important but computational power is limited.  Although I did a&lt;br /&gt;
//lot of work on this implementation, enormous amounts of credit must&lt;br /&gt;
//be given to the creators of the algorithm and those who came before&lt;br /&gt;
//me to implement it in other languages and computing environments.&lt;br /&gt;
//&lt;br /&gt;
//***If you do decide to use this code in a project, I&#039;d appreciate &lt;br /&gt;
//hearing about it.  You can reach me by e-mail at:  &lt;br /&gt;
//morseATmorsedillon.com&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT TEA AND XTEA&lt;br /&gt;
//------------------&lt;br /&gt;
//TEA was originally designed by David Wheeler and Roger Needham &lt;br /&gt;
//of the Cambridge Computer Laboratory.  The algorithm itself is not&lt;br /&gt;
//subject to any patents.  While the original TEA was found to have&lt;br /&gt;
//some minor weaknesses, XTEA (implemented herein) addresses these.  &lt;br /&gt;
//&lt;br /&gt;
//TEA and its derivatives consist of 64-bit block Feistel network &lt;br /&gt;
//with a 128-bit key.  This implementation uses six cycles, or rounds,&lt;br /&gt;
//which is less than one would like but still provides a reasonable&lt;br /&gt;
//level of security (16 is sufficient while 8 is enough for most &lt;br /&gt;
//applications).  Six is said to achieve theoretically good dispersion, &lt;br /&gt;
//but should more security be desired the number of cycles can easily be &lt;br /&gt;
//modified by changing the CYCLES global variable.  Due to the low &lt;br /&gt;
//execution speed of LSL scripts, it&#039;s suggested to make this as low as &lt;br /&gt;
//your comfort level allows.  Encryption time scales linearly with the &lt;br /&gt;
//number of cycles.&lt;br /&gt;
//&lt;br /&gt;
//For more information about XTEA, see the following:&lt;br /&gt;
//&lt;br /&gt;
//Original Paper by Walker and Needham&lt;br /&gt;
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html&lt;br /&gt;
//&lt;br /&gt;
//Wikipedia on TEA&lt;br /&gt;
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT THIS IMPLEMENTATION&lt;br /&gt;
//-------------------------&lt;br /&gt;
//This is a barebones implementation, and is meant to be included in&lt;br /&gt;
//the body of the script needing encryption facilities or wrapped&lt;br /&gt;
//in a link message handler.  If the latter approach is desired, care&lt;br /&gt;
//should be taken to only send link messages to the prim containing&lt;br /&gt;
//this implementation.  If ALL_PRIMS is used as the destination,&lt;br /&gt;
//one could link a link message listener to the object and intercept&lt;br /&gt;
//cleartext communications.  &lt;br /&gt;
//&lt;br /&gt;
//If you plan to place this code into the same script as that needing&lt;br /&gt;
//encryption facilities, you need only call the following functions:&lt;br /&gt;
//&lt;br /&gt;
//string Encrypt(string cleartext)&lt;br /&gt;
//string Decrypt(string cyphertext)&lt;br /&gt;
//&lt;br /&gt;
//Simple as that.&lt;br /&gt;
//&lt;br /&gt;
//This implementation does not provide any secure key exchange, so in&lt;br /&gt;
//terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
//&lt;br /&gt;
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,&lt;br /&gt;
//and KEY4.  These are global variables at the beginning of the source&lt;br /&gt;
//and can be set using a method that works for you.&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************&lt;br /&gt;
//It is VERY important to remember that there is no such thing as&lt;br /&gt;
//&#039;cookbook cryptography&#039;!  Simply using this cypher does not guarantee&lt;br /&gt;
//security.  Security is an end-to-end concern and responsibility lies&lt;br /&gt;
//with you to thoroughly examine your project from all possible angles&lt;br /&gt;
//if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d&lt;br /&gt;
//rather break into your house - futzing about with picking a high-security&lt;br /&gt;
//deadbolt on the front door or walking in through the back door that you &lt;br /&gt;
//left open.&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************&lt;br /&gt;
&lt;br /&gt;
//ENCRYPTION KEYS KEY[1-4]&lt;br /&gt;
//These together make up the 128-bit XTEA encryption key.  See the above &lt;br /&gt;
//documentation for details.  Whatever you do, don&#039;t leave them as the default.&lt;br /&gt;
integer KEY1 = 11111111;&lt;br /&gt;
integer KEY2 = 22222222;&lt;br /&gt;
integer KEY3 = 33333333;&lt;br /&gt;
integer KEY4 = 44444444;&lt;br /&gt;
&lt;br /&gt;
//DEBUG_FLAG&lt;br /&gt;
//If set to 1, will cause debug text to be printed containing some &lt;br /&gt;
//intermediate cleartext/cyphertext and the resultant cyphertext/cleartext.  &lt;br /&gt;
//Do not leave this enabled in production environments!!!!&lt;br /&gt;
integer DEBUG_FLAG = 0;&lt;br /&gt;
&lt;br /&gt;
//COMM_CHANNEL&lt;br /&gt;
//Specifies which channel should be used for debug and test harness communication.&lt;br /&gt;
integer COMM_CHANNEL = 0;&lt;br /&gt;
&lt;br /&gt;
//CYCLES&lt;br /&gt;
//Specifies the number of rounds to be used.  See the above documentation for&lt;br /&gt;
//details.&lt;br /&gt;
integer CYCLES = 6;&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS END HERE*********************&lt;br /&gt;
&lt;br /&gt;
//Other Globals&lt;br /&gt;
list cypherkey = [];&lt;br /&gt;
integer delta = 0x9E3779B9;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: ord&lt;br /&gt;
//Returns the index of an ASCII character&lt;br /&gt;
integer ord(string chr)&lt;br /&gt;
{&lt;br /&gt;
    string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
    if(llStringLength(chr) != 1) return -1;&lt;br /&gt;
    if(chr == &amp;quot; &amp;quot;) return 32;&lt;br /&gt;
    return llSubStringIndex(ASCII, chr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: chr&lt;br /&gt;
//Returns the ASCII character correspondent to index i&lt;br /&gt;
string chr(integer i)&lt;br /&gt;
{&lt;br /&gt;
    string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
    i %= 127;&lt;br /&gt;
    return llGetSubString(ASCII, i, i);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
                     &lt;br /&gt;
//Function:  DWord2Hex&lt;br /&gt;
//Converts a dword containted in a LSL integer to hexadecimal format.        &lt;br /&gt;
string DWord2Hex(integer m){&lt;br /&gt;
    &lt;br /&gt;
    string result;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer index = 0;&lt;br /&gt;
    &lt;br /&gt;
    //Define character string [0-F] for use in building the hex.&lt;br /&gt;
    string characters = &amp;quot;0123456789ABCDEF&amp;quot;;   &lt;br /&gt;
    &lt;br /&gt;
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.&lt;br /&gt;
    for (i = 0; i &amp;lt; 8; i++){&lt;br /&gt;
        //Get a nibble by right-shifting and masking off 4 bits.&lt;br /&gt;
        index  = (m &amp;gt;&amp;gt; (i * 4)) &amp;amp; 0xF;&lt;br /&gt;
        //Grab character from the characters string at index position and add it to the result string.&lt;br /&gt;
        result = llInsertString(result, 0, llGetSubString(characters,index,index));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function:  Hex2DWword&lt;br /&gt;
//Converts a string containing a hexadecimal number to a dword contained in a LSL integer.&lt;br /&gt;
integer Hex2DWord(string m){&lt;br /&gt;
    integer result = 0;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    string digit;&lt;br /&gt;
    integer value;&lt;br /&gt;
    integer index;&lt;br /&gt;
    &lt;br /&gt;
    string characters = &amp;quot;0123456789ABCDEF&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; i++){&lt;br /&gt;
        &lt;br /&gt;
        index = 8 - (i + 1);&lt;br /&gt;
        digit = llGetSubString(m,index,index);&lt;br /&gt;
        &lt;br /&gt;
        value = llSubStringIndex(characters, digit);&lt;br /&gt;
                        &lt;br /&gt;
        result = result | value &amp;lt;&amp;lt; (i * 4);&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Encrypt&lt;br /&gt;
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().&lt;br /&gt;
string Encrypt(string cleartext){&lt;br /&gt;
        &lt;br /&gt;
        //Initialize variables.&lt;br /&gt;
        integer dword1 = 0;&lt;br /&gt;
        integer dword2 = 0;&lt;br /&gt;
        integer cyphertext_numeric;&lt;br /&gt;
        list cypherblock;&lt;br /&gt;
        string cyphertext = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        //Pad cleartext string to the nearest multiple of 8.&lt;br /&gt;
        while(llStringLength(cleartext) &amp;amp; 0x7) {&lt;br /&gt;
            cleartext += &amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Define more variables pertaining to while loop.&lt;br /&gt;
        integer stringlength = llStringLength(cleartext); &lt;br /&gt;
        integer i=0;&lt;br /&gt;
        integer character;&lt;br /&gt;
        &lt;br /&gt;
        //Step through cleartext string, encrypting it in 64-bit (8 character) blocks.&lt;br /&gt;
        while (i &amp;lt; stringlength){&lt;br /&gt;
            &lt;br /&gt;
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.&lt;br /&gt;
            //4th byte winds up in the most-significant position.&lt;br /&gt;
            dword1 =  ord(llGetSubString(cleartext,i,i));&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 8);&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 16);&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 24);&lt;br /&gt;
            i++;&lt;br /&gt;
            &lt;br /&gt;
            //Do it again, this time for dword2                            &lt;br /&gt;
            dword2 =  ord(llGetSubString(cleartext,i,i));&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 8;&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 16;&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 24;&lt;br /&gt;
            i++;&lt;br /&gt;
&lt;br /&gt;
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.&lt;br /&gt;
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);&lt;br /&gt;
 &lt;br /&gt;
            //Convert dword values from cypherblock to hex and append to cyphertext.&lt;br /&gt;
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));&lt;br /&gt;
                    &lt;br /&gt;
            //Reset variables for the next round, just to be safe.&lt;br /&gt;
            dword1 = 0;&lt;br /&gt;
            dword2 = 0;&lt;br /&gt;
            cypherblock = [];&lt;br /&gt;
            &lt;br /&gt;
            if(DEBUG_FLAG){&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Crypt DWords: &amp;quot; + (string)dword1 + &amp;quot;,&amp;quot; + (string)dword2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Crypt DWords: &amp;quot; + (string)llList2Integer(cypherblock,1) + &amp;quot;,&amp;quot; + (string)llList2Integer(cypherblock,2));    &lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Crypt Hex: &amp;quot; + DWord2Hex(llList2Integer(cypherblock,1)) + &amp;quot;,&amp;quot; + DWord2Hex(llList2Integer(cypherblock,2)));&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        return cyphertext;        &lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Decrypt&lt;br /&gt;
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.&lt;br /&gt;
string Decrypt(string cyphertext){&lt;br /&gt;
        &lt;br /&gt;
        //Initialize variables.&lt;br /&gt;
        string hexvalue1 = &amp;quot;&amp;quot;;&lt;br /&gt;
        string hexvalue2 = &amp;quot;&amp;quot;;&lt;br /&gt;
        integer dword1 = 0;&lt;br /&gt;
        integer dword2 = 0;&lt;br /&gt;
        list clearblock = []; //res&lt;br /&gt;
        string cleartext = &amp;quot;&amp;quot;;&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        //Step through cyphertext string, descrypting it block by block.&lt;br /&gt;
        while (i &amp;lt; llStringLength(cyphertext)){&lt;br /&gt;
            &lt;br /&gt;
            //Pull first 32 bits worth of hexadecimal into hexvalue1&lt;br /&gt;
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);&lt;br /&gt;
            i = i + 8;&lt;br /&gt;
            &lt;br /&gt;
            //Pull second 32 bits worth of hexadecimal into hexvalue2&lt;br /&gt;
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);&lt;br /&gt;
            i = i + 8;&lt;br /&gt;
&lt;br /&gt;
            //Convert hexvalues to dwords contained in LSL integers.&lt;br /&gt;
            dword1 = Hex2DWord(hexvalue1);&lt;br /&gt;
            dword2 = Hex2DWord(hexvalue2); &lt;br /&gt;
    &lt;br /&gt;
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.&lt;br /&gt;
            clearblock = TEADecrypt(dword1, dword2, cypherkey);&lt;br /&gt;
            &lt;br /&gt;
            //Append first 4 characters of ASCII to cleartext string.&lt;br /&gt;
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.&lt;br /&gt;
            cleartext += chr( llList2Integer(clearblock,0) &amp;amp; 0x000000FF);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0x0000FF00)  &amp;gt;&amp;gt; 8);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0x00FF0000)  &amp;gt;&amp;gt; 16);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0xFF000000)  &amp;gt;&amp;gt; 24);&lt;br /&gt;
&lt;br /&gt;
            //Append second 4 characters of ASCII to cleartext string.&lt;br /&gt;
            cleartext += chr( llList2Integer(clearblock,1) &amp;amp; 0x000000FF);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0x0000FF00)  &amp;gt;&amp;gt; 8);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0x00FF0000)  &amp;gt;&amp;gt; 16);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0xFF000000)  &amp;gt;&amp;gt; 24);&lt;br /&gt;
&lt;br /&gt;
            //Reset variables for the next two blocks of decrypt.            &lt;br /&gt;
            hexvalue1 = &amp;quot;&amp;quot;;&lt;br /&gt;
            hexvalue2 = &amp;quot;&amp;quot;;&lt;br /&gt;
            dword1 = 0;&lt;br /&gt;
            dword2 = 0;&lt;br /&gt;
            clearblock = [];&lt;br /&gt;
            &lt;br /&gt;
            if(DEBUG_FLAG){&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Decrypt Hex: &amp;quot; + hexvalue1 + &amp;quot;,&amp;quot; + hexvalue2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Decrypt DWords: &amp;quot; + (string)dword1 + &amp;quot;,&amp;quot; + (string)dword2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Decrypt DWords: &amp;quot; + (string)llList2Integer(clearblock,1) + &amp;quot;,&amp;quot; + (string)llList2Integer(clearblock,2));&lt;br /&gt;
            }&lt;br /&gt;
             &lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return cleartext;        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEAEncrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cleartext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cyphertext in an LSL list of two integers.&lt;br /&gt;
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){&lt;br /&gt;
    &lt;br /&gt;
            list cryptlist = [];&lt;br /&gt;
            &lt;br /&gt;
            //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
            integer n = CYCLES;&lt;br /&gt;
                        &lt;br /&gt;
            integer sum = 0;&lt;br /&gt;
            &lt;br /&gt;
            //Operate for the specified number of cycles.&lt;br /&gt;
            while (n-- &amp;gt; 0){&lt;br /&gt;
                dword1 = dword1 + ( ( dword2 &amp;lt;&amp;lt; 4 ^ ((dword2 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum &amp;amp; 3) ) );&lt;br /&gt;
                sum += delta;&lt;br /&gt;
                dword2 = dword2 + ( ( dword1 &amp;lt;&amp;lt; 4 ^ ((dword1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum &amp;gt;&amp;gt; 11) &amp;amp; 3) ) );&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            cryptlist = [dword1,dword2];&lt;br /&gt;
&lt;br /&gt;
            return cryptlist;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cyphertext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cleartext in an LSL list of two integers.&lt;br /&gt;
list TEADecrypt(integer dword1, integer dword2,list cypherkey){&lt;br /&gt;
    &lt;br /&gt;
            list cryptlist = [];&lt;br /&gt;
            &lt;br /&gt;
            //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
            integer n = CYCLES;&lt;br /&gt;
                        &lt;br /&gt;
            integer sum = delta * CYCLES;&lt;br /&gt;
&lt;br /&gt;
            //Operate for the specified number of cycles.        &lt;br /&gt;
            while (n-- &amp;gt; 0){&lt;br /&gt;
                dword2 = dword2 - ( ( dword1 &amp;lt;&amp;lt; 4 ^ ((dword1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum &amp;gt;&amp;gt; 11) &amp;amp; 3) ) );&lt;br /&gt;
                sum -= delta;&lt;br /&gt;
                dword1 = dword1 - ( ( dword2 &amp;lt;&amp;lt; 4 ^ ((dword2 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum &amp;amp; 3) ) );        &lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            cryptlist = [dword1,dword2];&lt;br /&gt;
            return cryptlist;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage Example ==&lt;br /&gt;
Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cypher-text. Object than says the encrypted and decrypted messages to the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(COMM_CHANNEL, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        cypherkey = [KEY1,KEY2,KEY3,KEY4];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string temp_cyphertext = Encrypt(message);&lt;br /&gt;
        &lt;br /&gt;
        string temp_cleartext = Decrypt(temp_cyphertext);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;\nOriginal Cleartext: &amp;quot; + message + &amp;quot;\nCyphertext: &amp;quot; + temp_cyphertext + &amp;quot;\nDecrypted Cleartext: &amp;quot; + temp_cleartext);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimized ==&lt;br /&gt;
This version is untested but if it works should run faster (and be able to handle larger strings).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Include the documentation comments from above (separated here only for easier management)&lt;br /&gt;
&lt;br /&gt;
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
//Version 1.0a Alpha&lt;br /&gt;
//Copyright (C) 2007 by Strife Onizuka (blindwandererATgmail.com)&lt;br /&gt;
//&lt;br /&gt;
//Version 1.0&lt;br /&gt;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)&lt;br /&gt;
//&lt;br /&gt;
//This program is free software; you can redistribute it and/or&lt;br /&gt;
//modify it under the terms of the GNU General Public License&lt;br /&gt;
//as published by the Free Software Foundation; either version 2&lt;br /&gt;
//of the License, or (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
//This program is distributed in the hope that it will be useful,&lt;br /&gt;
//but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
//GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
//You should have received a copy of the GNU General Public License&lt;br /&gt;
//along with this program; if not, write to the Free Software&lt;br /&gt;
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA&lt;br /&gt;
//02110-1301, USA.&lt;br /&gt;
//========================================================================&lt;br /&gt;
//&lt;br /&gt;
//Included at the end of this source listing is a small bit of example &lt;br /&gt;
//code that shows the usage.  If you wish to include this implementation &lt;br /&gt;
//in your own work, just replace the example code with your own.  Also, &lt;br /&gt;
//please do not reuse or redistribute this work without including the &lt;br /&gt;
//above text attributing this code to its author Morse Dillon, the above&lt;br /&gt;
//GPL statement, and this documentation.&lt;br /&gt;
//&lt;br /&gt;
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) &lt;br /&gt;
//block cypher.  (X)TEA is a very good choice of cipher when security&lt;br /&gt;
//is important but computational power is limited.  Although I did a&lt;br /&gt;
//lot of work on this implementation, enormous amounts of credit must&lt;br /&gt;
//be given to the creators of the algorithm and those who came before&lt;br /&gt;
//me to implement it in other languages and computing environments.&lt;br /&gt;
//&lt;br /&gt;
//***If you do decide to use this code in a project, I&#039;d appreciate &lt;br /&gt;
//hearing about it.  You can reach me by e-mail at:  &lt;br /&gt;
//morseATmorsedillon.com&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT TEA AND XTEA&lt;br /&gt;
//------------------&lt;br /&gt;
//TEA was originally designed by David Wheeler and Roger Needham &lt;br /&gt;
//of the Cambridge Computer Laboratory.  The algorithm itself is not&lt;br /&gt;
//subject to any patents.  While the original TEA was found to have&lt;br /&gt;
//some minor weaknesses, XTEA (implemented herein) addresses these.  &lt;br /&gt;
//&lt;br /&gt;
//TEA and its derivatives consist of 64-bit block Feistel network &lt;br /&gt;
//with a 128-bit key.  This implementation uses six cycles, or rounds,&lt;br /&gt;
//which is less than one would like but still provides a reasonable&lt;br /&gt;
//level of security (16 is sufficient while 8 is enough for most &lt;br /&gt;
//applications).  Six is said to achieve theoretically good dispersion, &lt;br /&gt;
//but should more security be desired the number of cycles can easily be &lt;br /&gt;
//modified by changing the CYCLES global variable.  Due to the low &lt;br /&gt;
//execution speed of LSL scripts, it&#039;s suggested to make this as low as &lt;br /&gt;
//your comfort level allows.  Encryption time scales linearly with the &lt;br /&gt;
//number of cycles.&lt;br /&gt;
//&lt;br /&gt;
//For more information about XTEA, see the following:&lt;br /&gt;
//&lt;br /&gt;
//Original Paper by Walker and Needham&lt;br /&gt;
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html&lt;br /&gt;
//&lt;br /&gt;
//Wikipedia on TEA&lt;br /&gt;
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT THIS IMPLEMENTATION&lt;br /&gt;
//-------------------------&lt;br /&gt;
//This is a barebones implementation, and is meant to be included in&lt;br /&gt;
//the body of the script needing encryption facilities or wrapped&lt;br /&gt;
//in a link message handler.  If the latter approach is desired, care&lt;br /&gt;
//should be taken to only send link messages to the prim containing&lt;br /&gt;
//this implementation.  If ALL_PRIMS is used as the destination,&lt;br /&gt;
//one could link a link message listener to the object and intercept&lt;br /&gt;
//cleartext communications.  &lt;br /&gt;
//&lt;br /&gt;
//If you plan to place this code into the same script as that needing&lt;br /&gt;
//encryption facilities, you need only call the following functions:&lt;br /&gt;
//&lt;br /&gt;
//string Encrypt(string cleartext)&lt;br /&gt;
//string Decrypt(string cyphertext)&lt;br /&gt;
//&lt;br /&gt;
//Simple as that.&lt;br /&gt;
//&lt;br /&gt;
//This implementation does not provide any secure key exchange, so in&lt;br /&gt;
//terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
//&lt;br /&gt;
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,&lt;br /&gt;
//and KEY4.  These are global variables at the beginning of the source&lt;br /&gt;
//and can be set using a method that works for you.&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//CHANGES&lt;br /&gt;
//-------&lt;br /&gt;
//&lt;br /&gt;
//1.0a - Alpha&lt;br /&gt;
//*General optimization to run faster and use less bytecode.&lt;br /&gt;
//*Encrypt: Pad works differently, no longer extra characters appended to the output.&lt;br /&gt;
//*TEAEncrypt: Changed the return type&lt;br /&gt;
//*ord: Added null support.&lt;br /&gt;
//&lt;br /&gt;
//1.0&lt;br /&gt;
//*Initial Release&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//FUTURE CHANGES&lt;br /&gt;
//--------------&lt;br /&gt;
//&lt;br /&gt;
//It would be nice if it supported UTF-8; but adding that would be alot&lt;br /&gt;
//of work. The main issue is the decoding, the bytes would have to be&lt;br /&gt;
//reassembled into characters. It would be time consuming. Another possibility&lt;br /&gt;
//would be to implement XTEA to output to BASE64 instead of hex strings (also&lt;br /&gt;
//time consuming to implement).&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************&lt;br /&gt;
//It is VERY important to remember that there is no such thing as&lt;br /&gt;
//&#039;cookbook cryptography&#039;!  Simply using this cypher does not guarantee&lt;br /&gt;
//security.  Security is an end-to-end concern and responsibility lies&lt;br /&gt;
//with you to thoroughly examine your project from all possible angles&lt;br /&gt;
//if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d&lt;br /&gt;
//rather break into your house - futzing about with picking a high-security&lt;br /&gt;
//deadbolt on the front door or walking in through the back door that you &lt;br /&gt;
//left open.&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************&lt;br /&gt;
&lt;br /&gt;
//ENCRYPTION KEYS KEY[1-4]&lt;br /&gt;
//These together make up the 128-bit XTEA encryption key.  See the above &lt;br /&gt;
//documentation for details.  Whatever you do, don&#039;t leave them as the default.&lt;br /&gt;
//Don&#039;t be stupid and make it obvious like your av&#039;s key.&lt;br /&gt;
integer KEY1 = 11111111;&lt;br /&gt;
integer KEY2 = 22222222;&lt;br /&gt;
integer KEY3 = 33333333;&lt;br /&gt;
integer KEY4 = 44444444;&lt;br /&gt;
&lt;br /&gt;
//COMM_CHANNEL&lt;br /&gt;
//Specifies which channel should be used for debug and test harness communication.&lt;br /&gt;
integer COMM_CHANNEL = 0;&lt;br /&gt;
&lt;br /&gt;
//CYCLES&lt;br /&gt;
//Specifies the number of rounds to be used.  See the above documentation for&lt;br /&gt;
//details.&lt;br /&gt;
integer CYCLES = 6;&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS END HERE*********************&lt;br /&gt;
&lt;br /&gt;
//Other Globals&lt;br /&gt;
list cypherkey = [];&lt;br /&gt;
integer delta = 0x9E3779B9;&lt;br /&gt;
&lt;br /&gt;
string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
string characters = &amp;quot;0123456789ABCDEF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//Function: ord&lt;br /&gt;
//Returns the index of an ASCII character&lt;br /&gt;
integer ord(string chr)&lt;br /&gt;
{&lt;br /&gt;
    if(chr)&lt;br /&gt;
    {&lt;br /&gt;
        if(llStringLength(chr) &amp;gt; 1) return -1;&lt;br /&gt;
        if(chr == &amp;quot; &amp;quot;) return 32;&lt;br /&gt;
        return llSubStringIndex(ASCII, chr);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function: chr&lt;br /&gt;
//Returns the ASCII character correspondent to index i&lt;br /&gt;
string chr(integer i)&lt;br /&gt;
{&lt;br /&gt;
    if(i)&lt;br /&gt;
        return llGetSubString(ASCII, i %= 127, i);&lt;br /&gt;
    return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function:  DWord2Hex&lt;br /&gt;
//Converts a dword contained in a LSL integer to hexadecimal format.        &lt;br /&gt;
string DWord2Hex(integer m)&lt;br /&gt;
{&lt;br /&gt;
    string result;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
&lt;br /&gt;
    //Define character string [0-F] for use in building the hex.&lt;br /&gt;
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.&lt;br /&gt;
    do{&lt;br /&gt;
        integer index = (m &amp;gt;&amp;gt; i) &amp;amp; 0xF;&lt;br /&gt;
        result = llGetSubString(characters, index, index) + result;&lt;br /&gt;
    }while((i += 4) &amp;lt; 32);&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function: Encrypt&lt;br /&gt;
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().&lt;br /&gt;
string Encrypt(string cleartext)&lt;br /&gt;
{&lt;br /&gt;
    string cyphertext = &amp;quot;&amp;quot;;&lt;br /&gt;
    integer i = llStringLength(cleartext);&lt;br /&gt;
    if((i += (0x7 &amp;amp; -i)))//Pad cleartext string to the nearest multiple of 8.&lt;br /&gt;
    {&lt;br /&gt;
        //Step through cleartext string backwords, encrypting it in 64-bit (8 character) blocks.&lt;br /&gt;
        do{&lt;br /&gt;
            //i=~-i is the same as --i, just a bit faster and lighter on bytecode; requires one less stack manipulation.&lt;br /&gt;
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.&lt;br /&gt;
            //4th byte winds up in the most-significant position.&lt;br /&gt;
            integer dword2 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 8 )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 16)    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 24)    ;&lt;br /&gt;
&lt;br /&gt;
            //Do it again, this time for dword1                            &lt;br /&gt;
            integer dword1 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 8 )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 16)    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 24)    ;&lt;br /&gt;
&lt;br /&gt;
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.&lt;br /&gt;
&lt;br /&gt;
            //Convert dword values from cypherblock to hex and append to cyphertext.&lt;br /&gt;
            cyphertext = TEAEncrypt(dword1,dword2,cypherkey) + cyphertext;&lt;br /&gt;
        }while(i);&lt;br /&gt;
    }&lt;br /&gt;
    return cyphertext;&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Decrypt&lt;br /&gt;
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.&lt;br /&gt;
string Decrypt(string cyphertext){&lt;br /&gt;
&lt;br /&gt;
    //Initialize variables.&lt;br /&gt;
    string cleartext = &amp;quot;&amp;quot;;&lt;br /&gt;
    integer i = -llStringLength(cyphertext);&lt;br /&gt;
&lt;br /&gt;
    //Step through cyphertext string, decrypting it block by block.&lt;br /&gt;
    if((i -= (0xF &amp;amp; i)))//Pad cyphertext string to the nearest multiple of 16.&lt;br /&gt;
    {&lt;br /&gt;
        do&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            //Convert hexvalues to dwords contained in LSL integers.&lt;br /&gt;
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.&lt;br /&gt;
            list clearblock = TEADecrypt((integer)(&amp;quot;0x&amp;quot;+llGetSubString(cyphertext,i, ~-(i -= 8))), &lt;br /&gt;
                                         (integer)(&amp;quot;0x&amp;quot;+llGetSubString(cyphertext,i, ~-(i -= 8))), cypherkey);&lt;br /&gt;
&lt;br /&gt;
            //Append first 4 characters of ASCII to cleartext string.&lt;br /&gt;
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.&lt;br /&gt;
            integer t = llList2Integer(clearblock,1);&lt;br /&gt;
            cleartext += chr( (t      ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 8 ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 16) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t = llList2Integer(clearblock,0) &amp;gt;&amp;gt; 24) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t      ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 8 ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 16) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 24) &amp;amp; 0xFF) ;&lt;br /&gt;
        }while(i);&lt;br /&gt;
    }&lt;br /&gt;
    return cleartext;        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cleartext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cyphertext in an LSL list of two integers.&lt;br /&gt;
string TEAEncrypt(integer dword1, integer dword2, list cypherkey_)&lt;br /&gt;
{&lt;br /&gt;
    if(CYCLES &amp;gt; 0)//$[E20011] /*lslint ignore*/&lt;br /&gt;
    {&lt;br /&gt;
        //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
        integer n = CYCLES;&lt;br /&gt;
        integer sum = 0;&lt;br /&gt;
        //Operate for the specified number of cycles.&lt;br /&gt;
        do{&lt;br /&gt;
            dword1 = dword1 + ( ( dword2 &amp;lt;&amp;lt; 4 ^ dword2 &amp;gt;&amp;gt; 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, (sum &amp;amp; 3) ) );&lt;br /&gt;
            dword2 = dword2 + ( ( dword1 &amp;lt;&amp;lt; 4 ^ dword1 &amp;gt;&amp;gt; 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, ((sum += delta) &amp;gt;&amp;gt; 11 &amp;amp; 3) ) );&lt;br /&gt;
        }while (n = ~-n);&lt;br /&gt;
    }&lt;br /&gt;
    return DWord2Hex(dword1) + DWord2Hex(dword2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cyphertext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cleartext in an LSL list of two integers.&lt;br /&gt;
list TEADecrypt(integer dword1, integer dword2,list cypherkey_)&lt;br /&gt;
{&lt;br /&gt;
    if(CYCLES &amp;gt; 0)//$[E20011] /*lslint ignore*/&lt;br /&gt;
    {&lt;br /&gt;
        //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
        integer n = CYCLES;&lt;br /&gt;
        integer sum = delta * CYCLES;&lt;br /&gt;
        //Operate for the specified number of cycles.        &lt;br /&gt;
        do{&lt;br /&gt;
            dword2 = dword2 - ( ( dword1 &amp;lt;&amp;lt; 4 ^ dword1 &amp;gt;&amp;gt; 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, (sum &amp;gt;&amp;gt; 11 &amp;amp; 3) ) );&lt;br /&gt;
            dword1 = dword1 - ( ( dword2 &amp;lt;&amp;lt; 4 ^ dword2 &amp;gt;&amp;gt; 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, ((sum -= delta) &amp;amp; 3) ) );        &lt;br /&gt;
        }while (n = ~-n);&lt;br /&gt;
    }&lt;br /&gt;
    return [dword1,dword2];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//XTEA Usage Example&lt;br /&gt;
//Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cyphertext.&lt;br /&gt;
//Object than says the encrypted and decrypted messages to the owner.&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(COMM_CHANNEL, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        cypherkey = [KEY1,KEY2,KEY3,KEY4];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string temp_cyphertext = Encrypt(message);&lt;br /&gt;
&lt;br /&gt;
        string temp_cleartext = Decrypt(temp_cyphertext);&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;\nOriginal Cleartext: &amp;quot; + message + &amp;quot;\nCyphertext: &amp;quot; + temp_cyphertext + &amp;quot;\nDecrypted Cleartext: &amp;quot; + temp_cleartext);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== XTEA LSL &amp;lt;-&amp;gt; PHP ==&lt;br /&gt;
This is an XTEA implementation that has both LSL and PHP scripts to allow strong encryption not only inside LSL but also between LSL and a PHP serverscript.&lt;br /&gt;
&lt;br /&gt;
For those who want to see this in action with your Web server try these. Be sure that if you  edit these that Rounds and Key Phrase are the same in both LSL and PHP versions.&lt;br /&gt;
&lt;br /&gt;
LSL - PLACE IN PRIM -- Edit to change URL and tosend text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//************************************************// &lt;br /&gt;
//* Masa&#039;s XTEA encryption/decryption v3         *// &lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *// &lt;br /&gt;
//* intercommunication with PHP version          *// &lt;br /&gt;
//************************************************// &lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block! &lt;br /&gt;
// This code is public domain. &lt;br /&gt;
// Sleight was here 20070522 &lt;br /&gt;
// masa was here 20070315 &lt;br /&gt;
// so was strife 20070315 &lt;br /&gt;
// so was adz 20070812&lt;br /&gt;
//&lt;br /&gt;
// This was Modified by SleightOf Hand to allow&lt;br /&gt;
// Strong encryption between LSL and PHP. &lt;br /&gt;
//************************************************// &lt;br /&gt;
//* XTEA IMPLEMENTATION                          *// &lt;br /&gt;
//************************************************// &lt;br /&gt;
&lt;br /&gt;
integer XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31 &lt;br /&gt;
integer xtea_num_rounds = 6; &lt;br /&gt;
list    xtea_key        = [0, 0, 0, 0]; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Converts any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
// 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific&lt;br /&gt;
// 128 bit key is generated for any string passed.&lt;br /&gt;
list xtea_key_from_string( string str )&lt;br /&gt;
{ &lt;br /&gt;
    str = llMD5String(str,0); // Use Nonce = 0&lt;br /&gt;
    return [    hexdec(llGetSubString(  str,  0,  7)), &lt;br /&gt;
                hexdec(llGetSubString(  str,  8,  15)), &lt;br /&gt;
                hexdec(llGetSubString(  str,  16,  23)), &lt;br /&gt;
                hexdec(llGetSubString(  str,  24,  31))]; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Encipher two integers and return the result as a 12-byte string &lt;br /&gt;
// containing two base64-encoded integers. &lt;br /&gt;
string xtea_encipher( integer v0, integer v1 )&lt;br /&gt;
{ &lt;br /&gt;
    integer num_rounds = xtea_num_rounds; &lt;br /&gt;
    integer sum = 0; &lt;br /&gt;
    do { &lt;br /&gt;
        // LSL does not have unsigned integers, so when shifting right we &lt;br /&gt;
        // have to mask out sign-extension bits. &lt;br /&gt;
        v0  += (((v1 &amp;lt;&amp;lt; 4) ^ ((v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum &amp;amp; 3));&lt;br /&gt;
        sum +=  XTEA_DELTA;&lt;br /&gt;
        v1  += (((v0 &amp;lt;&amp;lt; 4) ^ ((v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3)); &lt;br /&gt;
&lt;br /&gt;
    } while( --num_rounds ); &lt;br /&gt;
    //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
    return llGetSubString(llIntegerToBase64(v0),0,5) +&lt;br /&gt;
           llGetSubString(llIntegerToBase64(v1),0,5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Decipher two base64-encoded integers and return the FIRST 30 BITS of &lt;br /&gt;
// each as one 10-byte base64-encoded string. &lt;br /&gt;
string xtea_decipher( integer v0, integer v1 )&lt;br /&gt;
{ &lt;br /&gt;
    integer num_rounds = xtea_num_rounds; &lt;br /&gt;
    integer sum = XTEA_DELTA*xtea_num_rounds; &lt;br /&gt;
    do { &lt;br /&gt;
        // LSL does not have unsigned integers, so when shifting right we &lt;br /&gt;
        // have to mask out sign-extension bits. &lt;br /&gt;
        v1  -= (((v0 &amp;lt;&amp;lt; 4) ^ ((v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum&amp;gt;&amp;gt;11) &amp;amp; 3)); &lt;br /&gt;
        sum -= XTEA_DELTA;&lt;br /&gt;
        v0  -= (((v1 &amp;lt;&amp;lt; 4) ^ ((v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum  &amp;amp; 3)); &lt;br /&gt;
    } while ( --num_rounds ); &lt;br /&gt;
&lt;br /&gt;
    return llGetSubString(llIntegerToBase64(v0), 0, 4) + &lt;br /&gt;
           llGetSubString(llIntegerToBase64(v1), 0, 4); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Encrypt a full string using XTEA. &lt;br /&gt;
string xtea_encrypt_string( string str )&lt;br /&gt;
{ &lt;br /&gt;
    // encode string &lt;br /&gt;
    str = llStringToBase64(str); &lt;br /&gt;
    // remove trailing =s so we can do our own 0 padding &lt;br /&gt;
    integer i = llSubStringIndex( str, &amp;quot;=&amp;quot; ); &lt;br /&gt;
    if ( i != -1 ) &lt;br /&gt;
        str = llDeleteSubString( str, i, -1 ); &lt;br /&gt;
&lt;br /&gt;
    // we don&#039;t want to process padding, so get length before adding it &lt;br /&gt;
    integer len = llStringLength(str); &lt;br /&gt;
&lt;br /&gt;
    // zero pad &lt;br /&gt;
    str += &amp;quot;AAAAAAAAAA=&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
    string result; &lt;br /&gt;
    i = 0; &lt;br /&gt;
&lt;br /&gt;
    do { &lt;br /&gt;
        // encipher 30 (5*6) bits at a time. &lt;br /&gt;
        result += xtea_encipher( &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str,   i, i += 4) + &amp;quot;A=&amp;quot;), &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str, ++i, i += 4) + &amp;quot;A=&amp;quot;) &lt;br /&gt;
        ); &lt;br /&gt;
    } while ( ++i &amp;lt; len ); &lt;br /&gt;
&lt;br /&gt;
    return result; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Decrypt a full string using XTEA &lt;br /&gt;
string xtea_decrypt_string( string str ) { &lt;br /&gt;
    integer len = llStringLength(str); &lt;br /&gt;
    integer i; &lt;br /&gt;
    string result; &lt;br /&gt;
    do { &lt;br /&gt;
        result += xtea_decipher( &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str,   i, i += 5) + &amp;quot;==&amp;quot;), &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str, ++i, i += 5) + &amp;quot;==&amp;quot;) &lt;br /&gt;
        ); &lt;br /&gt;
    } while ( ++i &amp;lt; len ); &lt;br /&gt;
&lt;br /&gt;
    // Replace multiple trailing zeroes with a single one &lt;br /&gt;
    i = llStringLength(result) - 1; &lt;br /&gt;
    while ( llGetSubString(result, --i, i+1) == &amp;quot;AA&amp;quot; ) &lt;br /&gt;
        result = llDeleteSubString(result, i+1, i+1); &lt;br /&gt;
    return llBase64ToString( result + &amp;quot;====&amp;quot; ); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
key requestid; // just to check if we&#039;re getting the result we&#039;ve asked for; all scripts in the same object get the same replies&lt;br /&gt;
string base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot; + &lt;br /&gt;
&lt;br /&gt;
                          &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot; + &lt;br /&gt;
&lt;br /&gt;
                          &amp;quot;0123456789+/&amp;quot;;&lt;br /&gt;
string url = &amp;quot;http://&amp;lt;enter your URL here&amp;gt;/test-script.php&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer number)&lt;br /&gt;
    {&lt;br /&gt;
        string tosend = &amp;quot;this is a message to send&amp;quot;;&lt;br /&gt;
        llWhisper(0, &amp;quot;Message to Send = &amp;quot; + tosend);&lt;br /&gt;
        xtea_key = xtea_key_from_string(&amp;quot;this is a test key&amp;quot;);&lt;br /&gt;
        string message = xtea_encrypt_string(tosend);&lt;br /&gt;
        llWhisper(0, &amp;quot;Message to Server = &amp;quot; + message);&lt;br /&gt;
        requestid = llHTTPRequest(url, &lt;br /&gt;
            [HTTP_METHOD, &amp;quot;POST&amp;quot;,&lt;br /&gt;
             HTTP_MIMETYPE, &amp;quot;application/x-www-form-urlencoded&amp;quot;],&lt;br /&gt;
            &amp;quot;parameter1=&amp;quot; + llEscapeURL(message));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == requestid) { &lt;br /&gt;
            llWhisper(0, &amp;quot;Web server sent: &amp;quot; + body);&lt;br /&gt;
            integer clean = 0;&lt;br /&gt;
            string cleanbody = &amp;quot;&amp;quot;;&lt;br /&gt;
            while(~llSubStringIndex(base64,llGetSubString(body,clean,clean))){&lt;br /&gt;
                cleanbody += llGetSubString(body,clean,clean++);&lt;br /&gt;
            }&lt;br /&gt;
            llWhisper(0, &amp;quot;Cleaned : &amp;quot; + cleanbody);&lt;br /&gt;
            llWhisper(0, &amp;quot;Web server said: &amp;quot; + xtea_decrypt_string( cleanbody ));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP Code - Place on web server at location that LSL URL will be looking for.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* Sleight&#039;s PHP XTEA encryption/decryption v3  *//&lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *//&lt;br /&gt;
//* intercommunication between PHP &amp;amp; LSL         *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block!&lt;br /&gt;
// This code is public domain.&lt;br /&gt;
// Sleight was here 20070522&lt;br /&gt;
// masa was here 20070315&lt;br /&gt;
// so was strife 20070315&lt;br /&gt;
// so was adz 20080812&lt;br /&gt;
//&lt;br /&gt;
// This was converted from the LSL version by&lt;br /&gt;
// SleightOf Hand to allow Strong encryption&lt;br /&gt;
// between LSL and PHP. If you find this useful&lt;br /&gt;
// any donations appreciated.&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* XTEA IMPLEMENTATION                          *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
&lt;br /&gt;
$_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31&lt;br /&gt;
$_xtea_num_rounds = 6;&lt;br /&gt;
$_xtea_key        = array(0, 0, 0, 0);&lt;br /&gt;
$_base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;.&lt;br /&gt;
           &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot;.&lt;br /&gt;
           &amp;quot;0123456789+/&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)&lt;br /&gt;
function base64_integer($str){&lt;br /&gt;
 global $_base64;&lt;br /&gt;
 if(strlen($str) != 8) return 0;&lt;br /&gt;
 return ((strpos($_base64,$str{0}) &amp;lt;&amp;lt; 26)|&lt;br /&gt;
 (strpos($_base64,$str{1}) &amp;lt;&amp;lt; 20)|&lt;br /&gt;
 (strpos($_base64,$str{2}) &amp;lt;&amp;lt; 14)|&lt;br /&gt;
 (strpos($_base64,$str{3}) &amp;lt;&amp;lt; 8) |&lt;br /&gt;
 (strpos($_base64,$str{4}) &amp;lt;&amp;lt; 2) |&lt;br /&gt;
 (strpos($_base64,$str{5}) &amp;gt;&amp;gt; 4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)&lt;br /&gt;
function integer_base64($int){&lt;br /&gt;
 global $_base64;&lt;br /&gt;
 if($int != (integer) $int) return 0;&lt;br /&gt;
 return  $_base64{($int &amp;gt;&amp;gt; 26 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 20 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 14 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 8 &amp;amp; 0x3F)}  .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 2 &amp;amp; 0x3F)}  .&lt;br /&gt;
 $_base64{($int &amp;lt;&amp;lt; 4 &amp;amp; 0x3F)} . &amp;quot;==&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//strict 32 bit addition using logic&lt;br /&gt;
function binadd($val1 , $val2){&lt;br /&gt;
 $tc = $val1 &amp;amp; $val2;&lt;br /&gt;
 $ta = $val1 ^ $val2;&lt;br /&gt;
 do{&lt;br /&gt;
  $tac = ($tc &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
  $tc = $ta &amp;amp; $tac;&lt;br /&gt;
  $ta = $ta ^ $tac;&lt;br /&gt;
 }while($tc);&lt;br /&gt;
 return $ta; // $ta will now be the result so return it&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Converts any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
// 4 * 32 bit integers = 128 bit Key.&lt;br /&gt;
function xtea_key_from_string( $str ) {&lt;br /&gt;
 global $_xtea_key;&lt;br /&gt;
 $str = md5($str . &amp;quot;:0&amp;quot;); // Use nonce = 0 in LSL for same output&lt;br /&gt;
 $_xtea_key[0] = hexdec(substr($str,0,8));&lt;br /&gt;
 $_xtea_key[1] = hexdec(substr($str,8,8));&lt;br /&gt;
 $_xtea_key[2] = hexdec(substr($str,16,8));&lt;br /&gt;
 $_xtea_key[3] = hexdec(substr($str,24,8));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encipher two integers and return the result as a 12-byte string&lt;br /&gt;
// containing two base64-encoded integers.&lt;br /&gt;
function xtea_encipher( $v0 , $v1 ) {&lt;br /&gt;
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds;&lt;br /&gt;
 $sum = 0;&lt;br /&gt;
 do {&lt;br /&gt;
  // LSL only has 32 bit integers. However PHP automatically changes&lt;br /&gt;
  // 32 bit integers to 64 bit floats as necessary. This causes&lt;br /&gt;
  // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
  // counterpart. I got round this by changing all addition to&lt;br /&gt;
  // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
  // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
  // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
  // encrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
&lt;br /&gt;
  // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
  // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
  // calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  $v0a = binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
  // calculate ($sum + $_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
  $v0b = binadd($sum , $_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
  // Calculate ($v0 + ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  //            ^ ($sum + $_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
  $v0 = binadd($v0 , ($v0a  ^ $v0b));&lt;br /&gt;
&lt;br /&gt;
  //Calculate ($sum + $_XTEA_DELTA)&lt;br /&gt;
  $sum = binadd($sum , $_XTEA_DELTA);&lt;br /&gt;
&lt;br /&gt;
  //Calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  $v1a = binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF))  , $v0);&lt;br /&gt;
  // Calculate ($sum + $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
  $v1b = binadd($sum , $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
  //Calculate ($v1 + ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0&lt;br /&gt;
  //           ^ ($sum &amp;amp; $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
  $v1 = binadd($v1 , ($v1a  ^ $v1b));&lt;br /&gt;
 } while( $num_rounds = ~-$num_rounds );&lt;br /&gt;
 //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
 return substr(integer_base64($v0),0,6) . substr(integer_base64($v1),0,6);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Decipher two base64-encoded integers and return the FIRST 30 BITS of&lt;br /&gt;
// each as one 10-byte base64-encoded string.&lt;br /&gt;
function xtea_decipher( $v0, $v1 ) {&lt;br /&gt;
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds;&lt;br /&gt;
 $sum = 0; // $_XTEA_DELTA * $_xtea_num_rounds;&lt;br /&gt;
 $tda = $_XTEA_DELTA;&lt;br /&gt;
 do{ // Binary multiplication using binary manipulation&lt;br /&gt;
  if($num_rounds &amp;amp; 1){&lt;br /&gt;
   $sum = binadd($sum , $tda);&lt;br /&gt;
  }&lt;br /&gt;
  $num_rounds = $num_rounds &amp;gt;&amp;gt; 1;&lt;br /&gt;
  $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
 }while($num_rounds);&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds; // reset $num_rounds back to its proper setting;&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
  // LSL only has 32 bit integers. However PHP automatically changes&lt;br /&gt;
  // 32 bit integers to 64 bit floats as necessary. This causes&lt;br /&gt;
  // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
  // counterpart. I got round this by changing all addition to&lt;br /&gt;
  // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
  // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
  // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
  // decrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
  // Subtractions are handled by using 2&#039;s compliment&lt;br /&gt;
&lt;br /&gt;
  // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
  // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
  // calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  $v1a = binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v0);&lt;br /&gt;
  // calculate ($sum + $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
  $v1b = binadd($sum , $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
  //Calculate 2&#039;s compliment of ($v1a ^ $v1b) for subtraction&lt;br /&gt;
  $v1c = binadd((~($v1a ^ $v1b)) , 1);&lt;br /&gt;
  //Calculate ($v1 - ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  //            ^ ($sum + $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
  $v1 = binadd($v1 , $v1c);&lt;br /&gt;
&lt;br /&gt;
  // Calculate new $sum based on $num_rounds - 1&lt;br /&gt;
  $tnr = $num_rounds - 1;  // Temp $num_rounds&lt;br /&gt;
  $sum = 0; // $_XTEA_DELTA * ($num_rounds - 1);&lt;br /&gt;
  $tda = $_XTEA_DELTA;&lt;br /&gt;
  do{ // Binary multiplication using binary manipulation&lt;br /&gt;
   if($tnr &amp;amp; 1){&lt;br /&gt;
    $sum = binadd($sum , $tda);&lt;br /&gt;
   }&lt;br /&gt;
   $tnr = $tnr &amp;gt;&amp;gt; 1;&lt;br /&gt;
   $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
  }while($tnr);&lt;br /&gt;
&lt;br /&gt;
  //Calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  $v0a = binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
  //Calculate ($sum + $_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
  $v0b = binadd($sum , $_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
  //Calculate 2&#039;s compliment of ($v0a ^ $v0b) for subtraction&lt;br /&gt;
  $v0c = binadd((~($v0a ^ $v0b)) , 1);&lt;br /&gt;
  //Calculate ($v0 - ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1&lt;br /&gt;
  //           ^ ($sum + $_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
  $v0 = binadd($v0 , $v0c);&lt;br /&gt;
 } while ( $num_rounds = ~-$num_rounds );&lt;br /&gt;
&lt;br /&gt;
 return substr(integer_base64($v0), 0, 5) . substr(integer_base64($v1), 0, 5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encrypt a full string using XTEA.&lt;br /&gt;
function xtea_encrypt_string( $str ) {&lt;br /&gt;
 // encode Binany string to Base64&lt;br /&gt;
 $str = base64_encode($str);&lt;br /&gt;
&lt;br /&gt;
 // remove trailing =s so we can do our own 0 padding&lt;br /&gt;
 $i = strpos($str, &#039;=&#039;, 0);&lt;br /&gt;
 if ( $i !== FALSE  ){&lt;br /&gt;
  $str = substr( $str, 0, $i);&lt;br /&gt;
 }&lt;br /&gt;
 // we don&#039;t want to process padding, so get length before adding it&lt;br /&gt;
 $len = strlen($str);&lt;br /&gt;
 // zero pad&lt;br /&gt;
 $str .= &amp;quot;AAAAAAAAAA=&amp;quot;;&lt;br /&gt;
 $result = &amp;quot;&amp;quot;;&lt;br /&gt;
 $i = 0;&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
  // encipher 30 (5*6) bits at a time.&lt;br /&gt;
  $enc1 = base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
  $i += 5;&lt;br /&gt;
  $enc2 = base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
  $i += 5;&lt;br /&gt;
  $result .= xtea_encipher($enc1, $enc2);&lt;br /&gt;
 } while ( $i &amp;lt; $len );&lt;br /&gt;
 return $result; //Return Encrypted string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Decrypt a full string using XTEA&lt;br /&gt;
function xtea_decrypt_string( $str ) {&lt;br /&gt;
 global $_base64 ;&lt;br /&gt;
&lt;br /&gt;
 $len = strlen($str);&lt;br /&gt;
 $i;&lt;br /&gt;
 $result;&lt;br /&gt;
 do {&lt;br /&gt;
  $dec1 = base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
  $i += 6;&lt;br /&gt;
  $dec2 = base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
  $i += 6;&lt;br /&gt;
  $result .= xtea_decipher( $dec1, $dec2);&lt;br /&gt;
 } while ( $i &amp;lt; $len );&lt;br /&gt;
&lt;br /&gt;
 // Replace multiple trailing zeroes with a single one&lt;br /&gt;
 $result = rtrim($result, &amp;quot;A&amp;quot;);&lt;br /&gt;
 $i = strlen($result);&lt;br /&gt;
 $mod = $i%4; //Depending on encoded length different appends are needed&lt;br /&gt;
 if($mod == 1) $result .= &amp;quot;A==&amp;quot;;&lt;br /&gt;
 else if($mod == 2 ) $result .= &amp;quot;==&amp;quot;;&lt;br /&gt;
 else if($mod == 3) $result .= &amp;quot;=&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 return base64_decode( $result );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Only works with PHP compiled as an Apache module&lt;br /&gt;
$headers = apache_request_headers();&lt;br /&gt;
&lt;br /&gt;
$objectName = $headers[&amp;quot;X-SecondLife-Object-Name&amp;quot;];&lt;br /&gt;
$objectKey     = $headers[&amp;quot;X-SecondLife-Object-Key&amp;quot;];&lt;br /&gt;
$ownerKey     = $headers[&amp;quot;X-SecondLife-Owner-Key&amp;quot;];&lt;br /&gt;
$ownerName = $headers[&amp;quot;X-SecondLife-Owner-Name&amp;quot;];&lt;br /&gt;
$region        = $headers[&amp;quot;X-SecondLife-Region&amp;quot;];&lt;br /&gt;
// and so on for getting all the other variables ...&lt;br /&gt;
&lt;br /&gt;
//to pull out this headers in other kinds of installations, use this (Adz)&lt;br /&gt;
/*&lt;br /&gt;
$objectName    = $_SERVER[&#039;HTTP_X_SECONDLIFE_OBJECT_NAME&#039;];&lt;br /&gt;
$objectKey     = $_SERVER[&#039;HTTP_X_SECONDLIFE_OBJECT_KEY&#039;];&lt;br /&gt;
$region        = $_SERVER[&#039;HTTP_X_SECONDLIFE_REGION&#039;];&lt;br /&gt;
$ownerName     = $_SERVER[&#039;HTTP_X_SECONDLIFE_OWNER_NAME&#039;];&lt;br /&gt;
$ownerKey      = $_SERVER[&#039;HTTP_X_SECONDLIFE_OWNER_KEY&#039;];&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
xtea_key_from_string(&amp;quot;this is a test key&amp;quot;);&lt;br /&gt;
// get things from $_POST[]&lt;br /&gt;
// Naturally enough, if this is empty, you won&#039;t get anything&lt;br /&gt;
$parameter1 = xtea_decrypt_string($_POST[&amp;quot;parameter1&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
echo xtea_encrypt_string($ownerName . &amp;quot; just said &amp;quot; . $parameter1) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This should result in the following output.&lt;br /&gt;
&lt;br /&gt;
Object whispers: Message to Send = this is a message to send&amp;lt;br/&amp;gt;&lt;br /&gt;
Object whispers: Message to Server = JSdgCA0FDyhgLlUnSgqMQWkAxz1AzA1vr9zwSEDnCgwJ6GNQ&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Web server sent: SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Cleaned : SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Web server said: SleightOf Hand just said this is a message to send&lt;br /&gt;
&lt;br /&gt;
PHP 5 class of XTEA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* Sleight&#039;s PHP XTEA encryption/decryption v3  *//&lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *//&lt;br /&gt;
//* intercommunication between PHP &amp;amp; LSL         *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block!&lt;br /&gt;
// This code is public domain.&lt;br /&gt;
// Sleight was here 20070522&lt;br /&gt;
// masa was here 20070315&lt;br /&gt;
// so was strife 20070315&lt;br /&gt;
// so was adz 20080812&lt;br /&gt;
// gave this some class 20080201 JB Kraft&lt;br /&gt;
//&lt;br /&gt;
// This was converted from the LSL version by&lt;br /&gt;
// SleightOf Hand to allow Strong encryption&lt;br /&gt;
// between LSL and PHP. If you find this usefull&lt;br /&gt;
// any donations apreciated.&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* XTEA IMPLEMENTATION                          *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * PHP 5 class to do XTEA crypting&lt;br /&gt;
 *&lt;br /&gt;
 * $xtea = new XTEA( &amp;quot;mypassword&amp;quot; );&lt;br /&gt;
 * $crypted = $xtea-&amp;gt;encrypt( &amp;quot;Some bogus string&amp;quot; );&lt;br /&gt;
 * echo &amp;quot;Encrypted: &amp;quot; . bin2hex($crypted);&lt;br /&gt;
 * echo &amp;quot;Decrypted: &amp;quot; . $xtea-&amp;gt;decrypt( $crypted );&lt;br /&gt;
 *&lt;br /&gt;
 * @package whatevah&lt;br /&gt;
 * @author JB Kraft&lt;br /&gt;
 **/&lt;br /&gt;
class XTEA&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  private $_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31&lt;br /&gt;
  private $_xtea_num_rounds = 6;&lt;br /&gt;
  private $_xtea_key        = array(0, 0, 0, 0);&lt;br /&gt;
  private $_base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * CTOR&lt;br /&gt;
   *&lt;br /&gt;
   * @param  $passwd the password to use for crypting&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function __construct( $passwd )&lt;br /&gt;
  {&lt;br /&gt;
    $this-&amp;gt;xtea_key_from_string( $passwd );    &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * Encrypt a full string using XTEA.&lt;br /&gt;
   *&lt;br /&gt;
   * @param $str the string to encrypt&lt;br /&gt;
   * @return the encrypted string&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function encrypt( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   // encode Binany string to Base64&lt;br /&gt;
   $str = base64_encode($str);&lt;br /&gt;
&lt;br /&gt;
   // remove trailing =s so we can do our own 0 padding&lt;br /&gt;
   $i = strpos($str, &#039;=&#039;, 0);&lt;br /&gt;
   if ( $i !== FALSE  ){&lt;br /&gt;
    $str = substr( $str, 0, $i);&lt;br /&gt;
   }&lt;br /&gt;
   // we don&#039;t want to process padding, so get length before adding it&lt;br /&gt;
   $len = strlen($str);&lt;br /&gt;
   // zero pad&lt;br /&gt;
   $str .= &amp;quot;AAAAAAAAAA=&amp;quot;;&lt;br /&gt;
   $result = &amp;quot;&amp;quot;;&lt;br /&gt;
   $i = 0;&lt;br /&gt;
&lt;br /&gt;
   do {&lt;br /&gt;
    // encipher 30 (5*6) bits at a time.&lt;br /&gt;
    $enc1 = $this-&amp;gt;base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
    $i += 5;&lt;br /&gt;
    $enc2 = $this-&amp;gt;base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
    $i += 5;&lt;br /&gt;
    $result .= $this-&amp;gt;xtea_encipher($enc1, $enc2);&lt;br /&gt;
   } while ( $i &amp;lt; $len );&lt;br /&gt;
   return $result; //Return Encrypted string&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * Decrypt a full string using XTEA&lt;br /&gt;
   *&lt;br /&gt;
   * @param $str the string to decrypt&lt;br /&gt;
   * @return the decrypted string&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function decrypt( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   $len = strlen($str);&lt;br /&gt;
   $i = 0;&lt;br /&gt;
   $result = &#039;&#039;;&lt;br /&gt;
   do {&lt;br /&gt;
    $dec1 = $this-&amp;gt;base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
    $i += 6;&lt;br /&gt;
    $dec2 = $this-&amp;gt;base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
    $i += 6;&lt;br /&gt;
    $result .= $this-&amp;gt;xtea_decipher( $dec1, $dec2);&lt;br /&gt;
   } while ( $i &amp;lt; $len );&lt;br /&gt;
&lt;br /&gt;
   // Replace multiple trailing zeroes with a single one&lt;br /&gt;
   $i = strlen($result);&lt;br /&gt;
   while ( substr($result, --$i, 1) == &amp;quot;A&amp;quot; );&lt;br /&gt;
   $result = substr($result, 0, $i+1);&lt;br /&gt;
   $i = strlen($result);&lt;br /&gt;
   $mod = $i%4; //Depending on encoded length diffrent appends are needed&lt;br /&gt;
   if($mod == 1) $result .= &amp;quot;A==&amp;quot;;&lt;br /&gt;
   else if($mod == 2 ) $result .= &amp;quot;==&amp;quot;;&lt;br /&gt;
   else if($mod == 3) $result .= &amp;quot;=&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   return base64_decode( $result );&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // -----------------------------&lt;br /&gt;
  // stuff below here is protected&lt;br /&gt;
  // -----------------------------&lt;br /&gt;
&lt;br /&gt;
  // Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)&lt;br /&gt;
  protected function base64_integer($str)&lt;br /&gt;
  {&lt;br /&gt;
   if(strlen($str) != 8) return 0;&lt;br /&gt;
   return ((strpos($this-&amp;gt;_base64,$str{0}) &amp;lt;&amp;lt; 26)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{1}) &amp;lt;&amp;lt; 20)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{2}) &amp;lt;&amp;lt; 14)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{3}) &amp;lt;&amp;lt; 8) |&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{4}) &amp;lt;&amp;lt; 2) |&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{5}) &amp;gt;&amp;gt; 4));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)&lt;br /&gt;
  protected function integer_base64($int)&lt;br /&gt;
  {&lt;br /&gt;
   if($int != (integer) $int) return 0;&lt;br /&gt;
   return  $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 26 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 20 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 14 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 8 &amp;amp; 0x3F)}  .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 2 &amp;amp; 0x3F)}  .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;lt;&amp;lt; 4 &amp;amp; 0x3F)} . &amp;quot;==&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //strict 32 bit addition using logic&lt;br /&gt;
  protected function binadd($val1 , $val2)&lt;br /&gt;
  {&lt;br /&gt;
   $tc = $val1 &amp;amp; $val2;&lt;br /&gt;
   $ta = $val1 ^ $val2;&lt;br /&gt;
   do{&lt;br /&gt;
    $tac = ($tc &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
    $tc = $ta &amp;amp; $tac;&lt;br /&gt;
    $ta = $ta ^ $tac;&lt;br /&gt;
   }while($tc);&lt;br /&gt;
   return $ta; // $ta will now be the result so return it&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Convers any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
  // 4 * 32 bit integers = 128 bit Key.&lt;br /&gt;
  protected function xtea_key_from_string( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   $str = md5($str . &amp;quot;:0&amp;quot;); // Use nonce = 0 in LSL for same output&lt;br /&gt;
   $this-&amp;gt;_xtea_key[0] = hexdec(substr($str,0,8));&lt;br /&gt;
   $this-&amp;gt;_xtea_key[1] = hexdec(substr($str,8,8));&lt;br /&gt;
   $this-&amp;gt;_xtea_key[2] = hexdec(substr($str,16,8));&lt;br /&gt;
   $this-&amp;gt;_xtea_key[3] = hexdec(substr($str,24,8));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Encipher two integers and return the result as a 12-byte string&lt;br /&gt;
  // containing two base64-encoded integers.&lt;br /&gt;
  protected function xtea_encipher( $v0 , $v1 ) &lt;br /&gt;
  {&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $sum = 0;&lt;br /&gt;
   do {&lt;br /&gt;
    // LSL only has 32 bit integers. However PHP automatically changes&lt;br /&gt;
    // 32 bit integers to 64 bit floats as necessary. This causes&lt;br /&gt;
    // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
    // counterpart. I got round this by changing all addition to&lt;br /&gt;
    // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
    // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
    // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
    // encrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
&lt;br /&gt;
    // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
    // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
    // calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    $v0a = $this-&amp;gt;binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
    // calculate ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
    $v0b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
    // Calculate ($v0 + ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    //            ^ ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
    $v0 = $this-&amp;gt;binadd($v0 , ($v0a  ^ $v0b));&lt;br /&gt;
&lt;br /&gt;
    //Calculate ($sum + $this-&amp;gt;_XTEA_DELTA)&lt;br /&gt;
    $sum = $this-&amp;gt;binadd($sum , $this-&amp;gt;_XTEA_DELTA);&lt;br /&gt;
&lt;br /&gt;
    //Calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    $v1a = $this-&amp;gt;binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF))  , $v0);&lt;br /&gt;
    // Calculate ($sum + $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
    $v1b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
    //Calculate ($v1 + ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0&lt;br /&gt;
    //           ^ ($sum &amp;amp; $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
    $v1 = $this-&amp;gt;binadd($v1 , ($v1a  ^ $v1b));&lt;br /&gt;
   } while( $num_rounds = ~-$num_rounds );&lt;br /&gt;
   //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
   return substr($this-&amp;gt;integer_base64($v0),0,6) . substr($this-&amp;gt;integer_base64($v1),0,6);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Decipher two base64-encoded integers and return the FIRST 30 BITS of&lt;br /&gt;
  // each as one 10-byte base64-encoded string.&lt;br /&gt;
  protected function xtea_decipher( $v0, $v1 ) &lt;br /&gt;
  {&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $sum = 0; // $this-&amp;gt;_XTEA_DELTA * $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $tda = $this-&amp;gt;_XTEA_DELTA;&lt;br /&gt;
   do{ // Binary multiplication using binary manipulation&lt;br /&gt;
    if($num_rounds &amp;amp; 1){&lt;br /&gt;
     $sum = $this-&amp;gt;binadd($sum , $tda);&lt;br /&gt;
    }&lt;br /&gt;
    $num_rounds = $num_rounds &amp;gt;&amp;gt; 1;&lt;br /&gt;
    $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
   }while($num_rounds);&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds; // reset $num_rounds back to its propper setting;&lt;br /&gt;
&lt;br /&gt;
   do {&lt;br /&gt;
    // LSL only has 32 bit integers. However PHP automatically changes&lt;br /&gt;
    // 32 bit integers to 64 bit floats as necessary. This causes&lt;br /&gt;
    // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
    // counterpart. I got round this by changing all addition to&lt;br /&gt;
    // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
    // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
    // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
    // decrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
    // Subtractions are handled by using 2&#039;s compliment&lt;br /&gt;
&lt;br /&gt;
    // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
    // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
    // calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    $v1a = $this-&amp;gt;binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v0);&lt;br /&gt;
    // calculate ($sum + $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
    $v1b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
    //Calculate 2&#039;s compliment of ($v1a ^ $v1b) for subtraction&lt;br /&gt;
    $v1c = $this-&amp;gt;binadd((~($v1a ^ $v1b)) , 1);&lt;br /&gt;
    //Calculate ($v1 - ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    //            ^ ($sum + $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
    $v1 = $this-&amp;gt;binadd($v1 , $v1c);&lt;br /&gt;
&lt;br /&gt;
    // Calculate new $sum based on $num_rounds - 1&lt;br /&gt;
    $tnr = $num_rounds - 1;  // Temp $num_rounds&lt;br /&gt;
    $sum = 0; // $this-&amp;gt;_XTEA_DELTA * ($num_rounds - 1);&lt;br /&gt;
    $tda = $this-&amp;gt;_XTEA_DELTA;&lt;br /&gt;
    do{ // Binary multiplication using binary manipulation&lt;br /&gt;
     if($tnr &amp;amp; 1){&lt;br /&gt;
      $sum = $this-&amp;gt;binadd($sum , $tda);&lt;br /&gt;
     }&lt;br /&gt;
     $tnr = $tnr &amp;gt;&amp;gt; 1;&lt;br /&gt;
     $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
    }while($tnr);&lt;br /&gt;
&lt;br /&gt;
    //Calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    $v0a = $this-&amp;gt;binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
    //Calculate ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
    $v0b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
    //Calculate 2&#039;s compliment of ($v0a ^ $v0b) for subtraction&lt;br /&gt;
    $v0c = $this-&amp;gt;binadd((~($v0a ^ $v0b)) , 1);&lt;br /&gt;
    //Calculate ($v0 - ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1&lt;br /&gt;
    //           ^ ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
    $v0 = $this-&amp;gt;binadd($v0 , $v0c);&lt;br /&gt;
   } while ( $num_rounds = ~-$num_rounds );&lt;br /&gt;
&lt;br /&gt;
   return substr($this-&amp;gt;integer_base64($v0), 0, 5) . substr($this-&amp;gt;integer_base64($v1), 0, 5);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Test Vectors =&lt;br /&gt;
These are test vectors to verify that the implementation is working correctly. Although the LSL implementation is for six rounds only, it can easily be changed to verify that the implementation is working as expected. Having a proper implementation allows other systems to communicate using the LSL implementation of XTEA.&lt;br /&gt;
&lt;br /&gt;
==Bouncy Castle C# API==&lt;br /&gt;
These test vectors are taken from [http://www.bouncycastle.org/csharp/ The Bouncy Castle C# API].&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Rounds&lt;br /&gt;
! Data&lt;br /&gt;
! Key&lt;br /&gt;
! Vector&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0xDEE9D4D8|}} {{LSL Hex|0xF7131ED9|}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x01020304|}} {{LSL Hex|0x05060708|}}&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x065C1B89|}} {{LSL Hex|0x75C6A816|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x01234567|}} {{LSL Hex|0x12345678|}} {{LSL Hex|0x23456789|}} {{LSL Hex|0x3456789A|}}&lt;br /&gt;
| {{LSL Hex|0x1FF9A026|}} {{LSL Hex|0x1AC64264|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x01020304|}} {{LSL Hex|0x05060708|}}&lt;br /&gt;
| {{LSL Hex|0x01234567|}} {{LSL Hex|0x12345678|}} {{LSL Hex|0x23456789|}} {{LSL Hex|0x3456789A|}}&lt;br /&gt;
| {{LSL Hex|0x8C67155B|}} {{LSL Hex|0x2EF91EAD|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Test Vectors for TEA and XTEA==&lt;br /&gt;
These test vectors used are from [http://www.cix.co.uk/~klockstone/teavect.htm Test Vectors for TEA and XTEA].&lt;br /&gt;
They are made by starting with a vector of 6 zeroes, data followed by key, and coding with one cycle then moving the six cyclically so that n becomes n-1 modulo 6.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Round&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|vector&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x9E3779B9|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
||{{LSL Hex|0xEC01A1DE|}}||{{LSL Hex|0xAAA0256D|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
||{{LSL Hex|0xBC3A7DE2|}}||{{LSL Hex|0x4E238EB9|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0xEC01A1DE|}}||{{LSL Hex|0x114F6D74|}}&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
||{{LSL Hex|0x31C5FA6C|}}||{{LSL Hex|0x241756D6|}}||{{LSL Hex|0xBC3A7DE2|}}||{{LSL Hex|0x845846CF|}}||{{LSL Hex|0x2794A127|}}||{{LSL Hex|0x6B8EA8B8|}}&lt;br /&gt;
|-&lt;br /&gt;
| 16&lt;br /&gt;
||{{LSL Hex|0x1D8E6992|}}||{{LSL Hex|0x9A478905|}}||{{LSL Hex|0x6A1D78C8|}}||{{LSL Hex|0x08C86D67|}}||{{LSL Hex|0x2A65BFBE|}}||{{LSL Hex|0xB4BD6E46|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
||{{LSL Hex|0xD26428AF|}}||{{LSL Hex|0x0A202283|}}||{{LSL Hex|0x27F917B1|}}||{{LSL Hex|0xC1DA8993|}}||{{LSL Hex|0x60E2ACAA|}}||{{LSL Hex|0xA6EB923D|}}&lt;br /&gt;
|-&lt;br /&gt;
| 64&lt;br /&gt;
||{{LSL Hex|0x7A01CBC9|}}||{{LSL Hex|0xB03D6068|}}||{{LSL Hex|0x62EE209F|}}||{{LSL Hex|0x069B7AFC|}}||{{LSL Hex|0x376A8936|}}||{{LSL Hex|0xCDC9E923|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==LSL Test==&lt;br /&gt;
The following code has been imported to LSL to test the vectors with an XTEA implementation. It also makes use of a modified version of the [[Hex]] method on this wiki to display the data. Right Shift of signed integers is handed by techniques introduced in the [[Right_Shift]] method on this wiki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// XTEA is a version of slightly improved TEA&lt;br /&gt;
// The plain or cypher text is in v[0], v[1]&lt;br /&gt;
// The key is in k[n], where n = 0 - 3&lt;br /&gt;
// The number of coding cycles is given by N and&lt;br /&gt;
// the number of decoding cycles is given by -N&lt;br /&gt;
&lt;br /&gt;
list XTEA(list v, list k, integer N) // Replaces TEA&#039;s Code and Decode&lt;br /&gt;
{&lt;br /&gt;
    integer y = llList2Integer(v, 0);&lt;br /&gt;
    integer z = llList2Integer(v, 1);&lt;br /&gt;
    integer DELTA = 0x9E3779B9;&lt;br /&gt;
    integer limit = DELTA * N;&lt;br /&gt;
    integer sum = 0;&lt;br /&gt;
    &lt;br /&gt;
    if(N &amp;gt; 0) // encrypt&lt;br /&gt;
    {&lt;br /&gt;
        while(sum != limit)&lt;br /&gt;
        {&lt;br /&gt;
            y   += (z &amp;lt;&amp;lt; 4 ^ ((z &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum &amp;amp; 3);&lt;br /&gt;
            sum += DELTA;&lt;br /&gt;
            z   += (y &amp;lt;&amp;lt; 4 ^ ((y &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // decrypt&lt;br /&gt;
    {&lt;br /&gt;
         for(sum = -limit; sum; )&lt;br /&gt;
         {   z   -= (y &amp;lt;&amp;lt; 4 ^ ((y &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3);&lt;br /&gt;
             sum -= DELTA;&lt;br /&gt;
             y   -= (z &amp;lt;&amp;lt; 4 ^ ((z &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum &amp;amp; 3);&lt;br /&gt;
         }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return [y,z];&lt;br /&gt;
}&lt;br /&gt;
string hex(integer value)&lt;br /&gt;
{&lt;br /&gt;
    string h = &amp;quot;&amp;quot;;&lt;br /&gt;
    while (value)&lt;br /&gt;
    {&lt;br /&gt;
        string c = llGetSubString(&amp;quot;0123456789ABCDEF&amp;quot;, value &amp;amp; 0xF, value &amp;amp; 0xF);&lt;br /&gt;
        h = c + h;&lt;br /&gt;
        value = (value &amp;gt;&amp;gt; 4) &amp;amp; 0x0FFFFFFF;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;0x&amp;quot; + llGetSubString(&amp;quot;00000000&amp;quot; + h, -8, -1);&lt;br /&gt;
}&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        // Bouncy Castle C# API Test Vectors&lt;br /&gt;
        list v;&lt;br /&gt;
        v = XTEA([0x00000000, 0x00000000], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0xDEE9D4D8\t0xF7131ED9&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x01020304, 0x05060708], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x065C1B89\t0x75C6A816&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x00000000, 0x00000000], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x1FF9A026\t0x1AC64264&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x01020304, 0x05060708], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x8C67155B\t0x2EF91EAD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Test Vectors for XTEA&lt;br /&gt;
&lt;br /&gt;
        list pz = [0,0,0,0,0,0,0];&lt;br /&gt;
        integer n;&lt;br /&gt;
        for (n = 1; n &amp;lt; 65; n++)&lt;br /&gt;
        {  &lt;br /&gt;
            &lt;br /&gt;
            list a = XTEA(llList2List(pz, n, n + 1), llList2List(pz, n + 2, n + 5), n);&lt;br /&gt;
            &lt;br /&gt;
            pz = llListReplaceList(pz, a, n, n + 1);&lt;br /&gt;
&lt;br /&gt;
            if (n == (n &amp;amp; -n))                         // if n power of 2&lt;br /&gt;
                llSay(DEBUG_CHANNEL, &lt;br /&gt;
                    (string)n &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 0)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 1)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 2))&lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 3)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 4))&lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 5))&lt;br /&gt;
                );&lt;br /&gt;
            pz = llListReplaceList(pz, llList2List(pz, n, n + 5), n + 6, n + 11);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#vardefine:sort|XTEA Strong Encryption Implementation}}{{LSLC|Library}}{{LSLC|Examples}}&lt;br /&gt;
 [[Category:LSL Encryption]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=AES_Java_Implementation&amp;diff=871113</id>
		<title>AES Java Implementation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=AES_Java_Implementation&amp;diff=871113"/>
		<updated>2010-04-20T00:53:44Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Description =&lt;br /&gt;
The following is a simple Java example of AES encryption and decryption, compatible with the [[AES LSL Implementation|LSL AES Engine]] by [[User:Haravikk Mistral|Haravikk Mistral]]. &lt;br /&gt;
&lt;br /&gt;
= Required Classes =&lt;br /&gt;
== Base64Coder ==&lt;br /&gt;
&amp;lt;java&amp;gt;package lslAESCrypto;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * A Base64 Encoder/Decoder.&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * This class is used to encode and decode data in Base64 format as described in&lt;br /&gt;
 * RFC 1521.&lt;br /&gt;
 * &amp;lt;/p&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
public class Base64Coder {&lt;br /&gt;
	/** Mapping table from 6-bits to Base64 characters. */&lt;br /&gt;
	private static char[] BITS_TO_BASE64_CHAR =&lt;br /&gt;
		           { &#039;A&#039;, &#039;B&#039;, &#039;C&#039;, &#039;D&#039;, &#039;E&#039;, &#039;F&#039;, &#039;G&#039;, &#039;H&#039;, &#039;I&#039;, &#039;J&#039;, &#039;K&#039;,&lt;br /&gt;
			&#039;L&#039;, &#039;M&#039;, &#039;N&#039;, &#039;O&#039;, &#039;P&#039;, &#039;Q&#039;, &#039;R&#039;, &#039;S&#039;, &#039;T&#039;, &#039;U&#039;, &#039;V&#039;, &#039;W&#039;, &#039;X&#039;,&lt;br /&gt;
			&#039;Y&#039;, &#039;Z&#039;, &#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;, &#039;g&#039;, &#039;h&#039;, &#039;i&#039;, &#039;j&#039;, &#039;k&#039;,&lt;br /&gt;
			&#039;l&#039;, &#039;m&#039;, &#039;n&#039;, &#039;o&#039;, &#039;p&#039;, &#039;q&#039;, &#039;r&#039;, &#039;s&#039;, &#039;t&#039;, &#039;u&#039;, &#039;v&#039;, &#039;w&#039;, &#039;x&#039;,&lt;br /&gt;
			&#039;y&#039;, &#039;z&#039;, &#039;0&#039;, &#039;1&#039;, &#039;2&#039;, &#039;3&#039;, &#039;4&#039;, &#039;5&#039;, &#039;6&#039;, &#039;7&#039;, &#039;8&#039;, &#039;9&#039;, &#039;+&#039;,&lt;br /&gt;
			&#039;/&#039; };&lt;br /&gt;
&lt;br /&gt;
	/** Mapping table from Base64 characters to 6-bits. */&lt;br /&gt;
	private static byte[] BASE64_CHAR_TO_BITS =&lt;br /&gt;
		          { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,&lt;br /&gt;
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,&lt;br /&gt;
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,&lt;br /&gt;
			52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1,&lt;br /&gt;
			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,&lt;br /&gt;
			19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,&lt;br /&gt;
			30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,&lt;br /&gt;
			47, 48, 49, 50, 51, -1, -1, -1, -1, -1, };&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Decodes a byte array from Base64 format. No blanks or line breaks are&lt;br /&gt;
	 * allowed within the Base64 encoded data.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param in&lt;br /&gt;
	 *            a character array containing the Base64 encoded data.&lt;br /&gt;
	 * @return An array containing the decoded data bytes.&lt;br /&gt;
	 * @throws IllegalArgumentException&lt;br /&gt;
	 *             if the input is not valid Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static byte[] decode(final char[] in)&lt;br /&gt;
		throws IllegalArgumentException {&lt;br /&gt;
		int len = in.length;&lt;br /&gt;
		if (len % 4 != 0)&lt;br /&gt;
			throw new IllegalArgumentException(&lt;br /&gt;
				&amp;quot;Length of Base64 encoded input string is not a multiple of 4.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		// Ignore trailing equals&lt;br /&gt;
		while (len &amp;gt; 0 &amp;amp;&amp;amp; in[len - 1] == &#039;=&#039;)&lt;br /&gt;
			--len;&lt;br /&gt;
&lt;br /&gt;
		final byte[] bytes = new byte[(len * 3) / 4];&lt;br /&gt;
		int o = 0;&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; len;) {&lt;br /&gt;
			try {&lt;br /&gt;
				final char c0 = in[i++];&lt;br /&gt;
				final char c1 = in[i++];&lt;br /&gt;
				final char c2 = (i &amp;lt; len) ? in[i++] : &#039;A&#039;;&lt;br /&gt;
				final char c3 = (i &amp;lt; len) ? in[i++] : &#039;A&#039;;&lt;br /&gt;
&lt;br /&gt;
				if (c0 &amp;gt; 127 || c1 &amp;gt; 127 || c2 &amp;gt; 127 || c3 &amp;gt; 127)&lt;br /&gt;
					throw new IllegalArgumentException(&lt;br /&gt;
						&amp;quot;Invalid base64 character&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
				final byte b0 = Base64Coder.BASE64_CHAR_TO_BITS[c0];&lt;br /&gt;
				final byte b1 = Base64Coder.BASE64_CHAR_TO_BITS[c1];&lt;br /&gt;
				final byte b2 = Base64Coder.BASE64_CHAR_TO_BITS[c2];&lt;br /&gt;
				final byte b3 = Base64Coder.BASE64_CHAR_TO_BITS[c3];&lt;br /&gt;
&lt;br /&gt;
				if (b0 &amp;lt; 0 || b1 &amp;lt; 0 || b2 &amp;lt; 0 || b3 &amp;lt; 0)&lt;br /&gt;
					throw new IllegalArgumentException(&lt;br /&gt;
						&amp;quot;Invalid base64 character&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
				bytes[o++] = (byte) ((b0 &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt;&amp;gt; 4));&lt;br /&gt;
				if (o &amp;lt; bytes.length) {&lt;br /&gt;
					bytes[o++] = (byte) (((b1 &amp;amp; 0xF) &amp;lt;&amp;lt; 4) | (b2 &amp;gt;&amp;gt;&amp;gt; 2));&lt;br /&gt;
					if (o &amp;lt; bytes.length)&lt;br /&gt;
						bytes[o++] = (byte) (((b2 &amp;amp; 0x3) &amp;lt;&amp;lt; 6) | b3);&lt;br /&gt;
				}&lt;br /&gt;
			} catch (final ArrayIndexOutOfBoundsException e) {&lt;br /&gt;
				throw new IllegalArgumentException(&amp;quot;Invalid base64 character&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return bytes;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Decodes a byte array from Base64 format.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param s&lt;br /&gt;
	 *            a Base64 String to be decoded.&lt;br /&gt;
	 * @return An array containing the decoded data bytes.&lt;br /&gt;
	 * @throws IllegalArgumentException&lt;br /&gt;
	 *             if the input is not valid Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static byte[] decode(final String s) {&lt;br /&gt;
		return Base64Coder.decode(s.toCharArray());&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Decodes a string from Base64 format.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param s&lt;br /&gt;
	 *            a Base64 String to be decoded.&lt;br /&gt;
	 * @return A String containing the decoded data.&lt;br /&gt;
	 * @throws IllegalArgumentException&lt;br /&gt;
	 *             if the input is not valid Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static String decodeString(final String s) {&lt;br /&gt;
		return new String(Base64Coder.decode(s));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Encodes a byte array into Base64 format. No blanks or line breaks are&lt;br /&gt;
	 * inserted.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param in&lt;br /&gt;
	 *            an array containing the data bytes to be encoded.&lt;br /&gt;
	 * @return A character array with the Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static char[] encode(final byte[] in) {&lt;br /&gt;
		return Base64Coder.encode(in, 0, in.length);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Encodes a byte array into Base64 format. No blanks or line breaks are&lt;br /&gt;
	 * inserted.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param in&lt;br /&gt;
	 *            an array containing the data bytes to be encoded.&lt;br /&gt;
	 * @param offset&lt;br /&gt;
	 *            the offset into the array at which to begin reading.&lt;br /&gt;
	 * @param bits&lt;br /&gt;
	 *            number of &amp;lt;b&amp;gt;bits&amp;lt;/b&amp;gt; to process from &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt;.&lt;br /&gt;
	 * @return A character array with the Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static char[] encode(&lt;br /&gt;
		final byte[] in,&lt;br /&gt;
		final int offset,&lt;br /&gt;
		final int bits) {&lt;br /&gt;
		int length = bits / 8;&lt;br /&gt;
		if ((length * 8) &amp;lt; bits) ++length;&lt;br /&gt;
&lt;br /&gt;
		final char[] chars = new char[((length + 2) / 3) * 4];&lt;br /&gt;
		final int out = ((length * 4) + 2) / 3;&lt;br /&gt;
&lt;br /&gt;
		int mask = ~(-1 &amp;lt;&amp;lt; (8 - (bits % 8))) | ~(-1 &amp;lt;&amp;lt; (bits % 8));&lt;br /&gt;
		if (mask == 0) mask = 0xFF;&lt;br /&gt;
&lt;br /&gt;
		int o = 0;&lt;br /&gt;
		final int end = length + offset;&lt;br /&gt;
		for (int i = offset; i &amp;lt; end;) {&lt;br /&gt;
			final int b0 = ((i + 1) == end) ? in[i++] &amp;amp; mask : in[i++] &amp;amp; 0xFF;&lt;br /&gt;
			final int b1 =&lt;br /&gt;
				(i &amp;lt; length) ? (((i + 1) == end) ? in[i++] &amp;amp; mask&lt;br /&gt;
					: in[i++] &amp;amp; 0xFF) : 0;&lt;br /&gt;
			final int b2 =&lt;br /&gt;
				(i &amp;lt; length) ? (((i + 1) == end) ? in[i++] &amp;amp; mask&lt;br /&gt;
					: in[i++] &amp;amp; 0xFF) : 0;&lt;br /&gt;
&lt;br /&gt;
			final int i0 = (b0 &amp;gt;&amp;gt;&amp;gt; 2);&lt;br /&gt;
			final int i1 = (((b0 &amp;amp; 0x3) &amp;lt;&amp;lt; 4) | (b1 &amp;gt;&amp;gt;&amp;gt; 4));&lt;br /&gt;
			final int i2 = (((b1 &amp;amp; 0xF) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt;&amp;gt; 6));&lt;br /&gt;
			final int i3 = b2 &amp;amp; 0x3F;&lt;br /&gt;
&lt;br /&gt;
			chars[o++] = Base64Coder.BITS_TO_BASE64_CHAR[i0];&lt;br /&gt;
			chars[o++] = Base64Coder.BITS_TO_BASE64_CHAR[i1];&lt;br /&gt;
			chars[o] = (o &amp;lt; out) ? Base64Coder.BITS_TO_BASE64_CHAR[i2] : &#039;=&#039;;&lt;br /&gt;
			++o;&lt;br /&gt;
			chars[o] = (o &amp;lt; out) ? Base64Coder.BITS_TO_BASE64_CHAR[i3] : &#039;=&#039;;&lt;br /&gt;
			++o;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return chars;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Produces a base64 string from the provided byte-array.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param bytes&lt;br /&gt;
	 *            the byte-array to read-from.&lt;br /&gt;
	 * @return the base64 encoded string produced.&lt;br /&gt;
	 */&lt;br /&gt;
	public static String encodeString(final byte[] bytes) {&lt;br /&gt;
		return Base64Coder.encodeString(bytes, 0, bytes.length);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Produces a base64 string from the provided byte-array slice.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param bytes&lt;br /&gt;
	 *            the byte-array to read-from.&lt;br /&gt;
	 * @param offset&lt;br /&gt;
	 *            the offset into the array at which to begin reading.&lt;br /&gt;
	 * @param bits&lt;br /&gt;
	 *            number of &amp;lt;b&amp;gt;bits&amp;lt;/b&amp;gt; to process from &amp;lt;code&amp;gt;bytes&amp;lt;/code&amp;gt;.&lt;br /&gt;
	 * @return the base64 encoded string produced.&lt;br /&gt;
	 */&lt;br /&gt;
	public static String encodeString(&lt;br /&gt;
		final byte[] bytes,&lt;br /&gt;
		final int offset,&lt;br /&gt;
		final int bits) {&lt;br /&gt;
		return new String(Base64Coder.encode(bytes, offset, bits));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Encodes a string into Base64 format. No blanks or line breaks are&lt;br /&gt;
	 * inserted.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param s&lt;br /&gt;
	 *            a String to be encoded.&lt;br /&gt;
	 * @return A String with the Base64 encoded data.&lt;br /&gt;
	 */&lt;br /&gt;
	public static String encodeString(final String s) {&lt;br /&gt;
		return new String(Base64Coder.encode(s.getBytes()));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/** Dummy constructor. */&lt;br /&gt;
	private Base64Coder() { /* Blocking constructor */}&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== HexCoder ==&lt;br /&gt;
&amp;lt;java&amp;gt;package lslAESCrypto;&lt;br /&gt;
/**&lt;br /&gt;
 * The following is a simple set of static methods for converting from hex to&lt;br /&gt;
 * bytes and vice-versa&lt;br /&gt;
 * &lt;br /&gt;
 * @author Haravikk Mistral&lt;br /&gt;
 * @date Sep 15, 2008, 3:26:42 PM&lt;br /&gt;
 * @version 1.0&lt;br /&gt;
 */&lt;br /&gt;
public class HexCoder {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Quick converts bytes to hex-characters&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param bytes&lt;br /&gt;
	 *            the byte-array to convert&lt;br /&gt;
	 * @return the hex-representation&lt;br /&gt;
	 */&lt;br /&gt;
	public static String bytesToHex(final byte[] bytes) {&lt;br /&gt;
		final StringBuffer s = new StringBuffer(bytes.length * 2);&lt;br /&gt;
		for (int i = 0; i &amp;lt; bytes.length; ++i) {&lt;br /&gt;
			s.append(Character.forDigit((bytes[i] &amp;gt;&amp;gt; 4) &amp;amp; 0xF, 16));&lt;br /&gt;
			s.append(Character.forDigit(bytes[i] &amp;amp; 0xF, 16));&lt;br /&gt;
		}&lt;br /&gt;
		return s.toString();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Quickly converts hex-characters to bytes&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param s&lt;br /&gt;
	 *            the hex-string&lt;br /&gt;
	 * @return the bytes represented&lt;br /&gt;
	 */&lt;br /&gt;
	public static byte[] hexToBytes(final String s) {&lt;br /&gt;
		final byte[] bytes = new byte[s.length() / 2];&lt;br /&gt;
		for (int i = 0; i &amp;lt; bytes.length; ++i)&lt;br /&gt;
			bytes[i] = (byte) Integer.parseInt(&lt;br /&gt;
				s.substring(2 * i, (2 * i) + 2),&lt;br /&gt;
				16);&lt;br /&gt;
		return bytes;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Class =&lt;br /&gt;
&amp;lt;java&amp;gt;package lslAESCrypto;&lt;br /&gt;
&lt;br /&gt;
import java.security.InvalidAlgorithmParameterException;&lt;br /&gt;
import java.security.InvalidKeyException;&lt;br /&gt;
import java.security.NoSuchAlgorithmException;&lt;br /&gt;
import java.security.SecureRandom;&lt;br /&gt;
import java.util.Random;&lt;br /&gt;
&lt;br /&gt;
import javax.crypto.BadPaddingException;&lt;br /&gt;
import javax.crypto.Cipher;&lt;br /&gt;
import javax.crypto.IllegalBlockSizeException;&lt;br /&gt;
import javax.crypto.NoSuchPaddingException;&lt;br /&gt;
import javax.crypto.spec.IvParameterSpec;&lt;br /&gt;
import javax.crypto.spec.SecretKeySpec;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * This is a class designed to process AES messages sent from the LSL&lt;br /&gt;
 * implementation of AES which can be found here:&amp;lt;br/&amp;gt;&lt;br /&gt;
 * &amp;lt;a&lt;br /&gt;
 * href=&amp;quot;https://wiki.secondlife.com/wiki/AES_LSL_Implementation&amp;quot;&amp;gt;https://wiki&lt;br /&gt;
 * .secondlife.com/wiki/AES_LSL_Implementation&amp;lt;/a&amp;gt;&lt;br /&gt;
 * &amp;lt;/p&amp;gt;&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * This Java class will be updated to support the same modes of operation as the&lt;br /&gt;
 * LSL implementation. It currently assumes that keys and input-vectors are&lt;br /&gt;
 * processed as hex-strings, and that text is received as plain-text, while&lt;br /&gt;
 * ciphertext will be handled as base64 strings.&lt;br /&gt;
 * &amp;lt;/p&amp;gt;&lt;br /&gt;
 * &lt;br /&gt;
 * @author Haravikk&lt;br /&gt;
 * @date Sep 15, 2008, 4:18:48 PM&lt;br /&gt;
 * @version 1.0&lt;br /&gt;
 */&lt;br /&gt;
public class LSLAESCrypto {&lt;br /&gt;
	/** Our currently set block-cipher mode */&lt;br /&gt;
	protected LSLAESCryptoMode mode = LSLAESCryptoMode.CBC;&lt;br /&gt;
	/** Used to detect when a new {@link Cipher} Is needed. */&lt;br /&gt;
	protected boolean modeChanged = false;&lt;br /&gt;
&lt;br /&gt;
	/** Our currently set padding mode */&lt;br /&gt;
	protected LSLAESCryptoPad pad = LSLAESCryptoPad.NONE;&lt;br /&gt;
	/** Our currently set pad-size */&lt;br /&gt;
	protected int padSize = 512;&lt;br /&gt;
&lt;br /&gt;
	/** The currently loaded key */&lt;br /&gt;
	protected SecretKeySpec keySpec = null;&lt;br /&gt;
	/** The currently loaded input-vector */&lt;br /&gt;
	protected IvParameterSpec ivSpec = null;&lt;br /&gt;
&lt;br /&gt;
	/** The currently active cipher */&lt;br /&gt;
	protected Cipher cipher = null;&lt;br /&gt;
&lt;br /&gt;
	/** A random class for secure random operations. */&lt;br /&gt;
	protected Random random = new SecureRandom();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Creates an instance of an LSL compatible AES handler.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param mode&lt;br /&gt;
	 *            the cipher-block mode of operation&lt;br /&gt;
	 * @param pad&lt;br /&gt;
	 *            the padding scheme to use&lt;br /&gt;
	 * @param padSize&lt;br /&gt;
	 *            the block-size to use when padding. Must be a non-zero,&lt;br /&gt;
	 *            positive value that is a multiple of 128.&lt;br /&gt;
	 * @param hexKey&lt;br /&gt;
	 *            the key to start with (represented as hexadecimal string)&lt;br /&gt;
	 * @param hexIV&lt;br /&gt;
	 *            the input vector to start with (represented as hexadecimal&lt;br /&gt;
	 *            string)&lt;br /&gt;
	 * @throws NoSuchAlgorithmException&lt;br /&gt;
	 *             if the AES algorithm is not supported by the current JVM&lt;br /&gt;
	 * @throws NoSuchPaddingException&lt;br /&gt;
	 *             if the padding scheme chosen is not supported by the current&lt;br /&gt;
	 *             JVM&lt;br /&gt;
	 */&lt;br /&gt;
	public LSLAESCrypto(&lt;br /&gt;
		final LSLAESCryptoMode mode,&lt;br /&gt;
			final LSLAESCryptoPad pad,&lt;br /&gt;
			final int padSize,&lt;br /&gt;
			final String hexKey,&lt;br /&gt;
			final String hexIV)&lt;br /&gt;
		throws NoSuchAlgorithmException,&lt;br /&gt;
			NoSuchPaddingException {&lt;br /&gt;
		this.init(mode, pad, padSize, hexKey, hexIV);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Decrypts a base64 ciphertext into plain-text&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param base64ciphertext&lt;br /&gt;
	 *            the ciphertext to decrypt&lt;br /&gt;
	 * @return the plain-text that was originally encrypted&lt;br /&gt;
	 * @throws InvalidKeyException&lt;br /&gt;
	 *             if the currently loaded key is not valid&lt;br /&gt;
	 * @throws InvalidAlgorithmParameterException&lt;br /&gt;
	 *             if the AES algorithm is not supported by the current JVM&lt;br /&gt;
	 * @throws IllegalBlockSizeException&lt;br /&gt;
	 *             if the ciphertext is somehow unreadable (bad base64&lt;br /&gt;
	 *             conversion)&lt;br /&gt;
	 * @throws BadPaddingException&lt;br /&gt;
	 *             if the chosen mode of operation requires padded data&lt;br /&gt;
	 */&lt;br /&gt;
	public String decrypt(final String base64ciphertext)&lt;br /&gt;
		throws InvalidKeyException,&lt;br /&gt;
			InvalidAlgorithmParameterException,&lt;br /&gt;
			IllegalBlockSizeException,&lt;br /&gt;
			BadPaddingException {&lt;br /&gt;
		if (this.modeChanged) try {&lt;br /&gt;
			this.createCipher();&lt;br /&gt;
		} catch (final Exception e) { /* Do nothing */}&lt;br /&gt;
&lt;br /&gt;
		this.cipher.init(Cipher.DECRYPT_MODE, this.keySpec, this.ivSpec);&lt;br /&gt;
		return new String(this.cipher.doFinal(Base64Coder&lt;br /&gt;
			.decode(base64ciphertext)));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Encrypts plain-text into a base64 string&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param text&lt;br /&gt;
	 *            the plain-text to encrypt&lt;br /&gt;
	 * @return the base64 ciphertext produced&lt;br /&gt;
	 * @throws IllegalBlockSizeException&lt;br /&gt;
	 *             if the plain text is somehow invalid&lt;br /&gt;
	 * @throws BadPaddingException&lt;br /&gt;
	 *             if the chosen mode of operation requires padded data&lt;br /&gt;
	 * @throws InvalidKeyException&lt;br /&gt;
	 *             if the currently loaded key is invalid&lt;br /&gt;
	 * @throws InvalidAlgorithmParameterException&lt;br /&gt;
	 *             if the AES algorithm is not supported by the current JVM&lt;br /&gt;
	 */&lt;br /&gt;
	public String encrypt(final String text)&lt;br /&gt;
		throws IllegalBlockSizeException,&lt;br /&gt;
			BadPaddingException,&lt;br /&gt;
			InvalidKeyException,&lt;br /&gt;
			InvalidAlgorithmParameterException {&lt;br /&gt;
		if (this.modeChanged) try {&lt;br /&gt;
			this.createCipher();&lt;br /&gt;
		} catch (final Exception e) { /* Do nothing */}&lt;br /&gt;
&lt;br /&gt;
		this.cipher.init(Cipher.ENCRYPT_MODE, this.keySpec, this.ivSpec);&lt;br /&gt;
&lt;br /&gt;
		byte[] data = text.getBytes();&lt;br /&gt;
		int bits = data.length * 8;&lt;br /&gt;
&lt;br /&gt;
		/* Apply padding */&lt;br /&gt;
		LSLAESCryptoPad padding = this.pad;&lt;br /&gt;
		if (padding == LSLAESCryptoPad.NONE) {&lt;br /&gt;
			if (this.mode == LSLAESCryptoMode.CFB) { return Base64Coder&lt;br /&gt;
				.encodeString(this.cipher.doFinal(data), 0, bits); }&lt;br /&gt;
			padding = LSLAESCryptoPad.RBT;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		int blockSize = this.padSize;&lt;br /&gt;
		if (padding == LSLAESCryptoPad.RBT) blockSize = 128;&lt;br /&gt;
&lt;br /&gt;
		final int blocks = bits / blockSize;&lt;br /&gt;
		int extra = bits % blockSize;&lt;br /&gt;
&lt;br /&gt;
		if (padding == LSLAESCryptoPad.RBT) {&lt;br /&gt;
			if (extra &amp;gt; 0) {&lt;br /&gt;
				/*&lt;br /&gt;
				 * This scheme takes the last encrypted block, encrypts it&lt;br /&gt;
				 * again, and XORs it with any leftover data, maintaining&lt;br /&gt;
				 * data-length. If input is less than a block in size, then the&lt;br /&gt;
				 * current input-vector is used.&lt;br /&gt;
				 */&lt;br /&gt;
				int bytes = extra / 8;&lt;br /&gt;
				if ((bytes * 8) &amp;lt; extra) ++bytes;&lt;br /&gt;
&lt;br /&gt;
				// Grab leftover bytes&lt;br /&gt;
				final byte[] t = new byte[bytes];&lt;br /&gt;
				if (bytes &amp;gt; 0)&lt;br /&gt;
					System.arraycopy(data, data.length - bytes, t, 0, bytes);&lt;br /&gt;
&lt;br /&gt;
				// Encrypt all other data.&lt;br /&gt;
				byte[] lb;&lt;br /&gt;
				if (blocks &amp;lt; 1) {&lt;br /&gt;
					// If not enough for a block, double-encrypt IV.&lt;br /&gt;
					data = new byte[0];&lt;br /&gt;
					lb =&lt;br /&gt;
						this.cipher.doFinal(this.cipher.doFinal(this.ivSpec&lt;br /&gt;
							.getIV()));&lt;br /&gt;
				} else {&lt;br /&gt;
					// If there are blocks, then double-encrypt final one.&lt;br /&gt;
					data = this.cipher.doFinal(data, 0, data.length - bytes);&lt;br /&gt;
					lb = this.cipher.doFinal(data, data.length - 16, 16);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// XOR lb with t.&lt;br /&gt;
				for (int i = 0; i &amp;lt; t.length; ++i)&lt;br /&gt;
					t[i] ^= lb[i];&lt;br /&gt;
&lt;br /&gt;
				lb = new byte[data.length + t.length];&lt;br /&gt;
				System.arraycopy(data, 0, lb, 0, data.length);&lt;br /&gt;
				System.arraycopy(t, 0, lb, data.length, t.length);&lt;br /&gt;
&lt;br /&gt;
				return Base64Coder.encodeString(lb);&lt;br /&gt;
			}&lt;br /&gt;
			return Base64Coder.encodeString(this.cipher.doFinal(data), 0, bits);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Padding schemes that add bytes until block-boundary is reached.&lt;br /&gt;
		extra = blockSize - extra;&lt;br /&gt;
&lt;br /&gt;
		if (padding == LSLAESCryptoPad.NULLS_SAFE) {&lt;br /&gt;
			++bits;&lt;br /&gt;
			final int bytes = bits / 8;&lt;br /&gt;
			final int bit = bytes % 8;&lt;br /&gt;
&lt;br /&gt;
			if (bytes &amp;lt; data.length) data[bytes] |= (1 &amp;lt;&amp;lt; (8 - bit));&lt;br /&gt;
			else {&lt;br /&gt;
				final byte[] t = new byte[data.length + 1];&lt;br /&gt;
				System.arraycopy(data, 0, t, 0, data.length);&lt;br /&gt;
				t[data.length] = (byte) 0x80;&lt;br /&gt;
				data = t;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if ((--extra) &amp;lt; 0) extra += blockSize;&lt;br /&gt;
			padding = LSLAESCryptoPad.NULLS;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		int bytes = extra / 8;&lt;br /&gt;
		if (bytes &amp;lt;= 0) {&lt;br /&gt;
			if (padding == LSLAESCryptoPad.NULLS)&lt;br /&gt;
				return Base64Coder.encodeString(&lt;br /&gt;
					this.cipher.doFinal(data),&lt;br /&gt;
					0,&lt;br /&gt;
					bits);&lt;br /&gt;
&lt;br /&gt;
			bytes = blockSize / 8;&lt;br /&gt;
			extra += blockSize;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		bits += extra;&lt;br /&gt;
		final byte[] t = new byte[data.length + bytes];&lt;br /&gt;
		int i = data.length;&lt;br /&gt;
		System.arraycopy(data, 0, t, 0, data.length);&lt;br /&gt;
		data = t;&lt;br /&gt;
&lt;br /&gt;
		for (; i &amp;lt; data.length; ++i) {&lt;br /&gt;
			byte b = 0;&lt;br /&gt;
			if ((i &amp;gt;= (data.length - 4)) &amp;amp;&amp;amp; (padding != LSLAESCryptoPad.NULLS)) b =&lt;br /&gt;
				(byte) bytes;&lt;br /&gt;
			else if (padding == LSLAESCryptoPad.RANDOM)&lt;br /&gt;
				b = (byte) this.random.nextInt(256);&lt;br /&gt;
&lt;br /&gt;
			data[i] = b;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return Base64Coder.encodeString(this.cipher.doFinal(data), 0, bits);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Initialises this AES instance with a mode, pad, key, and input vector in&lt;br /&gt;
	 * a single operation&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param mode&lt;br /&gt;
	 *            the cipher-block mode of operation&lt;br /&gt;
	 * @param pad&lt;br /&gt;
	 *            the padding scheme to use&lt;br /&gt;
	 * @param padSize&lt;br /&gt;
	 *            the block-size to use when padding. Must be a non-zero,&lt;br /&gt;
	 *            positive value that is a multiple of 128.&lt;br /&gt;
	 * @param hexKey&lt;br /&gt;
	 *            the key to use as a hexadecimal string&lt;br /&gt;
	 * @param hexIV&lt;br /&gt;
	 *            the input-vector to use as a hexadecimal string&lt;br /&gt;
	 * @throws NoSuchAlgorithmException&lt;br /&gt;
	 *             if the AES algorithm is not supported by the current JVM&lt;br /&gt;
	 * @throws NoSuchPaddingException&lt;br /&gt;
	 *             if the padding method is not supported by the current JVM&lt;br /&gt;
	 */&lt;br /&gt;
	public void init(&lt;br /&gt;
		final LSLAESCryptoMode mode,&lt;br /&gt;
		final LSLAESCryptoPad pad,&lt;br /&gt;
		final int padSize,&lt;br /&gt;
		final String hexKey,&lt;br /&gt;
		final String hexIV)&lt;br /&gt;
		throws NoSuchAlgorithmException,&lt;br /&gt;
			NoSuchPaddingException {&lt;br /&gt;
		if ((mode == null) || (pad == null) || (hexKey == null) ||&lt;br /&gt;
			(hexIV == null))&lt;br /&gt;
			throw new IllegalArgumentException(&amp;quot;No arguments may be null&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		this.setMode(mode);&lt;br /&gt;
		this.setPad(pad, padSize);&lt;br /&gt;
		this.setKey(hexKey);&lt;br /&gt;
		this.setInputVector(hexIV);&lt;br /&gt;
&lt;br /&gt;
		this.random.nextInt();&lt;br /&gt;
&lt;br /&gt;
		this.createCipher();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets the input-vector for this engine to use&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param hexIV&lt;br /&gt;
	 *            a hexadecimal input-vector to use&lt;br /&gt;
	 */&lt;br /&gt;
	public void setInputVector(final String hexIV) {&lt;br /&gt;
		if (hexIV == null)&lt;br /&gt;
			throw new IllegalArgumentException(&amp;quot;Input-vector may not be null!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		this.ivSpec = new IvParameterSpec(HexCoder.hexToBytes(hexIV));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets the key for this engine to use&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param hexKey&lt;br /&gt;
	 *            a hexadecimal key to use&lt;br /&gt;
	 */&lt;br /&gt;
	public void setKey(final String hexKey) {&lt;br /&gt;
		if (hexKey == null)&lt;br /&gt;
			throw new IllegalArgumentException(&amp;quot;Key may not be null!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		this.keySpec = new SecretKeySpec(HexCoder.hexToBytes(hexKey), &amp;quot;AES&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets the mode of this implementation&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param mode&lt;br /&gt;
	 *            the mode to set&lt;br /&gt;
	 */&lt;br /&gt;
	public void setMode(final LSLAESCryptoMode mode) {&lt;br /&gt;
		if (mode == null)&lt;br /&gt;
			throw new IllegalArgumentException(&amp;quot;Mode may not be null!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		this.mode = mode;&lt;br /&gt;
		this.modeChanged = true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets the padding scheme of this implementation&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param pad&lt;br /&gt;
	 *            the padding scheme to use&lt;br /&gt;
	 */&lt;br /&gt;
	public void setPad(final LSLAESCryptoPad pad) {&lt;br /&gt;
		this.setPad(pad, this.padSize);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets the padding scheme of this implementation&lt;br /&gt;
	 * &lt;br /&gt;
	 * @param pad&lt;br /&gt;
	 *            the padding scheme to use&lt;br /&gt;
	 * @param padSize&lt;br /&gt;
	 *            the block-size to use when padding. Must be a non-zero,&lt;br /&gt;
	 *            positive value that is a multiple of 128.&lt;br /&gt;
	 */&lt;br /&gt;
	public void setPad(final LSLAESCryptoPad pad, final int padSize) {&lt;br /&gt;
		if (pad == null)&lt;br /&gt;
			throw new IllegalArgumentException(&amp;quot;Pad may not be null!&amp;quot;);&lt;br /&gt;
		if ((padSize &amp;lt;= 0) || ((padSize % 128) &amp;gt; 0))&lt;br /&gt;
			throw new IllegalArgumentException(&lt;br /&gt;
				&amp;quot;Pad size may not be less than zero, and must be a multiple of 128&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		this.pad = pad;&lt;br /&gt;
		this.padSize = padSize;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Creates a new cipher instance for processing&lt;br /&gt;
	 * &lt;br /&gt;
	 * @throws NoSuchPaddingException&lt;br /&gt;
	 *             if the padding scheme set is invalid&lt;br /&gt;
	 * @throws NoSuchAlgorithmException&lt;br /&gt;
	 *             if AES is not supported by this JVM&lt;br /&gt;
	 */&lt;br /&gt;
	protected void createCipher()&lt;br /&gt;
		throws NoSuchAlgorithmException,&lt;br /&gt;
			NoSuchPaddingException {&lt;br /&gt;
		this.cipher = Cipher.getInstance(&amp;quot;AES/&amp;quot; + this.mode + &amp;quot;/NoPadding&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/** Defines modes of operation combatible with LSL */&lt;br /&gt;
	public enum LSLAESCryptoMode {&lt;br /&gt;
		/** Cipher-Block-Chaining mode */&lt;br /&gt;
		CBC,&lt;br /&gt;
		/** Cipher FeedBack mode */&lt;br /&gt;
		CFB;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/** Defines padding schemes compatible with LSL */&lt;br /&gt;
	public enum LSLAESCryptoPad {&lt;br /&gt;
		/** Performs no padding, will switch to RBT if mode is CBC. */&lt;br /&gt;
		NONE,&lt;br /&gt;
		/**&lt;br /&gt;
		 * Enables CFB mode temporarily for the final complete block, and&lt;br /&gt;
		 * combines with data. This preserves data-length.&lt;br /&gt;
		 */&lt;br /&gt;
		RBT,&lt;br /&gt;
		/**&lt;br /&gt;
		 * Adds null-bytes to the end of the data until it is of correct-size.&lt;br /&gt;
		 * This is an padding scheme (may result in loss of null-bytes from&lt;br /&gt;
		 * original data).&lt;br /&gt;
		 */&lt;br /&gt;
		NULLS,&lt;br /&gt;
		/**&lt;br /&gt;
		 * Same as NULLS, except that it first appends a single &#039;1&#039; bit to the&lt;br /&gt;
		 * data before padding.&lt;br /&gt;
		 */&lt;br /&gt;
		NULLS_SAFE,&lt;br /&gt;
		/**&lt;br /&gt;
		 * Appends null-bytes to the data until one word from block-size, final&lt;br /&gt;
		 * word is then populated with bytes describing the number of padding&lt;br /&gt;
		 * bytes added.&lt;br /&gt;
		 */&lt;br /&gt;
		ZEROES,&lt;br /&gt;
		/**&lt;br /&gt;
		 * Same as ZEROES, except that random-bytes are used in place of&lt;br /&gt;
		 * null-bytes.&lt;br /&gt;
		 */&lt;br /&gt;
		RANDOM;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
== Encryption ==&lt;br /&gt;
&amp;lt;java&amp;gt;import lslAESCrypto.LSLAESCrypto;&lt;br /&gt;
import lslAESCrypto.LSLAESCrypto.LSLAESCryptoMode;&lt;br /&gt;
import lslAESCrypto.LSLAESCrypto.LSLAESCryptoPad;&lt;br /&gt;
&lt;br /&gt;
/** */&lt;br /&gt;
public class ExampleEncrypt {&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 * @throws Exception&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(final String[] args) throws Exception {&lt;br /&gt;
		final String myKey = &amp;quot;1234567890ABCDEF0123456789ABCDEF&amp;quot;;&lt;br /&gt;
		final String myIV = &amp;quot;89ABCDEF0123456789ABCDEF01234567&amp;quot;;&lt;br /&gt;
		final String myMsg = &amp;quot;Hello world! I am a lovely message waiting to be encrypted!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		final LSLAESCrypto aes = new LSLAESCrypto(&lt;br /&gt;
			LSLAESCryptoMode.CFB,&lt;br /&gt;
			LSLAESCryptoPad.NoPadding,&lt;br /&gt;
			myKey,&lt;br /&gt;
			myIV);&lt;br /&gt;
		System.out.println(aes.encrypt(myMsg));&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Decryption ==&lt;br /&gt;
&amp;lt;java&amp;gt;import lslAESCrypto.LSLAESCrypto;&lt;br /&gt;
import lslAESCrypto.LSLAESCrypto.LSLAESCryptoMode;&lt;br /&gt;
import lslAESCrypto.LSLAESCrypto.LSLAESCryptoPad;&lt;br /&gt;
&lt;br /&gt;
/** */&lt;br /&gt;
public class ExampleDecrypt {&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param args&lt;br /&gt;
	 * @throws Exception&lt;br /&gt;
	 */&lt;br /&gt;
	public static void main(final String[] args) throws Exception {&lt;br /&gt;
		final String myKey = &amp;quot;1234567890ABCDEF0123456789ABCDEF&amp;quot;;&lt;br /&gt;
		final String myIV = &amp;quot;89ABCDEF0123456789ABCDEF01234567&amp;quot;;&lt;br /&gt;
		final String myMsg = &amp;quot;Mdn6jGTwRPMOKTYTTdDKGm9KScz26LIz96KVOGAeMw3hpwByPfa07PDRHxRW4TIh5dmu5LlhKpTQChi=&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		final LSLAESCrypto aes = new LSLAESCrypto(&lt;br /&gt;
			LSLAESCryptoMode.CFB,&lt;br /&gt;
			LSLAESCryptoPad.NoPadding,&lt;br /&gt;
			myKey,&lt;br /&gt;
			myIV);&lt;br /&gt;
		System.out.println(aes.decrypt(myMsg));&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/java&amp;gt;&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=PyOGP_Client_Library&amp;diff=848003</id>
		<title>PyOGP Client Library</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=PyOGP_Client_Library&amp;diff=848003"/>
		<updated>2010-04-10T01:40:25Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{PyOGP/navigation}}&lt;br /&gt;
== Intro ==&lt;br /&gt;
&lt;br /&gt;
PyOGP is a young, open source, python client library which provides an interface to an agent (client) of a Second Life grid. The code aims to enable automated testing of Second Life grids, to encourage and enable exploration into the client/server relationship and related protocols of Second Life, and to make possible simple prototyping of various client applications.&lt;br /&gt;
&lt;br /&gt;
Hosted on svn.secondlife.com, it does require a contributor&#039;s agreement for commit access, and currently has a few contributors from the Second Life open source community.&lt;br /&gt;
&lt;br /&gt;
P.S. We&#039;ll likely be moving to hg relatively soon...&lt;br /&gt;
&lt;br /&gt;
* mailing list: pyogp@lists.secondlife.com&lt;br /&gt;
* irc: irc://irc.freenode.com/#pyogp&lt;br /&gt;
* wiki: http://wiki.secondlife.com/wiki/Pyogp&lt;br /&gt;
* licensing: Apache 2.0 license, copyright Linden Lab&lt;br /&gt;
&lt;br /&gt;
=== Goals ===&lt;br /&gt;
&lt;br /&gt;
In the very near future, we can have tests available to be run as soon as a deploy is completed that exercise a simulator/grid in the same way we do a smoke test. We will use these as automated tests run at build time, post deploy validation, and regression testing of simulators and backend systems.&lt;br /&gt;
&lt;br /&gt;
This provides early feedback on code quality. QA is then able to dive deeper in testing the changes specific to a branch. &lt;br /&gt;
&lt;br /&gt;
Having this library available also allows us to test potential changes before we have finalized design and are ready to submit to QA. Not sure how something will play out? Try it, and test it with PyOGP....&lt;br /&gt;
&lt;br /&gt;
=== A Brief History ===&lt;br /&gt;
&lt;br /&gt;
PyOGP was originally created as a tool for testing [[OGP]] related changes to the Second Life grid. By the end of the summer in 2008, the &#039;&#039;&#039;pyogp.lib.base&#039;&#039;&#039; package provided a skeleton messaging system and was able to test Linden Lab&#039;s first implementation of an agent domain and the related changes in an agent&#039;s region handoff and teleport. As the development effort around OGP waned, we started to extend pyogp by adding higher level client related functionality. Recently, this functionality was split out into a separate python package (&#039;&#039;&#039;pyogp.lib.client&#039;&#039;&#039;), and sample scripts (and future apps) were moved into &#039;&#039;&#039;pyogp.apps&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Architecture Overview==&lt;br /&gt;
&lt;br /&gt;
=== Structure ===&lt;br /&gt;
&lt;br /&gt;
PyOGP is comprised of three python packages. The library consists of pyogp.lib.base and pyogp.lib.client, while sample scripts, and in time applications, live in pyogp.apps. &lt;br /&gt;
:&#039;&#039;&#039;pyogp.lib.base&#039;&#039;&#039; - consists of basic networking, messaging systems (UDP and event queue) and capabilities, custom datatypes, and a low level message related event system&lt;br /&gt;
:&#039;&#039;&#039;pyogp.lib.client&#039;&#039;&#039; - consists of &#039;convenience&#039; classes mapping methods and handlers to specific messages (e.g. Agent().say(msg) tells the client to send the ChatFromViewer message to the host region). Raises application oriented events based on processing of messages (these are currently sparsely implemented)&lt;br /&gt;
:&#039;&#039;&#039;pyogp.apps&#039;&#039;&#039; - sample scripts and works in progress, the scripts here generally illustrate simple usage of classes as related to in world interactions by an agent of a Second Life grid&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
&lt;br /&gt;
==== Platform / Python version compatibility ====&lt;br /&gt;
&lt;br /&gt;
PyOGP aims to be compatible across platforms, though there are known problems with various environments. We&#039;ll be focusing on ensuring better compatibility soon.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Known good configurations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Windows XP + Python 2.5&lt;br /&gt;
:Mac + Python 2.5, 2.6&lt;br /&gt;
:Linux + Python 2.4, 2.5, 2.6 (Linden hosts fall into this group) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Known bad configurations&#039;&#039;&#039;&lt;br /&gt;
:Windows Vista + Python 2.6&lt;br /&gt;
:Windows 7 + Python 2.6&lt;br /&gt;
&lt;br /&gt;
There have been challenges in ensuring compatibility between the various dependencies, largely due to greenlet, eventlet, and pyopenssl. Please report bugs on [http://jira.secondlife.com/browse/PYO pJira]&lt;br /&gt;
&lt;br /&gt;
==== Python module dependencies ====&lt;br /&gt;
&lt;br /&gt;
The packages that make up PyOGP have some dependencies on python modules not included in a standard install, or sometimes not available on an older Python distribution.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pyogp.lib.base dependencies:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;  #from setup.py&lt;br /&gt;
  &lt;br /&gt;
     install_requires=[&lt;br /&gt;
         &#039;setuptools&#039;,&lt;br /&gt;
         # -*- Extra requirements: -*-&lt;br /&gt;
         &#039;uuid&#039;,&lt;br /&gt;
         &#039;elementtree&#039;,&lt;br /&gt;
         &#039;llbase&#039;,&lt;br /&gt;
         &#039;WebOb&#039;,&lt;br /&gt;
         &#039;wsgiref&#039;,&lt;br /&gt;
         &#039;eventlet==0.8.14&#039;&lt;br /&gt;
         ]&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pyogp.lib.client dependencies:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;     install_requires=[&lt;br /&gt;
         &#039;setuptools&#039;,&lt;br /&gt;
         # -*- Extra requirements: -*-&lt;br /&gt;
         &#039;pyogp.lib.base&#039;&lt;br /&gt;
         ] &amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pyogp.apps dependencies:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;     install_requires=[&lt;br /&gt;
         &#039;setuptools&#039;,&lt;br /&gt;
         &#039;pyogp.lib.client&#039;&lt;br /&gt;
         ]&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to install ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Lindens can see internal documentation for more specific guidance. https://wiki.lindenlab.com/wiki/Pyogp#How_to_Install&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Standalone dev environment using buildout ====&lt;br /&gt;
&lt;br /&gt;
Buildout is a type of Python development environment, organizing and configuring various components and their dependencies. On a desktop, one may checkout such an environment for working with PyOGP. One may optionally use a virtualenv Python environment to isolate the development code and it&#039;s runtime environment on one&#039;s host.&lt;br /&gt;
&lt;br /&gt;
Dependencies: buildout takes care of everything, grabbing needed modules etc.&lt;br /&gt;
&lt;br /&gt;
Wiki instructions: https://wiki.secondlife.com/wiki/Pyogp/Client_Lib/The_Development_Sandbox&lt;br /&gt;
&lt;br /&gt;
==== Installing the PyOGP packages ====&lt;br /&gt;
&lt;br /&gt;
Each of the PyOGP package may be installed to one&#039;s Python install or to a [http://pypi.python.org/pypi/virtualenv virtualenv]. &#039;&#039;&#039;Buyer beware&#039;&#039;&#039; if installing into your system&#039;s install: you&#039;ll want to be able to uninstall manually, as we haven&#039;t hooked up the uninstall. PyOGP is still coming up to speed with respect to distutils and pypi and the like, but it&#039;s relatively close now.&lt;br /&gt;
&lt;br /&gt;
To install a package, simply run &#039;python setup.py install&#039; in a package&#039;s root.&lt;br /&gt;
&lt;br /&gt;
==== Referencing PyOGP packages via the PATH ====&lt;br /&gt;
&lt;br /&gt;
Source code can be referenced directly if one simply ensures that a package, and it&#039;s dependencies, are available in the PYTHONPATH environmental variable.&lt;br /&gt;
&lt;br /&gt;
== Current functional coverage ==&lt;br /&gt;
&lt;br /&gt;
Anything not listed as covered is probably not yet covered.&lt;br /&gt;
&lt;br /&gt;
pyogp.lib.base:&lt;br /&gt;
:* base udp messaging system (message.*)&lt;br /&gt;
:** UDP serialization/deserialization&lt;br /&gt;
:** message_template.msg parsing &lt;br /&gt;
:* base event queue messaging system (event_queue.EventQueueClient())&lt;br /&gt;
:* capabilities and their methods. Seed capabilities are a special case. (caps.Capability())&lt;br /&gt;
:* Message-based events (message.message_handler)&lt;br /&gt;
&lt;br /&gt;
pyogp.lib.client:&lt;br /&gt;
:* agents (agent.Agent())&lt;br /&gt;
:** L$ balance request, friending, and walk/fly/sit/stand actions...&lt;br /&gt;
:* OGP agentdomain (agentdomain.AgentDomain())&lt;br /&gt;
:* application level events (event_system.AppEventsHandler())&lt;br /&gt;
:* some object handling (objects.*)&lt;br /&gt;
:** edit name, description, next-owner permissions and more&lt;br /&gt;
:** object creation is possible&lt;br /&gt;
:* some inventory handling (inventory.*)&lt;br /&gt;
:** login inv skeletons&lt;br /&gt;
:** fetching inventory, including AIS (caps based Agent Inventory Services))&lt;br /&gt;
:** some creating of new inventory items (LSL scripts, notecards)&lt;br /&gt;
:* regions (region.Region())&lt;br /&gt;
:** host and neighboring regions are handled slightly differently&lt;br /&gt;
:** udp and event queue connections are optionally enabled for each case&lt;br /&gt;
:** currently only pulling caps available to the agent via the seed cap (plus using the inventory related caps in the AIS context)&lt;br /&gt;
:* some appearance handling (appearance.AppearanceManager), &lt;br /&gt;
:* parcels&lt;br /&gt;
:* chat&lt;br /&gt;
:* some ImprovedInstantMessage handling&lt;br /&gt;
:** raises events on received instant messages&lt;br /&gt;
:** can deal with inventory offers/accepts/declines&lt;br /&gt;
:** other cases in this message are currently only logged&lt;br /&gt;
:* groups&lt;br /&gt;
:* group chat&lt;br /&gt;
:* LSL script uploading&lt;br /&gt;
&lt;br /&gt;
=== Sample Scripts ===&lt;br /&gt;
&lt;br /&gt;
There are a variety of scripted examples that have been used to exercise and test functionality as it is added to the library. These persist as coded documentation.&lt;br /&gt;
&lt;br /&gt;
The source code is available in https://svn.secondlife.com/svn/linden/projects/2008/pyogp/pyogp.apps/trunk/pyogp/apps/examples/.&lt;br /&gt;
&lt;br /&gt;
The following refers to a buildout context. If one installs pyogp.apps vi setup.py, these scripts will exist in the python environment&#039;s bin/ directory. In the buildout context, these scripts are available in {buildout root}/bin.&lt;br /&gt;
&lt;br /&gt;
The scripts are derived from a package&#039;s &#039;setup.py&#039; via the entry_points parameter, and essentially build executable Python scripts configured to run in the correct environment with the proper dependencies added the the path used by the script. These scripts are currently just simple illustrations of some uses of the PyOGP codebase.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;  #the current entry_points in setup.py og pyogp.apps:&lt;br /&gt;
  &lt;br /&gt;
     entry_points={&lt;br /&gt;
         &#039;console_scripts&#039;: [&lt;br /&gt;
             &#039;AIS_inventory_handling = pyogp.apps.examples.AIS_inventory_handling:main&#039;,&lt;br /&gt;
             &#039;agent_login = pyogp.apps.examples.agent_login:main&#039;,&lt;br /&gt;
             &#039;agent_manager = pyogp.apps.examples.agent_manager:main&#039;,&lt;br /&gt;
             &#039;appearance_management = pyogp.apps.examples.appearance_management:main&#039;,&lt;br /&gt;
             &#039;chat_and_instant_messaging = pyogp.apps.examples.chat_and_instant_messaging:main&#039;,&lt;br /&gt;
             &#039;group_chat = pyogp.apps.examples.group_chat:main&#039;,&lt;br /&gt;
             &#039;group_creation = pyogp.apps.examples.group_creation:main&#039;,&lt;br /&gt;
             &#039;inventory_handling = pyogp.apps.examples.inventory_handling:main&#039;,&lt;br /&gt;
             &#039;inventory_transfer = pyogp.apps.examples.inventory_transfer:main&#039;,&lt;br /&gt;
             &#039;inventory_transfer_specify_agent = pyogp.apps.examples.inventory_transfer_specify_agent:main&#039;,&lt;br /&gt;
             &#039;login = pyogp.apps.examples.login:main&#039;,&lt;br /&gt;
             &#039;multi_region_connect = pyogp.apps.examples.multi_region_connect:main&#039;,&lt;br /&gt;
             &#039;object_create_edit = pyogp.apps.examples.object_create_edit:main&#039;,&lt;br /&gt;
             &#039;object_create_permissions = pyogp.apps.examples.object_create_permissions:main&#039;,&lt;br /&gt;
             &#039;object_create_rez_script = pyogp.apps.examples.object_create_rez_script:main&#039;,&lt;br /&gt;
             &#039;object_creation = pyogp.apps.examples.object_creation:main&#039;,&lt;br /&gt;
             &#039;object_properties = pyogp.apps.examples.object_properties:main&#039;,&lt;br /&gt;
             &#039;object_tracking = pyogp.apps.examples.object_tracking:main&#039;,&lt;br /&gt;
             &#039;parcel_management = pyogp.apps.examples.parcel_management:main&#039;,&lt;br /&gt;
             &#039;parse_packets = pyogp.apps.examples.parse_packets:main&#039;,&lt;br /&gt;
             &#039;region_connect = pyogp.apps.examples.region_connect:main&#039;,&lt;br /&gt;
             &#039;smoke_test = pyogp.apps.examples.smoke_test:main&#039;,&lt;br /&gt;
             &#039;chat = pyogp.apps.examples.chat_interface:main&#039;,&lt;br /&gt;
             ]&lt;br /&gt;
        }&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How it Works (High Level) ==&lt;br /&gt;
&lt;br /&gt;
=== Eventlet ===&lt;br /&gt;
&lt;br /&gt;
PyOGP use [[Eventlet]] to run coroutines to handle multiple &#039;concurrent&#039; processes, rather than threads or multiple processes. Each client agent instance will spawn a handful of coroutines to handles e.g. the UDP pipe, the Event Queue, various monitors, while yielding time to the parent process which should ensure it yields to the other routines as well.&lt;br /&gt;
&lt;br /&gt;
PyOGP uses eventlet in very elementary ways at this point, but will perhaps start to use blocking queues in some cases, so that the coroutine only is allocated processing time if there is work for it to do.&lt;br /&gt;
&lt;br /&gt;
=== pyogp.lib.base ===&lt;br /&gt;
&lt;br /&gt;
This package handles the protocols used when communicating with a Second Life grid. A high level perspective on the package reveals a MessageManager() (still in development) which provides an interface to the UDP and Event Queue connections, as well as basic networking with enables login and capabilities interactions. The base package also has a low level even system through which all messages are passed and sent to subscribers.&lt;br /&gt;
&lt;br /&gt;
Any subcomponent is available for direct interaction at any time, the MessageManager() and the MessageHandler() are the simple access points.&lt;br /&gt;
&lt;br /&gt;
==== Events &amp;amp; Callbacks ====&lt;br /&gt;
&lt;br /&gt;
The event implementation in pyogp follows the observer pattern, where observers subscribe to and are notified when an event occurs. Data is passed throughout the client instance via events. &lt;br /&gt;
&lt;br /&gt;
* MessageManager - is an attribute of a Region and every packet received/sent is filtered through here. subscriptions are by message name&lt;br /&gt;
** MessageHandler - is an attribute of MessageManager, and every categorized message received from the event queue or udp dispatcher is filtered through here. (message as defined in message_template.msg, or one of [&#039;ChatterBoxInvitation&#039;, &#039;ChatterBoxSessionEventReply&#039;, &#039;ChatterBoxSessionAgentListUpdates&#039;, &#039;ChatterBoxSessionStartReply&#039;, &#039;EstablishAgentCommunication&#039;]. There may be unhandled messages, I just haven&#039;t seen em yet :))&lt;br /&gt;
&lt;br /&gt;
===== Message Events =====&lt;br /&gt;
&lt;br /&gt;
In the most fundamental implementation of event usage, all packets are passed through a MessageManager() instance for evaluation. Observers may register to receive udp packets serialized into the form of Message() instances. The MessageHandler() is a consolidation point for subscribing to messages keyed by message name, and created on demand via subscription.&lt;br /&gt;
&lt;br /&gt;
See pyogp.lib.base.message.message_handler.MessageHandler() for more details.&lt;br /&gt;
&lt;br /&gt;
The pyogp agent&#039;s Region() instances each monitor their stream of packets (e.g. the host region: agent.region.message_manager.message_handler). (Perhaps this should be changed to a generalized Network() class where all packets (coupled to their originating regions) are evaluated.&lt;br /&gt;
&lt;br /&gt;
Event firing passes data on to a callback handler defined in the subscription, in the form of (handler, *args, **kwargs).&lt;br /&gt;
&lt;br /&gt;
The Agent class monitors the ImprovedInstantMessage packet:&lt;br /&gt;
&amp;lt;python&amp;gt;        onImprovedInstantMessage_received = self.region.message_handler.register(&#039;ImprovedInstantMessage&#039;)&lt;br /&gt;
        onImprovedInstantMessage_received.subscribe(self.onImprovedInstantMessage)&lt;br /&gt;
&lt;br /&gt;
    def onImprovedInstantMessage(self, packet):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; handles the many cases of data being passed in this message &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {code} # parse and handle the data...&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The messaging system then fires the event when an ImprovedInstantMessage message is received, which calls onImprovedInstantMessage method above to handle the message contents. Multiple subscribers may be listening for any message related event, and each would be notified of the same Message() instance.&lt;br /&gt;
&lt;br /&gt;
Unsubscribing from an event:&lt;br /&gt;
&amp;lt;python&amp;gt;        onImprovedInstantMessage_received.unsubscribe(self.onImprovedInstantMessage)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are various event and callback implementations viewable in pyogp, poke around and help consolidate things if you like.&lt;br /&gt;
&lt;br /&gt;
=== pyogp.lib.client ===&lt;br /&gt;
&lt;br /&gt;
The client package generally provides a convenient interface to initiate or interpret interactions with host region (or neighboring regions). By listening to the messaging related event system in pyogp.lib.base, the client package interprets the messages that come in off the wire, and executes business logic in building responses. pyogp.lib.client also provides simple methods to enable the ending of messages to a grid.&lt;br /&gt;
&lt;br /&gt;
==== Events ====&lt;br /&gt;
&lt;br /&gt;
* EventsHandler - an attribute of an Agent, also able to be passed in, that is intended as the primary interface of a pyogp application into the internal state and data events within the lib. This system uses the same base classes as used by the MessageHandler() in the base package, and the descriptions about events and callbacks above apply here as well. The api for subscribing to these events is similar to the MessageHandler(), with an additional timeout parameter passed in the _register() method. When the specified timeout expires, the subscription returns None and expires the subscription.&lt;br /&gt;
&lt;br /&gt;
==== Agent Login (examples) ====&lt;br /&gt;
&lt;br /&gt;
===== Single Agent Login &amp;amp; Chat=====&lt;br /&gt;
&lt;br /&gt;
Spawn a client in a co-routine, allowing persistent presence until forcefully terminated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;from eventlet import api&lt;br /&gt;
&lt;br /&gt;
from pyogp.lib.client.agent import Agent&lt;br /&gt;
from pyogp.lib.client.settings import Settings&lt;br /&gt;
&lt;br /&gt;
settings = Settings()&lt;br /&gt;
&lt;br /&gt;
settings.ENABLE_INVENTORY_MANAGEMENT = True&lt;br /&gt;
settings.MULTIPLE_SIM_CONNECTIONS = False&lt;br /&gt;
&lt;br /&gt;
client = Agent(settings = settings)&lt;br /&gt;
&lt;br /&gt;
api.spawn(client.login, options.loginuri, &#039;first&#039;, &#039;last&#039;, &#039;password&#039;, start_location = options.region)&lt;br /&gt;
&lt;br /&gt;
# wait for the agent to connect to it&#039;s region&lt;br /&gt;
while client.connected == False:&lt;br /&gt;
    api.sleep(0)&lt;br /&gt;
&lt;br /&gt;
while client.region.connected == False:&lt;br /&gt;
    api.sleep(0)&lt;br /&gt;
&lt;br /&gt;
client.say(&amp;quot;Hello World!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# once connected, live until someone kills me&lt;br /&gt;
while client.running:&lt;br /&gt;
    api.sleep(0)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Multiple Agent Login =====&lt;br /&gt;
&lt;br /&gt;
Each agent instance in logged in in a separate coroutine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;from pyogp.lib.client.agent import Agent&lt;br /&gt;
from pyogp.lib.client.agentmanager import AgentManager&lt;br /&gt;
&lt;br /&gt;
credentials= [(&#039;agent1&#039;, &#039;lastname&#039;, &#039;password&#039;), (&#039;agent2&#039;, &#039;lastname&#039;, &#039;password&#039;)]&lt;br /&gt;
&lt;br /&gt;
# prime the Agent instances&lt;br /&gt;
agents = [Agent(settings, firstname, lastname, password)&lt;br /&gt;
          for firstname, lastname, password in credentials]&lt;br /&gt;
&lt;br /&gt;
agentmanager = AgentManager()&lt;br /&gt;
agentmanager.initialize(agents)&lt;br /&gt;
&lt;br /&gt;
# log them in&lt;br /&gt;
for key in agentmanager.agents:&lt;br /&gt;
    agentmanager.login(key, options.loginuri, options.region)&lt;br /&gt;
&lt;br /&gt;
# while they are connected, stay alive&lt;br /&gt;
while agentmanager.has_agents_running():&lt;br /&gt;
    api.sleep(0)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Extending Functionality ==&lt;br /&gt;
&lt;br /&gt;
While the implementations and structures in pyogp.lib.base can (and are in the process of) being refactored to improve performance or usability, it is a fairly complete package. &lt;br /&gt;
&lt;br /&gt;
The functional coverage PyOGP provides on the other hand is not complete, and there are a variety of needs to complete the implementation in pyogp.lib.base. We need to improve coverage of message handling (dealing with messages sent to the client), add more wrappers for sending various messages and performing multistep tasks (to simplify the initiation of interactions with the region), and we need to raise more application level events in the client package so that applications have easy access to incoming data. &lt;br /&gt;
&lt;br /&gt;
=== Sending Messages ===&lt;br /&gt;
&lt;br /&gt;
PyOGP, like the Viewer, communicates with the Second Life simulator by sending messages over UDP. &lt;br /&gt;
&lt;br /&gt;
In order to extend PyOGP, you&#039;ll build a representation of a new UDP message, and send it through the pyogp.lib.base modules for serialization and wire handling.&lt;br /&gt;
&lt;br /&gt;
=== Example: Sending an IM ===&lt;br /&gt;
&lt;br /&gt;
To send an IM to the simulator, send an ImprovedInstantMessage packet.  The base class for message packets is defined in &amp;lt;code&amp;gt;base/message/message.py&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Packets are assembled using a Message() instance which has the message name and Block() instances passed in through its constructor.  Similarly, Blocks are assembled by passing in the Block name and the value name and values for each of the Block values. (The ability to build Message() instances via an llsd payload is expected to be introduced soon.)&lt;br /&gt;
&lt;br /&gt;
Note: It is important that the message name, block name, and value names and types should match what is specified in the message template. (It is also possible to manipulate the representation of the stored template, or to use a custom message template.)&lt;br /&gt;
 &lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;python&amp;gt;    def send_ImprovedInstantMessage(self, AgentID = None, SessionID = None, &lt;br /&gt;
                                FromGroup = None, ToAgentID = None, &lt;br /&gt;
                                ParentEstateID = None, RegionID = None, &lt;br /&gt;
                                Position = None, Offline = None, &lt;br /&gt;
                                Dialog = None, _ID = None, Timestamp = None, &lt;br /&gt;
                                FromAgentName = None, _Message = None, &lt;br /&gt;
                                BinaryBucket = None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
        sends an instant message packet to ToAgentID. this is a &lt;br /&gt;
        multi-purpose message for inventory offer handling, im, group chat, &lt;br /&gt;
        and more &lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        packet = Message(&#039;ImprovedInstantMessage&#039;, &lt;br /&gt;
                         Block(&#039;AgentData&#039;, &lt;br /&gt;
                               AgentID = AgentID, &lt;br /&gt;
                               SessionID = SessionID), &lt;br /&gt;
                         Block(&#039;MessageBlock&#039;, &lt;br /&gt;
                               FromGroup = FromGroup, &lt;br /&gt;
                               ToAgentID = ToAgentID, &lt;br /&gt;
                               ParentEstateID = ParentEstateID, &lt;br /&gt;
                               RegionID = RegionID, &lt;br /&gt;
                               Position = Position, &lt;br /&gt;
                               Offline = Offline, &lt;br /&gt;
                               Dialog = Dialog, &lt;br /&gt;
                               ID = UUID(str(_ID)), &lt;br /&gt;
                               Timestamp = Timestamp, &lt;br /&gt;
                               FromAgentName = FromAgentName, &lt;br /&gt;
                               Message = _Message, &lt;br /&gt;
                               BinaryBucket = BinaryBucket))&lt;br /&gt;
&lt;br /&gt;
        # Send the message:&lt;br /&gt;
        self.region.enqueue_message(packet, True)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Handling Incoming Messages and Raising an Event ===&lt;br /&gt;
&lt;br /&gt;
To listen for when messages of a particular type are sent to the client instance, subscribe to the MessageHandler() on the host region&#039;s MessageManager(), like the example that follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;        onImprovedInstantMessage_received = self.region.message_handler.register(&#039;ImprovedInstantMessage&#039;)&lt;br /&gt;
        onImprovedInstantMessage_received.subscribe(self.onImprovedInstantMessage)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the event is fired upon receipt of the message matching the name, the specified callback handles the data passed along, and in this case raises an event notifying observers of the &#039;InstantMessageReceived&#039; event in pyogp.lib.client of the important data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;    def onImprovedInstantMessage(self, packet):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; callback handler for received ImprovedInstantMessage messages. much is passed in this message, and handling the data is only partially implemented &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        Dialog = packet.blocks[&#039;MessageBlock&#039;][0].get_variable(&#039;Dialog&#039;).data&lt;br /&gt;
        FromAgentID = packet.blocks[&#039;AgentData&#039;][0].get_variable(&#039;AgentID&#039;).data&lt;br /&gt;
&lt;br /&gt;
        if Dialog == ImprovedIMDialogue.InventoryOffered:&lt;br /&gt;
&lt;br /&gt;
            self.inventory.handle_inventory_offer(packet)&lt;br /&gt;
&lt;br /&gt;
        # ...&lt;br /&gt;
        # some of the Dialogue types this message can contain are handled, we are showing 2&lt;br /&gt;
        # ...&lt;br /&gt;
&lt;br /&gt;
        elif Dialog == ImprovedIMDialogue.FromAgent:&lt;br /&gt;
&lt;br /&gt;
            # ... code parses the data from the Message() instance ...&lt;br /&gt;
&lt;br /&gt;
            message = AppEvent(&#039;InstantMessageReceived&#039;, FromAgentID = FromAgentID, RegionID = RegionID, Position = Position, ID = ID, FromAgentName = FromAgentName, Message = _Message)&lt;br /&gt;
&lt;br /&gt;
            logger.info(&amp;quot;Received instant message from %s: %s&amp;quot; % (FromAgentName, _Message))&lt;br /&gt;
&lt;br /&gt;
            self.events_handler.handle(message)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
Uses python&#039;s standard logging module (http://docs.python.org/library/logging.html). The library defines logging events throughout, it is up to the application/script to determine the output.&lt;br /&gt;
&lt;br /&gt;
Hooking logging into a new module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;from logging import getLogger&lt;br /&gt;
&lt;br /&gt;
# initialize logging&lt;br /&gt;
logger = getLogger(&#039;pyogp.lib.client.agent&#039;)&lt;br /&gt;
&lt;br /&gt;
class Agent(object):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; our agent class &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, params):&lt;br /&gt;
&lt;br /&gt;
        self.params = params&lt;br /&gt;
&lt;br /&gt;
        logger.debug(&amp;quot;Initializing agent with params: %s&amp;quot; % (params))&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An application can then set up the logging output as follows (or any other way it pleases):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;console = logging.StreamHandler()&lt;br /&gt;
formatter = logging.Formatter(&#039;%(asctime)-30s%(name)-30s: %(levelname)-8s %(message)s&#039;)&lt;br /&gt;
console.setFormatter(formatter)&lt;br /&gt;
logging.getLogger(&#039;&#039;).addHandler(console)&lt;br /&gt;
logging.getLogger(&#039;&#039;).setLevel(logging.DEBUG)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output to console is then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bash&amp;gt;2009-04-21 22:08:58,681       pyogp.lib.base.agent          : DEBUG    agent with params: params&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pyogp Unit Tests ==&lt;br /&gt;
&lt;br /&gt;
See [[PyOGP_Package_Unittests]].&lt;br /&gt;
&lt;br /&gt;
== Sphinx (api docs) ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Api documentation is now available for PyOGP packages&#039;&#039;&#039; (well, not for apps yet, but someday....)!&lt;br /&gt;
 &lt;br /&gt;
In pyogp/docs in each of the pyogp.lib.base and pyogp.lib.client packages, one will find source, last revision, and build files for sphinx based documents. Output is available at {package root}/docs/html/index.html.&lt;br /&gt;
&lt;br /&gt;
We plan on sharing the api documentation on the web soon, and will work to make simple build wrappers work on various platforms, though this is a low priority.&lt;br /&gt;
&lt;br /&gt;
Ask Enus for updated documentation to be checked in, or, build a better refresh.py.&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[Pyogp/Roadmap]] for details, or ask in irc or on the mailing list. Here&#039;s what&#039;s up in the near term for pyogp:&lt;br /&gt;
&lt;br /&gt;
* better &#039;&#039;&#039;packaging&#039;&#039;&#039; and &#039;&#039;&#039;platform compatibility&#039;&#039;&#039;&lt;br /&gt;
* more &#039;&#039;&#039;functional coverage&#039;&#039;&#039; of message. We are covering 32% of the messages the viewers sends or handles when received (though it&#039;s estimated at more like 50% of normal use cases.&lt;br /&gt;
* &#039;&#039;&#039;permissions system testing&#039;&#039;&#039; to save QA from 3-5 day regression passes on perms&lt;br /&gt;
* &#039;&#039;&#039;appearance&#039;&#039;&#039; - this will require enabling upload and download, plus baking. Anyone have some spare time? :)&lt;br /&gt;
&lt;br /&gt;
[[Category: Pyogp_Client_Lib]]&lt;br /&gt;
[[Category: Pyogp]]&lt;br /&gt;
[[Category:Architecture Working Group]]&lt;br /&gt;
[[Category:Grid_Interoperability]]&lt;br /&gt;
[[Category:AW Groupies]]&lt;br /&gt;
[[Category:MMOX]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=XTEA_Strong_Encryption_Implementation&amp;diff=799973</id>
		<title>XTEA Strong Encryption Implementation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=XTEA_Strong_Encryption_Implementation&amp;diff=799973"/>
		<updated>2010-03-12T06:52:19Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}{{RightToc}}&lt;br /&gt;
&lt;br /&gt;
XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
Version 1.0&lt;br /&gt;
&lt;br /&gt;
= Contributors =&lt;br /&gt;
*[http://morsedillon.com/ Morse Dillon], Author, (morseATmorsedillon.com)&lt;br /&gt;
*{{User|Strife Onizuka}} (blindwandererATgmail.com)&lt;br /&gt;
*[http://dedricmauriac.wordpress.com/ Dedric Mauriac], Contributor (dedric.mauriacATgmail.com)&lt;br /&gt;
*{{User|JB_Kraft}} (php 5 class)&lt;br /&gt;
&lt;br /&gt;
= License =&lt;br /&gt;
This work is licensed under a [http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution-Share Alike 3.0 Unported License]&lt;br /&gt;
&lt;br /&gt;
You are free:&lt;br /&gt;
*&#039;&#039;&#039;to Share&#039;&#039;&#039; — to copy, distribute and transmit the work&lt;br /&gt;
*&#039;&#039;&#039;to Remix&#039;&#039;&#039; — to adapt the work&lt;br /&gt;
&lt;br /&gt;
Under the following conditions&lt;br /&gt;
*&#039;&#039;&#039;Attribution.&#039;&#039;&#039; You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).&lt;br /&gt;
&lt;br /&gt;
# For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with [http://creativecommons.org/licenses/by/3.0/ a link to this web page].&lt;br /&gt;
# Any of the above conditions can be waived if you get permission from the copyright holder.&lt;br /&gt;
# Nothing in this license impairs or restricts the author&#039;s moral rights.&lt;br /&gt;
&lt;br /&gt;
= Disclaimer =&lt;br /&gt;
This program is distributed in the hope that it will be useful, but &#039;&#039;&#039;WITHOUT ANY WARRANTY&#039;&#039;&#039;; without even the implied warranty of &#039;&#039;&#039;MERCHANTABILITY&#039;&#039;&#039; or &#039;&#039;&#039;FITNESS FOR A PARTICULAR PURPOSE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IF YOU READ ONE THING IN HERE, READ THIS&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is VERY important to remember that there is no such thing as &#039;&#039;cookbook cryptography&#039;&#039;!  Simply using this cypher does not guarantee security.  Security is an end-to-end concern and responsibility lies with you to thoroughly examine your project from all possible angles if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d rather break into your house - futzing about with picking a high-security deadbolt on the front door or walking in through the back door that you left open.&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
Included at the end of this source listing is a small bit of example  code that shows the usage.  If you wish to include this implementation in your own work, just replace the example code with your own.  Also, please do not reuse or redistribute this work without including the above text attributing this code to its author Morse Dillon, the above GPL statement, and this documentation.&lt;br /&gt;
&lt;br /&gt;
This is an implementation of the XTEA (eXtended Tiny Encryption Algorithm) block cypher.  (X)TEA is a very good choice of cipher when security is important but computational power is limited.  Although I did a lot of work on this implementation, enormous amounts of credit must be given to the creators of the algorithm and those who came before me to implement it in other languages and computing environments.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you do decide to use this code in a project, I&#039;d appreciate hearing about it.  You can reach me by e-mail at: morseATmorsedillon.com&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== About TEA ==&lt;br /&gt;
&lt;br /&gt;
The Tiny Encryption Algorithm ([http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm TEA]), was originally designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory.  The [http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html algorithm] itself is not subject to any patents.  While the original TEA was found to have some minor weaknesses, the eXtended Tiny Encryption Algorithm ([http://en.wikipedia.org/wiki/XTEA XTEA]) implemented herein addresses these.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;NOTE: XTEA has been superseded by Corrected Block TEA ([http://en.wikipedia.org/wiki/XXTEA XXTEA])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TEA and its derivatives consist of 64-bit block [http://en.wikipedia.org/wiki/Feistel_cipher Feistel network] with a 128-bit key.  This implementation uses six cycles, or rounds, which is less than one would like but still provides a reasonable level of security (16 is sufficient while 8 is enough for most applications).  Six is said to achieve theoretically good dispersion, but should more security be desired the number of cycles can easily be modified by changing the CYCLES global variable.  Due to the low execution speed of LSL scripts, it&#039;s suggested to make this as low as your comfort level allows.  Encryption time scales linearly with the number of cycles.&lt;br /&gt;
&lt;br /&gt;
== About this implementation ==&lt;br /&gt;
This is a bare bones implementation, and is meant to be included in the body of the script needing encryption facilities or wrapped in a link message handler.  If the latter approach is desired, care should be taken to only send link messages to the prim containing this implementation.  If ALL_PRIMS is used as the destination, one could link a link message listener to the object and intercept clear-text communications.  &lt;br /&gt;
&lt;br /&gt;
If you plan to place this code into the same script as that needing encryption facilities, you need only call the following functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string Encrypt(string clearText)&lt;br /&gt;
string Decrypt(string cypherText)&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simple as that.&lt;br /&gt;
&lt;br /&gt;
This implementation does not provide any secure key exchange, so in terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
&lt;br /&gt;
The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3, and KEY4.  These are global variables at the beginning of the source and can be set using a method that works for you.&lt;br /&gt;
&lt;br /&gt;
==Changes==&lt;br /&gt;
&lt;br /&gt;
===Version 1.1===&lt;br /&gt;
*Changed to treat [[Right Shift]] as if integers were unsigned&lt;br /&gt;
&lt;br /&gt;
===Version 1.0a - Alpha===&lt;br /&gt;
*General optimization to run faster and use less bytecode.&lt;br /&gt;
*Encrypt: Pad works differently, no longer extra characters appended to the output.&lt;br /&gt;
*TEAEncrypt: Changed the return type&lt;br /&gt;
*ord: Added null support.&lt;br /&gt;
&lt;br /&gt;
===Version 1.0===&lt;br /&gt;
*Initial Release&lt;br /&gt;
&lt;br /&gt;
== Future Recommendations ==&lt;br /&gt;
*Support [[UTF-8]]&lt;br /&gt;
*Output to [[Base64]] instead of [[Hex]] strings&lt;br /&gt;
*Append hash to the message to verify integrity of data&lt;br /&gt;
*Hash clear-text passwords into 128 bit keys&lt;br /&gt;
*Upgrade to XXTEA&lt;br /&gt;
&lt;br /&gt;
= Code =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Original ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
//Version 1.0&lt;br /&gt;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)&lt;br /&gt;
//&lt;br /&gt;
//This program is free software; you can redistribute it and/or&lt;br /&gt;
//modify it under the terms of the GNU General Public License&lt;br /&gt;
//as published by the Free Software Foundation; either version 2&lt;br /&gt;
//of the License, or (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
//This program is distributed in the hope that it will be useful,&lt;br /&gt;
//but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
//GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
//You should have received a copy of the GNU General Public License&lt;br /&gt;
//along with this program; if not, write to the Free Software&lt;br /&gt;
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA&lt;br /&gt;
//02110-1301, USA.&lt;br /&gt;
//========================================================================&lt;br /&gt;
//&lt;br /&gt;
//Included at the end of this source listing is a small bit of example &lt;br /&gt;
//code that shows the usage.  If you wish to include this implementation &lt;br /&gt;
//in your own work, just replace the example code with your own.  Also, &lt;br /&gt;
//please do not reuse or redistribute this work without including the &lt;br /&gt;
//above text attributing this code to its author Morse Dillon, the above&lt;br /&gt;
//GPL statement, and this documentation.&lt;br /&gt;
//&lt;br /&gt;
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) &lt;br /&gt;
//block cypher.  (X)TEA is a very good choice of cipher when security&lt;br /&gt;
//is important but computational power is limited.  Although I did a&lt;br /&gt;
//lot of work on this implementation, enormous amounts of credit must&lt;br /&gt;
//be given to the creators of the algorithm and those who came before&lt;br /&gt;
//me to implement it in other languages and computing environments.&lt;br /&gt;
//&lt;br /&gt;
//***If you do decide to use this code in a project, I&#039;d appreciate &lt;br /&gt;
//hearing about it.  You can reach me by e-mail at:  &lt;br /&gt;
//morseATmorsedillon.com&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT TEA AND XTEA&lt;br /&gt;
//------------------&lt;br /&gt;
//TEA was originally designed by David Wheeler and Roger Needham &lt;br /&gt;
//of the Cambridge Computer Laboratory.  The algorithm itself is not&lt;br /&gt;
//subject to any patents.  While the original TEA was found to have&lt;br /&gt;
//some minor weaknesses, XTEA (implemented herein) addresses these.  &lt;br /&gt;
//&lt;br /&gt;
//TEA and its derivatives consist of 64-bit block Feistel network &lt;br /&gt;
//with a 128-bit key.  This implementation uses six cycles, or rounds,&lt;br /&gt;
//which is less than one would like but still provides a reasonable&lt;br /&gt;
//level of security (16 is sufficient while 8 is enough for most &lt;br /&gt;
//applications).  Six is said to achieve theoretically good dispersion, &lt;br /&gt;
//but should more security be desired the number of cycles can easily be &lt;br /&gt;
//modified by changing the CYCLES global variable.  Due to the low &lt;br /&gt;
//execution speed of LSL scripts, it&#039;s suggested to make this as low as &lt;br /&gt;
//your comfort level allows.  Encryption time scales linearly with the &lt;br /&gt;
//number of cycles.&lt;br /&gt;
//&lt;br /&gt;
//For more information about XTEA, see the following:&lt;br /&gt;
//&lt;br /&gt;
//Original Paper by Walker and Needham&lt;br /&gt;
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html&lt;br /&gt;
//&lt;br /&gt;
//Wikipedia on TEA&lt;br /&gt;
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT THIS IMPLEMENTATION&lt;br /&gt;
//-------------------------&lt;br /&gt;
//This is a barebones implementation, and is meant to be included in&lt;br /&gt;
//the body of the script needing encryption facilities or wrapped&lt;br /&gt;
//in a link message handler.  If the latter approach is desired, care&lt;br /&gt;
//should be taken to only send link messages to the prim containing&lt;br /&gt;
//this implementation.  If ALL_PRIMS is used as the destination,&lt;br /&gt;
//one could link a link message listener to the object and intercept&lt;br /&gt;
//cleartext communications.  &lt;br /&gt;
//&lt;br /&gt;
//If you plan to place this code into the same script as that needing&lt;br /&gt;
//encryption facilities, you need only call the following functions:&lt;br /&gt;
//&lt;br /&gt;
//string Encrypt(string cleartext)&lt;br /&gt;
//string Decrypt(string cyphertext)&lt;br /&gt;
//&lt;br /&gt;
//Simple as that.&lt;br /&gt;
//&lt;br /&gt;
//This implementation does not provide any secure key exchange, so in&lt;br /&gt;
//terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
//&lt;br /&gt;
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,&lt;br /&gt;
//and KEY4.  These are global variables at the beginning of the source&lt;br /&gt;
//and can be set using a method that works for you.&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************&lt;br /&gt;
//It is VERY important to remember that there is no such thing as&lt;br /&gt;
//&#039;cookbook cryptography&#039;!  Simply using this cypher does not guarantee&lt;br /&gt;
//security.  Security is an end-to-end concern and responsibility lies&lt;br /&gt;
//with you to thoroughly examine your project from all possible angles&lt;br /&gt;
//if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d&lt;br /&gt;
//rather break into your house - futzing about with picking a high-security&lt;br /&gt;
//deadbolt on the front door or walking in through the back door that you &lt;br /&gt;
//left open.&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************&lt;br /&gt;
&lt;br /&gt;
//ENCRYPTION KEYS KEY[1-4]&lt;br /&gt;
//These together make up the 128-bit XTEA encryption key.  See the above &lt;br /&gt;
//documentation for details.  Whatever you do, don&#039;t leave them as the default.&lt;br /&gt;
integer KEY1 = 11111111;&lt;br /&gt;
integer KEY2 = 22222222;&lt;br /&gt;
integer KEY3 = 33333333;&lt;br /&gt;
integer KEY4 = 44444444;&lt;br /&gt;
&lt;br /&gt;
//DEBUG_FLAG&lt;br /&gt;
//If set to 1, will cause debug text to be printed containing some &lt;br /&gt;
//intermediate cleartext/cyphertext and the resultant cyphertext/cleartext.  &lt;br /&gt;
//Do not leave this enabled in production environments!!!!&lt;br /&gt;
integer DEBUG_FLAG = 0;&lt;br /&gt;
&lt;br /&gt;
//COMM_CHANNEL&lt;br /&gt;
//Specifies which channel should be used for debug and test harness communication.&lt;br /&gt;
integer COMM_CHANNEL = 0;&lt;br /&gt;
&lt;br /&gt;
//CYCLES&lt;br /&gt;
//Specifies the number of rounds to be used.  See the above documentation for&lt;br /&gt;
//details.&lt;br /&gt;
integer CYCLES = 6;&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS END HERE*********************&lt;br /&gt;
&lt;br /&gt;
//Other Globals&lt;br /&gt;
list cypherkey = [];&lt;br /&gt;
integer delta = 0x9E3779B9;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: ord&lt;br /&gt;
//Returns the index of an ASCII character&lt;br /&gt;
integer ord(string chr)&lt;br /&gt;
{&lt;br /&gt;
    string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
    if(llStringLength(chr) != 1) return -1;&lt;br /&gt;
    if(chr == &amp;quot; &amp;quot;) return 32;&lt;br /&gt;
    return llSubStringIndex(ASCII, chr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: chr&lt;br /&gt;
//Returns the ASCII character correspondent to index i&lt;br /&gt;
string chr(integer i)&lt;br /&gt;
{&lt;br /&gt;
    string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
    i %= 127;&lt;br /&gt;
    return llGetSubString(ASCII, i, i);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
                     &lt;br /&gt;
//Function:  DWord2Hex&lt;br /&gt;
//Converts a dword containted in a LSL integer to hexadecimal format.        &lt;br /&gt;
string DWord2Hex(integer m){&lt;br /&gt;
    &lt;br /&gt;
    string result;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer index = 0;&lt;br /&gt;
    &lt;br /&gt;
    //Define character string [0-F] for use in building the hex.&lt;br /&gt;
    string characters = &amp;quot;0123456789ABCDEF&amp;quot;;   &lt;br /&gt;
    &lt;br /&gt;
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.&lt;br /&gt;
    for (i = 0; i &amp;lt; 8; i++){&lt;br /&gt;
        //Get a nibble by right-shifting and masking off 4 bits.&lt;br /&gt;
        index  = (m &amp;gt;&amp;gt; (i * 4)) &amp;amp; 0xF;&lt;br /&gt;
        //Grab character from the characters string at index position and add it to the result string.&lt;br /&gt;
        result = llInsertString(result, 0, llGetSubString(characters,index,index));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function:  Hex2DWword&lt;br /&gt;
//Converts a string containing a hexadecimal number to a dword contained in a LSL integer.&lt;br /&gt;
integer Hex2DWord(string m){&lt;br /&gt;
    integer result = 0;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    string digit;&lt;br /&gt;
    integer value;&lt;br /&gt;
    integer index;&lt;br /&gt;
    &lt;br /&gt;
    string characters = &amp;quot;0123456789ABCDEF&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; i++){&lt;br /&gt;
        &lt;br /&gt;
        index = 8 - (i + 1);&lt;br /&gt;
        digit = llGetSubString(m,index,index);&lt;br /&gt;
        &lt;br /&gt;
        value = llSubStringIndex(characters, digit);&lt;br /&gt;
                        &lt;br /&gt;
        result = result | value &amp;lt;&amp;lt; (i * 4);&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Encrypt&lt;br /&gt;
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().&lt;br /&gt;
string Encrypt(string cleartext){&lt;br /&gt;
        &lt;br /&gt;
        //Initialize variables.&lt;br /&gt;
        integer dword1 = 0;&lt;br /&gt;
        integer dword2 = 0;&lt;br /&gt;
        integer cyphertext_numeric;&lt;br /&gt;
        list cypherblock;&lt;br /&gt;
        string cyphertext = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        //Pad cleartext string to the nearest multiple of 8.&lt;br /&gt;
        while(llStringLength(cleartext) &amp;amp; 0x7) {&lt;br /&gt;
            cleartext += &amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Define more variables pertaining to while loop.&lt;br /&gt;
        integer stringlength = llStringLength(cleartext); &lt;br /&gt;
        integer i=0;&lt;br /&gt;
        integer character;&lt;br /&gt;
        &lt;br /&gt;
        //Step through cleartext string, encrypting it in 64-bit (8 character) blocks.&lt;br /&gt;
        while (i &amp;lt; stringlength){&lt;br /&gt;
            &lt;br /&gt;
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.&lt;br /&gt;
            //4th byte winds up in the most-significant position.&lt;br /&gt;
            dword1 =  ord(llGetSubString(cleartext,i,i));&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 8);&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 16);&lt;br /&gt;
            i++;&lt;br /&gt;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 24);&lt;br /&gt;
            i++;&lt;br /&gt;
            &lt;br /&gt;
            //Do it again, this time for dword2                            &lt;br /&gt;
            dword2 =  ord(llGetSubString(cleartext,i,i));&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 8;&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 16;&lt;br /&gt;
            i++;&lt;br /&gt;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) &amp;lt;&amp;lt; 24;&lt;br /&gt;
            i++;&lt;br /&gt;
&lt;br /&gt;
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.&lt;br /&gt;
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);&lt;br /&gt;
 &lt;br /&gt;
            //Convert dword values from cypherblock to hex and append to cyphertext.&lt;br /&gt;
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));&lt;br /&gt;
                    &lt;br /&gt;
            //Reset variables for the next round, just to be safe.&lt;br /&gt;
            dword1 = 0;&lt;br /&gt;
            dword2 = 0;&lt;br /&gt;
            cypherblock = [];&lt;br /&gt;
            &lt;br /&gt;
            if(DEBUG_FLAG){&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Crypt DWords: &amp;quot; + (string)dword1 + &amp;quot;,&amp;quot; + (string)dword2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Crypt DWords: &amp;quot; + (string)llList2Integer(cypherblock,1) + &amp;quot;,&amp;quot; + (string)llList2Integer(cypherblock,2));    &lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Crypt Hex: &amp;quot; + DWord2Hex(llList2Integer(cypherblock,1)) + &amp;quot;,&amp;quot; + DWord2Hex(llList2Integer(cypherblock,2)));&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        return cyphertext;        &lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Decrypt&lt;br /&gt;
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.&lt;br /&gt;
string Decrypt(string cyphertext){&lt;br /&gt;
        &lt;br /&gt;
        //Initialize variables.&lt;br /&gt;
        string hexvalue1 = &amp;quot;&amp;quot;;&lt;br /&gt;
        string hexvalue2 = &amp;quot;&amp;quot;;&lt;br /&gt;
        integer dword1 = 0;&lt;br /&gt;
        integer dword2 = 0;&lt;br /&gt;
        list clearblock = []; //res&lt;br /&gt;
        string cleartext = &amp;quot;&amp;quot;;&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        //Step through cyphertext string, descrypting it block by block.&lt;br /&gt;
        while (i &amp;lt; llStringLength(cyphertext)){&lt;br /&gt;
            &lt;br /&gt;
            //Pull first 32 bits worth of hexadecimal into hexvalue1&lt;br /&gt;
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);&lt;br /&gt;
            i = i + 8;&lt;br /&gt;
            &lt;br /&gt;
            //Pull second 32 bits worth of hexadecimal into hexvalue2&lt;br /&gt;
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);&lt;br /&gt;
            i = i + 8;&lt;br /&gt;
&lt;br /&gt;
            //Convert hexvalues to dwords contained in LSL integers.&lt;br /&gt;
            dword1 = Hex2DWord(hexvalue1);&lt;br /&gt;
            dword2 = Hex2DWord(hexvalue2); &lt;br /&gt;
    &lt;br /&gt;
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.&lt;br /&gt;
            clearblock = TEADecrypt(dword1, dword2, cypherkey);&lt;br /&gt;
            &lt;br /&gt;
            //Append first 4 characters of ASCII to cleartext string.&lt;br /&gt;
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.&lt;br /&gt;
            cleartext += chr( llList2Integer(clearblock,0) &amp;amp; 0x000000FF);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0x0000FF00)  &amp;gt;&amp;gt; 8);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0x00FF0000)  &amp;gt;&amp;gt; 16);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,0) &amp;amp; 0xFF000000)  &amp;gt;&amp;gt; 24);&lt;br /&gt;
&lt;br /&gt;
            //Append second 4 characters of ASCII to cleartext string.&lt;br /&gt;
            cleartext += chr( llList2Integer(clearblock,1) &amp;amp; 0x000000FF);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0x0000FF00)  &amp;gt;&amp;gt; 8);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0x00FF0000)  &amp;gt;&amp;gt; 16);&lt;br /&gt;
            cleartext += chr( (llList2Integer(clearblock,1) &amp;amp; 0xFF000000)  &amp;gt;&amp;gt; 24);&lt;br /&gt;
&lt;br /&gt;
            //Reset variables for the next two blocks of decrypt.            &lt;br /&gt;
            hexvalue1 = &amp;quot;&amp;quot;;&lt;br /&gt;
            hexvalue2 = &amp;quot;&amp;quot;;&lt;br /&gt;
            dword1 = 0;&lt;br /&gt;
            dword2 = 0;&lt;br /&gt;
            clearblock = [];&lt;br /&gt;
            &lt;br /&gt;
            if(DEBUG_FLAG){&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Decrypt Hex: &amp;quot; + hexvalue1 + &amp;quot;,&amp;quot; + hexvalue2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Pre-Decrypt DWords: &amp;quot; + (string)dword1 + &amp;quot;,&amp;quot; + (string)dword2);&lt;br /&gt;
                llOwnerSay(&amp;quot;Post-Decrypt DWords: &amp;quot; + (string)llList2Integer(clearblock,1) + &amp;quot;,&amp;quot; + (string)llList2Integer(clearblock,2));&lt;br /&gt;
            }&lt;br /&gt;
             &lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return cleartext;        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEAEncrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cleartext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cyphertext in an LSL list of two integers.&lt;br /&gt;
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){&lt;br /&gt;
    &lt;br /&gt;
            list cryptlist = [];&lt;br /&gt;
            &lt;br /&gt;
            //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
            integer n = CYCLES;&lt;br /&gt;
                        &lt;br /&gt;
            integer sum = 0;&lt;br /&gt;
            &lt;br /&gt;
            //Operate for the specified number of cycles.&lt;br /&gt;
            while (n-- &amp;gt; 0){&lt;br /&gt;
                dword1 = dword1 + ( ( dword2 &amp;lt;&amp;lt; 4 ^ ((dword2 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum &amp;amp; 3) ) );&lt;br /&gt;
                sum += delta;&lt;br /&gt;
                dword2 = dword2 + ( ( dword1 &amp;lt;&amp;lt; 4 ^ ((dword1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum &amp;gt;&amp;gt; 11) &amp;amp; 3) ) );&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            cryptlist = [dword1,dword2];&lt;br /&gt;
&lt;br /&gt;
            return cryptlist;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cyphertext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cleartext in an LSL list of two integers.&lt;br /&gt;
list TEADecrypt(integer dword1, integer dword2,list cypherkey){&lt;br /&gt;
    &lt;br /&gt;
            list cryptlist = [];&lt;br /&gt;
            &lt;br /&gt;
            //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
            integer n = CYCLES;&lt;br /&gt;
                        &lt;br /&gt;
            integer sum = delta * CYCLES;&lt;br /&gt;
&lt;br /&gt;
            //Operate for the specified number of cycles.        &lt;br /&gt;
            while (n-- &amp;gt; 0){&lt;br /&gt;
                dword2 = dword2 - ( ( dword1 &amp;lt;&amp;lt; 4 ^ ((dword1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum &amp;gt;&amp;gt; 11) &amp;amp; 3) ) );&lt;br /&gt;
                sum -= delta;&lt;br /&gt;
                dword1 = dword1 - ( ( dword2 &amp;lt;&amp;lt; 4 ^ ((dword2 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum &amp;amp; 3) ) );        &lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            cryptlist = [dword1,dword2];&lt;br /&gt;
            return cryptlist;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage Example ==&lt;br /&gt;
Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cypher-text. Object than says the encrypted and decrypted messages to the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(COMM_CHANNEL, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        cypherkey = [KEY1,KEY2,KEY3,KEY4];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string temp_cyphertext = Encrypt(message);&lt;br /&gt;
        &lt;br /&gt;
        string temp_cleartext = Decrypt(temp_cyphertext);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;\nOriginal Cleartext: &amp;quot; + message + &amp;quot;\nCyphertext: &amp;quot; + temp_cyphertext + &amp;quot;\nDecrypted Cleartext: &amp;quot; + temp_cleartext);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimized ==&lt;br /&gt;
This version is untested but if it works should run faster (and be able to handle larger strings).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Include the documentation comments from above (separated here only for easier management)&lt;br /&gt;
&lt;br /&gt;
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)&lt;br /&gt;
//Version 1.0a Alpha&lt;br /&gt;
//Copyright (C) 2007 by Strife Onizuka (blindwandererATgmail.com)&lt;br /&gt;
//&lt;br /&gt;
//Version 1.0&lt;br /&gt;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)&lt;br /&gt;
//&lt;br /&gt;
//This program is free software; you can redistribute it and/or&lt;br /&gt;
//modify it under the terms of the GNU General Public License&lt;br /&gt;
//as published by the Free Software Foundation; either version 2&lt;br /&gt;
//of the License, or (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
//This program is distributed in the hope that it will be useful,&lt;br /&gt;
//but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
//GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
//You should have received a copy of the GNU General Public License&lt;br /&gt;
//along with this program; if not, write to the Free Software&lt;br /&gt;
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA&lt;br /&gt;
//02110-1301, USA.&lt;br /&gt;
//========================================================================&lt;br /&gt;
//&lt;br /&gt;
//Included at the end of this source listing is a small bit of example &lt;br /&gt;
//code that shows the usage.  If you wish to include this implementation &lt;br /&gt;
//in your own work, just replace the example code with your own.  Also, &lt;br /&gt;
//please do not reuse or redistribute this work without including the &lt;br /&gt;
//above text attributing this code to its author Morse Dillon, the above&lt;br /&gt;
//GPL statement, and this documentation.&lt;br /&gt;
//&lt;br /&gt;
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) &lt;br /&gt;
//block cypher.  (X)TEA is a very good choice of cipher when security&lt;br /&gt;
//is important but computational power is limited.  Although I did a&lt;br /&gt;
//lot of work on this implementation, enormous amounts of credit must&lt;br /&gt;
//be given to the creators of the algorithm and those who came before&lt;br /&gt;
//me to implement it in other languages and computing environments.&lt;br /&gt;
//&lt;br /&gt;
//***If you do decide to use this code in a project, I&#039;d appreciate &lt;br /&gt;
//hearing about it.  You can reach me by e-mail at:  &lt;br /&gt;
//morseATmorsedillon.com&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT TEA AND XTEA&lt;br /&gt;
//------------------&lt;br /&gt;
//TEA was originally designed by David Wheeler and Roger Needham &lt;br /&gt;
//of the Cambridge Computer Laboratory.  The algorithm itself is not&lt;br /&gt;
//subject to any patents.  While the original TEA was found to have&lt;br /&gt;
//some minor weaknesses, XTEA (implemented herein) addresses these.  &lt;br /&gt;
//&lt;br /&gt;
//TEA and its derivatives consist of 64-bit block Feistel network &lt;br /&gt;
//with a 128-bit key.  This implementation uses six cycles, or rounds,&lt;br /&gt;
//which is less than one would like but still provides a reasonable&lt;br /&gt;
//level of security (16 is sufficient while 8 is enough for most &lt;br /&gt;
//applications).  Six is said to achieve theoretically good dispersion, &lt;br /&gt;
//but should more security be desired the number of cycles can easily be &lt;br /&gt;
//modified by changing the CYCLES global variable.  Due to the low &lt;br /&gt;
//execution speed of LSL scripts, it&#039;s suggested to make this as low as &lt;br /&gt;
//your comfort level allows.  Encryption time scales linearly with the &lt;br /&gt;
//number of cycles.&lt;br /&gt;
//&lt;br /&gt;
//For more information about XTEA, see the following:&lt;br /&gt;
//&lt;br /&gt;
//Original Paper by Walker and Needham&lt;br /&gt;
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html&lt;br /&gt;
//&lt;br /&gt;
//Wikipedia on TEA&lt;br /&gt;
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//ABOUT THIS IMPLEMENTATION&lt;br /&gt;
//-------------------------&lt;br /&gt;
//This is a barebones implementation, and is meant to be included in&lt;br /&gt;
//the body of the script needing encryption facilities or wrapped&lt;br /&gt;
//in a link message handler.  If the latter approach is desired, care&lt;br /&gt;
//should be taken to only send link messages to the prim containing&lt;br /&gt;
//this implementation.  If ALL_PRIMS is used as the destination,&lt;br /&gt;
//one could link a link message listener to the object and intercept&lt;br /&gt;
//cleartext communications.  &lt;br /&gt;
//&lt;br /&gt;
//If you plan to place this code into the same script as that needing&lt;br /&gt;
//encryption facilities, you need only call the following functions:&lt;br /&gt;
//&lt;br /&gt;
//string Encrypt(string cleartext)&lt;br /&gt;
//string Decrypt(string cyphertext)&lt;br /&gt;
//&lt;br /&gt;
//Simple as that.&lt;br /&gt;
//&lt;br /&gt;
//This implementation does not provide any secure key exchange, so in&lt;br /&gt;
//terms of key generation and exchange you&#039;re on your own.&lt;br /&gt;
//&lt;br /&gt;
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,&lt;br /&gt;
//and KEY4.  These are global variables at the beginning of the source&lt;br /&gt;
//and can be set using a method that works for you.&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//CHANGES&lt;br /&gt;
//-------&lt;br /&gt;
//&lt;br /&gt;
//1.0a - Alpha&lt;br /&gt;
//*General optimization to run faster and use less bytecode.&lt;br /&gt;
//*Encrypt: Pad works differently, no longer extra characters appended to the output.&lt;br /&gt;
//*TEAEncrypt: Changed the return type&lt;br /&gt;
//*ord: Added null support.&lt;br /&gt;
//&lt;br /&gt;
//1.0&lt;br /&gt;
//*Initial Release&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//FUTURE CHANGES&lt;br /&gt;
//--------------&lt;br /&gt;
//&lt;br /&gt;
//It would be nice if it supported UTF-8; but adding that would be alot&lt;br /&gt;
//of work. The main issue is the decoding, the bytes would have to be&lt;br /&gt;
//reassembled into characters. It would be time consuming. Another possibility&lt;br /&gt;
//would be to implement XTEA to output to BASE64 instead of hex strings (also&lt;br /&gt;
//time consuming to implement).&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************&lt;br /&gt;
//It is VERY important to remember that there is no such thing as&lt;br /&gt;
//&#039;cookbook cryptography&#039;!  Simply using this cypher does not guarantee&lt;br /&gt;
//security.  Security is an end-to-end concern and responsibility lies&lt;br /&gt;
//with you to thoroughly examine your project from all possible angles&lt;br /&gt;
//if valuable data is at risk.  If you doubt this, ask any thief how they&#039;d&lt;br /&gt;
//rather break into your house - futzing about with picking a high-security&lt;br /&gt;
//deadbolt on the front door or walking in through the back door that you &lt;br /&gt;
//left open.&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************&lt;br /&gt;
&lt;br /&gt;
//ENCRYPTION KEYS KEY[1-4]&lt;br /&gt;
//These together make up the 128-bit XTEA encryption key.  See the above &lt;br /&gt;
//documentation for details.  Whatever you do, don&#039;t leave them as the default.&lt;br /&gt;
//Don&#039;t be stupid and make it obvious like your av&#039;s key.&lt;br /&gt;
integer KEY1 = 11111111;&lt;br /&gt;
integer KEY2 = 22222222;&lt;br /&gt;
integer KEY3 = 33333333;&lt;br /&gt;
integer KEY4 = 44444444;&lt;br /&gt;
&lt;br /&gt;
//COMM_CHANNEL&lt;br /&gt;
//Specifies which channel should be used for debug and test harness communication.&lt;br /&gt;
integer COMM_CHANNEL = 0;&lt;br /&gt;
&lt;br /&gt;
//CYCLES&lt;br /&gt;
//Specifies the number of rounds to be used.  See the above documentation for&lt;br /&gt;
//details.&lt;br /&gt;
integer CYCLES = 6;&lt;br /&gt;
&lt;br /&gt;
//******************USER-CONFIGURABLE GLOBALS END HERE*********************&lt;br /&gt;
&lt;br /&gt;
//Other Globals&lt;br /&gt;
list cypherkey = [];&lt;br /&gt;
integer delta = 0x9E3779B9;&lt;br /&gt;
&lt;br /&gt;
string ASCII = &amp;quot;             \n                    !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
string characters = &amp;quot;0123456789ABCDEF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//Function: ord&lt;br /&gt;
//Returns the index of an ASCII character&lt;br /&gt;
integer ord(string chr)&lt;br /&gt;
{&lt;br /&gt;
    if(chr)&lt;br /&gt;
    {&lt;br /&gt;
        if(llStringLength(chr) &amp;gt; 1) return -1;&lt;br /&gt;
        if(chr == &amp;quot; &amp;quot;) return 32;&lt;br /&gt;
        return llSubStringIndex(ASCII, chr);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function: chr&lt;br /&gt;
//Returns the ASCII character correspondent to index i&lt;br /&gt;
string chr(integer i)&lt;br /&gt;
{&lt;br /&gt;
    if(i)&lt;br /&gt;
        return llGetSubString(ASCII, i %= 127, i);&lt;br /&gt;
    return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function:  DWord2Hex&lt;br /&gt;
//Converts a dword contained in a LSL integer to hexadecimal format.        &lt;br /&gt;
string DWord2Hex(integer m)&lt;br /&gt;
{&lt;br /&gt;
    string result;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
&lt;br /&gt;
    //Define character string [0-F] for use in building the hex.&lt;br /&gt;
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.&lt;br /&gt;
    do{&lt;br /&gt;
        integer index = (m &amp;gt;&amp;gt; i) &amp;amp; 0xF;&lt;br /&gt;
        result = llGetSubString(characters, index, index) + result;&lt;br /&gt;
    }while((i += 4) &amp;lt; 32);&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Function: Encrypt&lt;br /&gt;
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().&lt;br /&gt;
string Encrypt(string cleartext)&lt;br /&gt;
{&lt;br /&gt;
    string cyphertext = &amp;quot;&amp;quot;;&lt;br /&gt;
    integer i = llStringLength(cleartext);&lt;br /&gt;
    if((i += (0x7 &amp;amp; -i)))//Pad cleartext string to the nearest multiple of 8.&lt;br /&gt;
    {&lt;br /&gt;
        //Step through cleartext string backwords, encrypting it in 64-bit (8 character) blocks.&lt;br /&gt;
        do{&lt;br /&gt;
            //i=~-i is the same as --i, just a bit faster and lighter on bytecode; requires one less stack manipulation.&lt;br /&gt;
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.&lt;br /&gt;
            //4th byte winds up in the most-significant position.&lt;br /&gt;
            integer dword2 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 8 )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 16)    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 24)    ;&lt;br /&gt;
&lt;br /&gt;
            //Do it again, this time for dword1                            &lt;br /&gt;
            integer dword1 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 8 )    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 16)    |&lt;br /&gt;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) &amp;lt;&amp;lt; 24)    ;&lt;br /&gt;
&lt;br /&gt;
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.&lt;br /&gt;
&lt;br /&gt;
            //Convert dword values from cypherblock to hex and append to cyphertext.&lt;br /&gt;
            cyphertext = TEAEncrypt(dword1,dword2,cypherkey) + cyphertext;&lt;br /&gt;
        }while(i);&lt;br /&gt;
    }&lt;br /&gt;
    return cyphertext;&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: Decrypt&lt;br /&gt;
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.&lt;br /&gt;
string Decrypt(string cyphertext){&lt;br /&gt;
&lt;br /&gt;
    //Initialize variables.&lt;br /&gt;
    string cleartext = &amp;quot;&amp;quot;;&lt;br /&gt;
    integer i = -llStringLength(cyphertext);&lt;br /&gt;
&lt;br /&gt;
    //Step through cyphertext string, decrypting it block by block.&lt;br /&gt;
    if((i -= (0xF &amp;amp; i)))//Pad cyphertext string to the nearest multiple of 16.&lt;br /&gt;
    {&lt;br /&gt;
        do&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            //Convert hexvalues to dwords contained in LSL integers.&lt;br /&gt;
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.&lt;br /&gt;
            list clearblock = TEADecrypt((integer)(&amp;quot;0x&amp;quot;+llGetSubString(cyphertext,i, ~-(i -= 8))), &lt;br /&gt;
                                         (integer)(&amp;quot;0x&amp;quot;+llGetSubString(cyphertext,i, ~-(i -= 8))), cypherkey);&lt;br /&gt;
&lt;br /&gt;
            //Append first 4 characters of ASCII to cleartext string.&lt;br /&gt;
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.&lt;br /&gt;
            integer t = llList2Integer(clearblock,1);&lt;br /&gt;
            cleartext += chr( (t      ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 8 ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 16) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t = llList2Integer(clearblock,0) &amp;gt;&amp;gt; 24) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t      ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 8 ) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 16) &amp;amp; 0xFF) +&lt;br /&gt;
                         chr( (t &amp;gt;&amp;gt; 24) &amp;amp; 0xFF) ;&lt;br /&gt;
        }while(i);&lt;br /&gt;
    }&lt;br /&gt;
    return cleartext;        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cleartext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cyphertext in an LSL list of two integers.&lt;br /&gt;
string TEAEncrypt(integer dword1, integer dword2, list cypherkey_)&lt;br /&gt;
{&lt;br /&gt;
    if(CYCLES &amp;gt; 0)//$[E20011] /*lslint ignore*/&lt;br /&gt;
    {&lt;br /&gt;
        //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
        integer n = CYCLES;&lt;br /&gt;
        integer sum = 0;&lt;br /&gt;
        //Operate for the specified number of cycles.&lt;br /&gt;
        do{&lt;br /&gt;
            dword1 = dword1 + ( ( dword2 &amp;lt;&amp;lt; 4 ^ dword2 &amp;gt;&amp;gt; 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, (sum &amp;amp; 3) ) );&lt;br /&gt;
            dword2 = dword2 + ( ( dword1 &amp;lt;&amp;lt; 4 ^ dword1 &amp;gt;&amp;gt; 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, ((sum += delta) &amp;gt;&amp;gt; 11 &amp;amp; 3) ) );&lt;br /&gt;
        }while (n = ~-n);&lt;br /&gt;
    }&lt;br /&gt;
    return DWord2Hex(dword1) + DWord2Hex(dword2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Function: TEADecrypt&lt;br /&gt;
//This is the implementation of XTEA proper.  It takes a block of cyphertext&lt;br /&gt;
//consisting of two dwords contained in LSL integers and a 128-bit key &lt;br /&gt;
//contained in an LSL list of 4 integers.  The function then returns &lt;br /&gt;
//the cleartext in an LSL list of two integers.&lt;br /&gt;
list TEADecrypt(integer dword1, integer dword2,list cypherkey_)&lt;br /&gt;
{&lt;br /&gt;
    if(CYCLES &amp;gt; 0)//$[E20011] /*lslint ignore*/&lt;br /&gt;
    {&lt;br /&gt;
        //Set n to the number of cycles given in the CYCLES global variable&lt;br /&gt;
        integer n = CYCLES;&lt;br /&gt;
        integer sum = delta * CYCLES;&lt;br /&gt;
        //Operate for the specified number of cycles.        &lt;br /&gt;
        do{&lt;br /&gt;
            dword2 = dword2 - ( ( dword1 &amp;lt;&amp;lt; 4 ^ dword1 &amp;gt;&amp;gt; 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, (sum &amp;gt;&amp;gt; 11 &amp;amp; 3) ) );&lt;br /&gt;
            dword1 = dword1 - ( ( dword2 &amp;lt;&amp;lt; 4 ^ dword2 &amp;gt;&amp;gt; 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, ((sum -= delta) &amp;amp; 3) ) );        &lt;br /&gt;
        }while (n = ~-n);&lt;br /&gt;
    }&lt;br /&gt;
    return [dword1,dword2];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//XTEA Usage Example&lt;br /&gt;
//Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cyphertext.&lt;br /&gt;
//Object than says the encrypted and decrypted messages to the owner.&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(COMM_CHANNEL, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        cypherkey = [KEY1,KEY2,KEY3,KEY4];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string temp_cyphertext = Encrypt(message);&lt;br /&gt;
&lt;br /&gt;
        string temp_cleartext = Decrypt(temp_cyphertext);&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;\nOriginal Cleartext: &amp;quot; + message + &amp;quot;\nCyphertext: &amp;quot; + temp_cyphertext + &amp;quot;\nDecrypted Cleartext: &amp;quot; + temp_cleartext);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== XTEA LSL &amp;lt;-&amp;gt; PHP ==&lt;br /&gt;
This is an XTEA implementation that has both LSL and PHP scripts to allow strong encryption not only inside LSL but also between LSL and a PHP serverscript.&lt;br /&gt;
&lt;br /&gt;
For those who want to see this in action with your Web server try these. Be sure that if you  edit these that Rounds and Key Phrase are the same in both LSL and PHP versions.&lt;br /&gt;
&lt;br /&gt;
LSL - PLACE IN PRIM -- Edit to change URL and tosend text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//************************************************// &lt;br /&gt;
//* Masa&#039;s XTEA encryption/decryption v3         *// &lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *// &lt;br /&gt;
//* intercommunication with PHP version          *// &lt;br /&gt;
//************************************************// &lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block! &lt;br /&gt;
// This code is public domain. &lt;br /&gt;
// Sleight was here 20070522 &lt;br /&gt;
// masa was here 20070315 &lt;br /&gt;
// so was strife 20070315 &lt;br /&gt;
// so was adz 20070812&lt;br /&gt;
//&lt;br /&gt;
// This was Modified by SleightOf Hand to allow&lt;br /&gt;
// Strong encryption between LSL and PHP. &lt;br /&gt;
//************************************************// &lt;br /&gt;
//* XTEA IMPLEMENTATION                          *// &lt;br /&gt;
//************************************************// &lt;br /&gt;
&lt;br /&gt;
integer XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31 &lt;br /&gt;
integer xtea_num_rounds = 6; &lt;br /&gt;
list    xtea_key        = [0, 0, 0, 0]; &lt;br /&gt;
&lt;br /&gt;
integer hex2int(string hex) {&lt;br /&gt;
    if(llGetSubString(hex,0,1) == &amp;quot;0x&amp;quot;)&lt;br /&gt;
        return (integer)hex;&lt;br /&gt;
    if(llGetSubString(hex,0,0) == &amp;quot;x&amp;quot;)&lt;br /&gt;
        return (integer)(&amp;quot;0&amp;quot;+hex);&lt;br /&gt;
    return(integer)(&amp;quot;0x&amp;quot;+hex);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Convers any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
// 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific&lt;br /&gt;
// 128 bit key is generated for any string passed.&lt;br /&gt;
list xtea_key_from_string( string str )&lt;br /&gt;
{ &lt;br /&gt;
    str = llMD5String(str,0); // Use Nonce = 0&lt;br /&gt;
    return [    hex2int(llGetSubString(  str,  0,  7)), &lt;br /&gt;
                hex2int(llGetSubString(  str,  8,  15)), &lt;br /&gt;
                hex2int(llGetSubString(  str,  16,  23)), &lt;br /&gt;
                hex2int(llGetSubString(  str,  24,  31))]; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Encipher two integers and return the result as a 12-byte string &lt;br /&gt;
// containing two base64-encoded integers. &lt;br /&gt;
string xtea_encipher( integer v0, integer v1 )&lt;br /&gt;
{ &lt;br /&gt;
    integer num_rounds = xtea_num_rounds; &lt;br /&gt;
    integer sum = 0; &lt;br /&gt;
    do { &lt;br /&gt;
        // LSL does not have unsigned integers, so when shifting right we &lt;br /&gt;
        // have to mask out sign-extension bits. &lt;br /&gt;
        v0  += (((v1 &amp;lt;&amp;lt; 4) ^ ((v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum &amp;amp; 3));&lt;br /&gt;
        sum +=  XTEA_DELTA;&lt;br /&gt;
        v1  += (((v0 &amp;lt;&amp;lt; 4) ^ ((v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3)); &lt;br /&gt;
&lt;br /&gt;
    } while( num_rounds = ~-num_rounds ); &lt;br /&gt;
    //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
    return llGetSubString(llIntegerToBase64(v0),0,5) +&lt;br /&gt;
           llGetSubString(llIntegerToBase64(v1),0,5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Decipher two base64-encoded integers and return the FIRST 30 BITS of &lt;br /&gt;
// each as one 10-byte base64-encoded string. &lt;br /&gt;
string xtea_decipher( integer v0, integer v1 )&lt;br /&gt;
{ &lt;br /&gt;
    integer num_rounds = xtea_num_rounds; &lt;br /&gt;
    integer sum = XTEA_DELTA*xtea_num_rounds; &lt;br /&gt;
    do { &lt;br /&gt;
        // LSL does not have unsigned integers, so when shifting right we &lt;br /&gt;
        // have to mask out sign-extension bits. &lt;br /&gt;
        v1  -= (((v0 &amp;lt;&amp;lt; 4) ^ ((v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum&amp;gt;&amp;gt;11) &amp;amp; 3)); &lt;br /&gt;
        sum -= XTEA_DELTA;&lt;br /&gt;
        v0  -= (((v1 &amp;lt;&amp;lt; 4) ^ ((v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum  &amp;amp; 3)); &lt;br /&gt;
    } while ( num_rounds = ~-num_rounds ); &lt;br /&gt;
&lt;br /&gt;
    return llGetSubString(llIntegerToBase64(v0), 0, 4) + &lt;br /&gt;
           llGetSubString(llIntegerToBase64(v1), 0, 4); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Encrypt a full string using XTEA. &lt;br /&gt;
string xtea_encrypt_string( string str )&lt;br /&gt;
{ &lt;br /&gt;
    // encode string &lt;br /&gt;
    str = llStringToBase64(str); &lt;br /&gt;
    // remove trailing =s so we can do our own 0 padding &lt;br /&gt;
    integer i = llSubStringIndex( str, &amp;quot;=&amp;quot; ); &lt;br /&gt;
    if ( i != -1 ) &lt;br /&gt;
        str = llDeleteSubString( str, i, -1 ); &lt;br /&gt;
&lt;br /&gt;
    // we don&#039;t want to process padding, so get length before adding it &lt;br /&gt;
    integer len = llStringLength(str); &lt;br /&gt;
&lt;br /&gt;
    // zero pad &lt;br /&gt;
    str += &amp;quot;AAAAAAAAAA=&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
    string result; &lt;br /&gt;
    i = 0; &lt;br /&gt;
&lt;br /&gt;
    do { &lt;br /&gt;
        // encipher 30 (5*6) bits at a time. &lt;br /&gt;
        result += xtea_encipher( &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str,   i, i += 4) + &amp;quot;A=&amp;quot;), &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str, ++i, i += 4) + &amp;quot;A=&amp;quot;) &lt;br /&gt;
        ); &lt;br /&gt;
    } while ( ++i &amp;lt; len ); &lt;br /&gt;
&lt;br /&gt;
    return result; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
// Decrypt a full string using XTEA &lt;br /&gt;
string xtea_decrypt_string( string str ) { &lt;br /&gt;
    integer len = llStringLength(str); &lt;br /&gt;
    integer i; &lt;br /&gt;
    string result; &lt;br /&gt;
    do { &lt;br /&gt;
        result += xtea_decipher( &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str,   i, i += 5) + &amp;quot;==&amp;quot;), &lt;br /&gt;
            llBase64ToInteger(llGetSubString(str, ++i, i += 5) + &amp;quot;==&amp;quot;) &lt;br /&gt;
        ); &lt;br /&gt;
    } while ( ++i &amp;lt; len ); &lt;br /&gt;
&lt;br /&gt;
    // Replace multiple trailing zeroes with a single one &lt;br /&gt;
    i = llStringLength(result) - 1; &lt;br /&gt;
    while ( llGetSubString(result, --i, i+1) == &amp;quot;AA&amp;quot; ) &lt;br /&gt;
        result = llDeleteSubString(result, i+1, i+1); &lt;br /&gt;
    return llBase64ToString( result + &amp;quot;====&amp;quot; ); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
key requestid; // just to check if we&#039;re getting the result we&#039;ve asked for; all scripts in the same object get the same replies&lt;br /&gt;
string base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot; + &lt;br /&gt;
&lt;br /&gt;
                          &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot; + &lt;br /&gt;
&lt;br /&gt;
                          &amp;quot;0123456789+/&amp;quot;;&lt;br /&gt;
string url = &amp;quot;http://&amp;lt;enter your URL here&amp;gt;/test-script.php&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer number)&lt;br /&gt;
    {&lt;br /&gt;
        string tosend = &amp;quot;this is a message to send&amp;quot;;&lt;br /&gt;
        llWhisper(0, &amp;quot;Message to Send = &amp;quot; + tosend);&lt;br /&gt;
        xtea_key = xtea_key_from_string(&amp;quot;this is a test key&amp;quot;);&lt;br /&gt;
        string message = xtea_encrypt_string(tosend);&lt;br /&gt;
        llWhisper(0, &amp;quot;Message to Server = &amp;quot; + message);&lt;br /&gt;
        requestid = llHTTPRequest(url, &lt;br /&gt;
            [HTTP_METHOD, &amp;quot;POST&amp;quot;,&lt;br /&gt;
             HTTP_MIMETYPE, &amp;quot;application/x-www-form-urlencoded&amp;quot;],&lt;br /&gt;
            &amp;quot;parameter1=&amp;quot; + llEscapeURL(message));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == requestid) { &lt;br /&gt;
            llWhisper(0, &amp;quot;Web server sent: &amp;quot; + body);&lt;br /&gt;
            integer clean = 0;&lt;br /&gt;
            string cleanbody = &amp;quot;&amp;quot;;&lt;br /&gt;
            while(~llSubStringIndex(base64,llGetSubString(body,clean,clean))){&lt;br /&gt;
                cleanbody += llGetSubString(body,clean,clean++);&lt;br /&gt;
            }&lt;br /&gt;
            llWhisper(0, &amp;quot;Cleaned : &amp;quot; + cleanbody);&lt;br /&gt;
            llWhisper(0, &amp;quot;Web server said: &amp;quot; + xtea_decrypt_string( cleanbody ));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP Code - Place on web server at location that LSL URL will be looking for.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* Sleight&#039;s PHP XTEA encryption/decryption v3  *//&lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *//&lt;br /&gt;
//* intercommunication between PHP &amp;amp; LSL         *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block!&lt;br /&gt;
// This code is public domain.&lt;br /&gt;
// Sleight was here 20070522&lt;br /&gt;
// masa was here 20070315&lt;br /&gt;
// so was strife 20070315&lt;br /&gt;
// so was adz 20080812&lt;br /&gt;
//&lt;br /&gt;
// This was converted from the LSL version by&lt;br /&gt;
// SleightOf Hand to allow Strong encryption&lt;br /&gt;
// between LSL and PHP. If you find this usefull&lt;br /&gt;
// any donations apreciated.&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* XTEA IMPLEMENTATION                          *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
&lt;br /&gt;
$_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31&lt;br /&gt;
$_xtea_num_rounds = 6;&lt;br /&gt;
$_xtea_key        = array(0, 0, 0, 0);&lt;br /&gt;
$_base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;.&lt;br /&gt;
           &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot;.&lt;br /&gt;
           &amp;quot;0123456789+/&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)&lt;br /&gt;
function base64_integer($str){&lt;br /&gt;
 global $_base64;&lt;br /&gt;
 if(strlen($str) != 8) return 0;&lt;br /&gt;
 return ((strpos($_base64,$str{0}) &amp;lt;&amp;lt; 26)|&lt;br /&gt;
 (strpos($_base64,$str{1}) &amp;lt;&amp;lt; 20)|&lt;br /&gt;
 (strpos($_base64,$str{2}) &amp;lt;&amp;lt; 14)|&lt;br /&gt;
 (strpos($_base64,$str{3}) &amp;lt;&amp;lt; 8) |&lt;br /&gt;
 (strpos($_base64,$str{4}) &amp;lt;&amp;lt; 2) |&lt;br /&gt;
 (strpos($_base64,$str{5}) &amp;gt;&amp;gt; 4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)&lt;br /&gt;
function integer_base64($int){&lt;br /&gt;
 global $_base64;&lt;br /&gt;
 if($int != (integer) $int) return 0;&lt;br /&gt;
 return  $_base64{($int &amp;gt;&amp;gt; 26 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 20 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 14 &amp;amp; 0x3F)} .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 8 &amp;amp; 0x3F)}  .&lt;br /&gt;
 $_base64{($int &amp;gt;&amp;gt; 2 &amp;amp; 0x3F)}  .&lt;br /&gt;
 $_base64{($int &amp;lt;&amp;lt; 4 &amp;amp; 0x3F)} . &amp;quot;==&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//strict 32 bit addition using logic&lt;br /&gt;
function binadd($val1 , $val2){&lt;br /&gt;
 $tc = $val1 &amp;amp; $val2;&lt;br /&gt;
 $ta = $val1 ^ $val2;&lt;br /&gt;
 do{&lt;br /&gt;
  $tac = ($tc &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
  $tc = $ta &amp;amp; $tac;&lt;br /&gt;
  $ta = $ta ^ $tac;&lt;br /&gt;
 }while($tc);&lt;br /&gt;
 return $ta; // $ta will now be the result so return it&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Convers any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
// 4 * 32 bit integers = 128 bit Key.&lt;br /&gt;
function xtea_key_from_string( $str ) {&lt;br /&gt;
 global $_xtea_key;&lt;br /&gt;
 $str = md5($str . &amp;quot;:0&amp;quot;); // Use nonce = 0 in LSL for same output&lt;br /&gt;
 eval(&amp;quot;\$_xtea_key[0] = 0x&amp;quot; . substr($str,0,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
 eval(&amp;quot;\$_xtea_key[1] = 0x&amp;quot; . substr($str,8,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
 eval(&amp;quot;\$_xtea_key[2] = 0x&amp;quot; . substr($str,16,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
 eval(&amp;quot;\$_xtea_key[3] = 0x&amp;quot; . substr($str,24,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encipher two integers and return the result as a 12-byte string&lt;br /&gt;
// containing two base64-encoded integers.&lt;br /&gt;
function xtea_encipher( $v0 , $v1 ) {&lt;br /&gt;
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds;&lt;br /&gt;
 $sum = 0;&lt;br /&gt;
 do {&lt;br /&gt;
  // LSL only has 32 bit integers. However PHP automaticly changes&lt;br /&gt;
  // 32 bit integers to 64 bit floats as nessesary. This causes&lt;br /&gt;
  // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
  // counterpart. I got round this by changing all addition to&lt;br /&gt;
  // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
  // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
  // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
  // encrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
&lt;br /&gt;
  // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
  // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
  // calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  $v0a = binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
  // calculate ($sum + $_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
  $v0b = binadd($sum , $_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
  // Calculate ($v0 + ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  //            ^ ($sum + $_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
  $v0 = binadd($v0 , ($v0a  ^ $v0b));&lt;br /&gt;
&lt;br /&gt;
  //Calculate ($sum + $_XTEA_DELTA)&lt;br /&gt;
  $sum = binadd($sum , $_XTEA_DELTA);&lt;br /&gt;
&lt;br /&gt;
  //Calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  $v1a = binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF))  , $v0);&lt;br /&gt;
  // Calculate ($sum + $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
  $v1b = binadd($sum , $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
  //Calculate ($v1 + ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0&lt;br /&gt;
  //           ^ ($sum &amp;amp; $_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
  $v1 = binadd($v1 , ($v1a  ^ $v1b));&lt;br /&gt;
 } while( $num_rounds = ~-$num_rounds );&lt;br /&gt;
 //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
 return substr(integer_base64($v0),0,6) . substr(integer_base64($v1),0,6);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Decipher two base64-encoded integers and return the FIRST 30 BITS of&lt;br /&gt;
// each as one 10-byte base64-encoded string.&lt;br /&gt;
function xtea_decipher( $v0, $v1 ) {&lt;br /&gt;
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds;&lt;br /&gt;
 $sum = 0; // $_XTEA_DELTA * $_xtea_num_rounds;&lt;br /&gt;
 $tda = $_XTEA_DELTA;&lt;br /&gt;
 do{ // Binary multiplication using binary manipulation&lt;br /&gt;
  if($num_rounds &amp;amp; 1){&lt;br /&gt;
   $sum = binadd($sum , $tda);&lt;br /&gt;
  }&lt;br /&gt;
  $num_rounds = $num_rounds &amp;gt;&amp;gt; 1;&lt;br /&gt;
  $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
 }while($num_rounds);&lt;br /&gt;
 $num_rounds = $_xtea_num_rounds; // reset $num_rounds back to its propper setting;&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
  // LSL only has 32 bit integers. However PHP automaticly changes&lt;br /&gt;
  // 32 bit integers to 64 bit floats as nessesary. This causes&lt;br /&gt;
  // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
  // counterpart. I got round this by changing all addition to&lt;br /&gt;
  // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
  // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
  // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
  // decrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
  // Subtrations are handled by using 2&#039;s compliment&lt;br /&gt;
&lt;br /&gt;
  // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
  // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
  // calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  $v1a = binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v0);&lt;br /&gt;
  // calculate ($sum + $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
  $v1b = binadd($sum , $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
  //Calculate 2&#039;s compliment of ($v1a ^ $v1b) for subtraction&lt;br /&gt;
  $v1c = binadd((~($v1a ^ $v1b)) , 1);&lt;br /&gt;
  //Calculate ($v1 - ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
  //            ^ ($sum + $_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
  $v1 = binadd($v1 , $v1c);&lt;br /&gt;
&lt;br /&gt;
  // Calculate new $sum based on $num_rounds - 1&lt;br /&gt;
  $tnr = $num_rounds - 1;  // Temp $num_rounds&lt;br /&gt;
  $sum = 0; // $_XTEA_DELTA * ($num_rounds - 1);&lt;br /&gt;
  $tda = $_XTEA_DELTA;&lt;br /&gt;
  do{ // Binary multiplication using binary manipulation&lt;br /&gt;
   if($tnr &amp;amp; 1){&lt;br /&gt;
    $sum = binadd($sum , $tda);&lt;br /&gt;
   }&lt;br /&gt;
   $tnr = $tnr &amp;gt;&amp;gt; 1;&lt;br /&gt;
   $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
  }while($tnr);&lt;br /&gt;
&lt;br /&gt;
  //Calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
  $v0a = binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
  //Calculate ($sum + $_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
  $v0b = binadd($sum , $_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
  //Calculate 2&#039;s compliment of ($v0a ^ $v0b) for subtraction&lt;br /&gt;
  $v0c = binadd((~($v0a ^ $v0b)) , 1);&lt;br /&gt;
  //Calculate ($v0 - ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1&lt;br /&gt;
  //           ^ ($sum + $_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
  $v0 = binadd($v0 , $v0c);&lt;br /&gt;
 } while ( $num_rounds = ~-$num_rounds );&lt;br /&gt;
&lt;br /&gt;
 return substr(integer_base64($v0), 0, 5) . substr(integer_base64($v1), 0, 5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Encrypt a full string using XTEA.&lt;br /&gt;
function xtea_encrypt_string( $str ) {&lt;br /&gt;
 // encode Binany string to Base64&lt;br /&gt;
 $str = base64_encode($str);&lt;br /&gt;
&lt;br /&gt;
 // remove trailing =s so we can do our own 0 padding&lt;br /&gt;
 $i = strpos($str, &#039;=&#039;, 0);&lt;br /&gt;
 if ( $i !== FALSE  ){&lt;br /&gt;
  $str = substr( $str, 0, $i);&lt;br /&gt;
 }&lt;br /&gt;
 // we don&#039;t want to process padding, so get length before adding it&lt;br /&gt;
 $len = strlen($str);&lt;br /&gt;
 // zero pad&lt;br /&gt;
 $str .= &amp;quot;AAAAAAAAAA=&amp;quot;;&lt;br /&gt;
 $result = &amp;quot;&amp;quot;;&lt;br /&gt;
 $i = 0;&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
  // encipher 30 (5*6) bits at a time.&lt;br /&gt;
  $enc1 = base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
  $i += 5;&lt;br /&gt;
  $enc2 = base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
  $i += 5;&lt;br /&gt;
  $result .= xtea_encipher($enc1, $enc2);&lt;br /&gt;
 } while ( $i &amp;lt; $len );&lt;br /&gt;
 return $result; //Return Encrypted string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Decrypt a full string using XTEA&lt;br /&gt;
function xtea_decrypt_string( $str ) {&lt;br /&gt;
 global $_base64 ;&lt;br /&gt;
&lt;br /&gt;
 $len = strlen($str);&lt;br /&gt;
 $i;&lt;br /&gt;
 $result;&lt;br /&gt;
 do {&lt;br /&gt;
  $dec1 = base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
  $i += 6;&lt;br /&gt;
  $dec2 = base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
  $i += 6;&lt;br /&gt;
  $result .= xtea_decipher( $dec1, $dec2);&lt;br /&gt;
 } while ( $i &amp;lt; $len );&lt;br /&gt;
&lt;br /&gt;
 // Replace multiple trailing zeroes with a single one&lt;br /&gt;
 $result = rtrim($result, &amp;quot;A&amp;quot;);&lt;br /&gt;
 $i = strlen($result);&lt;br /&gt;
 $mod = $i%4; //Depending on encoded length diffrent appends are needed&lt;br /&gt;
 if($mod == 1) $result .= &amp;quot;A==&amp;quot;;&lt;br /&gt;
 else if($mod == 2 ) $result .= &amp;quot;==&amp;quot;;&lt;br /&gt;
 else if($mod == 3) $result .= &amp;quot;=&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 return base64_decode( $result );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Only works with PHP compiled as an Apache module&lt;br /&gt;
$headers = apache_request_headers();&lt;br /&gt;
&lt;br /&gt;
$objectName = $headers[&amp;quot;X-SecondLife-Object-Name&amp;quot;];&lt;br /&gt;
$objectKey     = $headers[&amp;quot;X-SecondLife-Object-Key&amp;quot;];&lt;br /&gt;
$ownerKey     = $headers[&amp;quot;X-SecondLife-Owner-Key&amp;quot;];&lt;br /&gt;
$ownerName = $headers[&amp;quot;X-SecondLife-Owner-Name&amp;quot;];&lt;br /&gt;
$region        = $headers[&amp;quot;X-SecondLife-Region&amp;quot;];&lt;br /&gt;
// and so on for getting all the other variables ...&lt;br /&gt;
&lt;br /&gt;
//to pull out this headers in other kinds of installations, use this (Adz)&lt;br /&gt;
/*&lt;br /&gt;
$objectName    = $_SERVER[&#039;HTTP_X_SECONDLIFE_OBJECT_NAME&#039;];&lt;br /&gt;
$objectKey     = $_SERVER[&#039;HTTP_X_SECONDLIFE_OBJECT_KEY&#039;];&lt;br /&gt;
$region        = $_SERVER[&#039;HTTP_X_SECONDLIFE_REGION&#039;];&lt;br /&gt;
$ownerName     = $_SERVER[&#039;HTTP_X_SECONDLIFE_OWNER_NAME&#039;];&lt;br /&gt;
$ownerKey      = $_SERVER[&#039;HTTP_X_SECONDLIFE_OWNER_KEY&#039;];&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
xtea_key_from_string(&amp;quot;this is a test key&amp;quot;);&lt;br /&gt;
// get things from $_POST[]&lt;br /&gt;
// Naturally enough, if this is empty, you won&#039;t get anything&lt;br /&gt;
$parameter1 = xtea_decrypt_string($_POST[&amp;quot;parameter1&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
echo xtea_encrypt_string($ownerName . &amp;quot; just said &amp;quot; . $parameter1) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This should result in the following output.&lt;br /&gt;
&lt;br /&gt;
Object whispers: Message to Send = this is a message to send&amp;lt;br/&amp;gt;&lt;br /&gt;
Object whispers: Message to Server = JSdgCA0FDyhgLlUnSgqMQWkAxz1AzA1vr9zwSEDnCgwJ6GNQ&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Web server sent: SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Cleaned : SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw&amp;lt;br /&amp;gt;&lt;br /&gt;
Object whispers: Web server said: SleightOf Hand just said this is a message to send&lt;br /&gt;
&lt;br /&gt;
PHP 5 class of XTEA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* Sleight&#039;s PHP XTEA encryption/decryption v3  *//&lt;br /&gt;
//* Modified by SleightOf Hand for Stability and *//&lt;br /&gt;
//* intercommunication between PHP &amp;amp; LSL         *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
// NOTE: This version only encodes 60 bits per 64-bit block!&lt;br /&gt;
// This code is public domain.&lt;br /&gt;
// Sleight was here 20070522&lt;br /&gt;
// masa was here 20070315&lt;br /&gt;
// so was strife 20070315&lt;br /&gt;
// so was adz 20080812&lt;br /&gt;
// gave this some class 20080201 JB Kraft&lt;br /&gt;
//&lt;br /&gt;
// This was converted from the LSL version by&lt;br /&gt;
// SleightOf Hand to allow Strong encryption&lt;br /&gt;
// between LSL and PHP. If you find this usefull&lt;br /&gt;
// any donations apreciated.&lt;br /&gt;
//************************************************//&lt;br /&gt;
//* XTEA IMPLEMENTATION                          *//&lt;br /&gt;
//************************************************//&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * PHP 5 class to do XTEA crypting&lt;br /&gt;
 *&lt;br /&gt;
 * $xtea = new XTEA( &amp;quot;mypassword&amp;quot; );&lt;br /&gt;
 * $crypted = $xtea-&amp;gt;encrypt( &amp;quot;Some bogus string&amp;quot; );&lt;br /&gt;
 * echo &amp;quot;Encrypted: &amp;quot; . bin2hex($crypted);&lt;br /&gt;
 * echo &amp;quot;Decrypted: &amp;quot; . $xtea-&amp;gt;decrypt( $crypted );&lt;br /&gt;
 *&lt;br /&gt;
 * @package whatevah&lt;br /&gt;
 * @author JB Kraft&lt;br /&gt;
 **/&lt;br /&gt;
class XTEA&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  private $_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31&lt;br /&gt;
  private $_xtea_num_rounds = 6;&lt;br /&gt;
  private $_xtea_key        = array(0, 0, 0, 0);&lt;br /&gt;
  private $_base64 = &amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * CTOR&lt;br /&gt;
   *&lt;br /&gt;
   * @param  $passwd the password to use for crypting&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function __construct( $passwd )&lt;br /&gt;
  {&lt;br /&gt;
    $this-&amp;gt;xtea_key_from_string( $passwd );    &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * Encrypt a full string using XTEA.&lt;br /&gt;
   *&lt;br /&gt;
   * @param $str the string to encrypt&lt;br /&gt;
   * @return the encrypted string&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function encrypt( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   // encode Binany string to Base64&lt;br /&gt;
   $str = base64_encode($str);&lt;br /&gt;
&lt;br /&gt;
   // remove trailing =s so we can do our own 0 padding&lt;br /&gt;
   $i = strpos($str, &#039;=&#039;, 0);&lt;br /&gt;
   if ( $i !== FALSE  ){&lt;br /&gt;
    $str = substr( $str, 0, $i);&lt;br /&gt;
   }&lt;br /&gt;
   // we don&#039;t want to process padding, so get length before adding it&lt;br /&gt;
   $len = strlen($str);&lt;br /&gt;
   // zero pad&lt;br /&gt;
   $str .= &amp;quot;AAAAAAAAAA=&amp;quot;;&lt;br /&gt;
   $result = &amp;quot;&amp;quot;;&lt;br /&gt;
   $i = 0;&lt;br /&gt;
&lt;br /&gt;
   do {&lt;br /&gt;
    // encipher 30 (5*6) bits at a time.&lt;br /&gt;
    $enc1 = $this-&amp;gt;base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
    $i += 5;&lt;br /&gt;
    $enc2 = $this-&amp;gt;base64_integer(substr($str , $i , 5) . &amp;quot;A==&amp;quot;);&lt;br /&gt;
    $i += 5;&lt;br /&gt;
    $result .= $this-&amp;gt;xtea_encipher($enc1, $enc2);&lt;br /&gt;
   } while ( $i &amp;lt; $len );&lt;br /&gt;
   return $result; //Return Encrypted string&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /**&lt;br /&gt;
   * Decrypt a full string using XTEA&lt;br /&gt;
   *&lt;br /&gt;
   * @param $str the string to decrypt&lt;br /&gt;
   * @return the decrypted string&lt;br /&gt;
   * @author JB Kraft&lt;br /&gt;
   **/&lt;br /&gt;
  public function decrypt( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   $len = strlen($str);&lt;br /&gt;
   $i = 0;&lt;br /&gt;
   $result = &#039;&#039;;&lt;br /&gt;
   do {&lt;br /&gt;
    $dec1 = $this-&amp;gt;base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
    $i += 6;&lt;br /&gt;
    $dec2 = $this-&amp;gt;base64_integer(substr($str , $i , 6).&amp;quot;==&amp;quot;);&lt;br /&gt;
    $i += 6;&lt;br /&gt;
    $result .= $this-&amp;gt;xtea_decipher( $dec1, $dec2);&lt;br /&gt;
   } while ( $i &amp;lt; $len );&lt;br /&gt;
&lt;br /&gt;
   // Replace multiple trailing zeroes with a single one&lt;br /&gt;
   $i = strlen($result);&lt;br /&gt;
   while ( substr($result, --$i, 1) == &amp;quot;A&amp;quot; );&lt;br /&gt;
   $result = substr($result, 0, $i+1);&lt;br /&gt;
   $i = strlen($result);&lt;br /&gt;
   $mod = $i%4; //Depending on encoded length diffrent appends are needed&lt;br /&gt;
   if($mod == 1) $result .= &amp;quot;A==&amp;quot;;&lt;br /&gt;
   else if($mod == 2 ) $result .= &amp;quot;==&amp;quot;;&lt;br /&gt;
   else if($mod == 3) $result .= &amp;quot;=&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   return base64_decode( $result );&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // -----------------------------&lt;br /&gt;
  // stuff below here is protected&lt;br /&gt;
  // -----------------------------&lt;br /&gt;
&lt;br /&gt;
  // Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)&lt;br /&gt;
  protected function base64_integer($str)&lt;br /&gt;
  {&lt;br /&gt;
   if(strlen($str) != 8) return 0;&lt;br /&gt;
   return ((strpos($this-&amp;gt;_base64,$str{0}) &amp;lt;&amp;lt; 26)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{1}) &amp;lt;&amp;lt; 20)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{2}) &amp;lt;&amp;lt; 14)|&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{3}) &amp;lt;&amp;lt; 8) |&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{4}) &amp;lt;&amp;lt; 2) |&lt;br /&gt;
   (strpos($this-&amp;gt;_base64,$str{5}) &amp;gt;&amp;gt; 4));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)&lt;br /&gt;
  protected function integer_base64($int)&lt;br /&gt;
  {&lt;br /&gt;
   if($int != (integer) $int) return 0;&lt;br /&gt;
   return  $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 26 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 20 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 14 &amp;amp; 0x3F)} .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 8 &amp;amp; 0x3F)}  .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;gt;&amp;gt; 2 &amp;amp; 0x3F)}  .&lt;br /&gt;
   $this-&amp;gt;_base64{($int &amp;lt;&amp;lt; 4 &amp;amp; 0x3F)} . &amp;quot;==&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //strict 32 bit addition using logic&lt;br /&gt;
  protected function binadd($val1 , $val2)&lt;br /&gt;
  {&lt;br /&gt;
   $tc = $val1 &amp;amp; $val2;&lt;br /&gt;
   $ta = $val1 ^ $val2;&lt;br /&gt;
   do{&lt;br /&gt;
    $tac = ($tc &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
    $tc = $ta &amp;amp; $tac;&lt;br /&gt;
    $ta = $ta ^ $tac;&lt;br /&gt;
   }while($tc);&lt;br /&gt;
   return $ta; // $ta will now be the result so return it&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Convers any string to a 32 char MD5 string and then to a list of&lt;br /&gt;
  // 4 * 32 bit integers = 128 bit Key.&lt;br /&gt;
  protected function xtea_key_from_string( $str ) &lt;br /&gt;
  {&lt;br /&gt;
   $str = md5($str . &amp;quot;:0&amp;quot;); // Use nonce = 0 in LSL for same output&lt;br /&gt;
   eval(&amp;quot;\$this-&amp;gt;_xtea_key[0] = 0x&amp;quot; . substr($str,0,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
   eval(&amp;quot;\$this-&amp;gt;_xtea_key[1] = 0x&amp;quot; . substr($str,8,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
   eval(&amp;quot;\$this-&amp;gt;_xtea_key[2] = 0x&amp;quot; . substr($str,16,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
   eval(&amp;quot;\$this-&amp;gt;_xtea_key[3] = 0x&amp;quot; . substr($str,24,8) . &amp;quot;;&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Encipher two integers and return the result as a 12-byte string&lt;br /&gt;
  // containing two base64-encoded integers.&lt;br /&gt;
  protected function xtea_encipher( $v0 , $v1 ) &lt;br /&gt;
  {&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $sum = 0;&lt;br /&gt;
   do {&lt;br /&gt;
    // LSL only has 32 bit integers. However PHP automaticly changes&lt;br /&gt;
    // 32 bit integers to 64 bit floats as nessesary. This causes&lt;br /&gt;
    // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
    // counterpart. I got round this by changing all addition to&lt;br /&gt;
    // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
    // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
    // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
    // encrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
&lt;br /&gt;
    // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
    // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
    // calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    $v0a = $this-&amp;gt;binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
    // calculate ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
    $v0b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
    // Calculate ($v0 + ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    //            ^ ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
    $v0 = $this-&amp;gt;binadd($v0 , ($v0a  ^ $v0b));&lt;br /&gt;
&lt;br /&gt;
    //Calculate ($sum + $this-&amp;gt;_XTEA_DELTA)&lt;br /&gt;
    $sum = $this-&amp;gt;binadd($sum , $this-&amp;gt;_XTEA_DELTA);&lt;br /&gt;
&lt;br /&gt;
    //Calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    $v1a = $this-&amp;gt;binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF))  , $v0);&lt;br /&gt;
    // Calculate ($sum + $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
    $v1b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
    //Calculate ($v1 + ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0&lt;br /&gt;
    //           ^ ($sum &amp;amp; $this-&amp;gt;_xtea_key[($sum &amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
    $v1 = $this-&amp;gt;binadd($v1 , ($v1a  ^ $v1b));&lt;br /&gt;
   } while( $num_rounds = ~-$num_rounds );&lt;br /&gt;
   //return only first 6 chars to remove &amp;quot;==&amp;quot;&#039;s and compact encrypted text.&lt;br /&gt;
   return substr($this-&amp;gt;integer_base64($v0),0,6) . substr($this-&amp;gt;integer_base64($v1),0,6);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Decipher two base64-encoded integers and return the FIRST 30 BITS of&lt;br /&gt;
  // each as one 10-byte base64-encoded string.&lt;br /&gt;
  protected function xtea_decipher( $v0, $v1 ) &lt;br /&gt;
  {&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $sum = 0; // $this-&amp;gt;_XTEA_DELTA * $this-&amp;gt;_xtea_num_rounds;&lt;br /&gt;
   $tda = $this-&amp;gt;_XTEA_DELTA;&lt;br /&gt;
   do{ // Binary multiplication using binary manipulation&lt;br /&gt;
    if($num_rounds &amp;amp; 1){&lt;br /&gt;
     $sum = $this-&amp;gt;binadd($sum , $tda);&lt;br /&gt;
    }&lt;br /&gt;
    $num_rounds = $num_rounds &amp;gt;&amp;gt; 1;&lt;br /&gt;
    $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
   }while($num_rounds);&lt;br /&gt;
   $num_rounds = $this-&amp;gt;_xtea_num_rounds; // reset $num_rounds back to its propper setting;&lt;br /&gt;
&lt;br /&gt;
   do {&lt;br /&gt;
    // LSL only has 32 bit integers. However PHP automaticly changes&lt;br /&gt;
    // 32 bit integers to 64 bit floats as nessesary. This causes&lt;br /&gt;
    // incompatibilities between the LSL Encryption and the PHP&lt;br /&gt;
    // counterpart. I got round this by changing all addition to&lt;br /&gt;
    // binary addition using logical &amp;amp; and ^ and loops to handle bit&lt;br /&gt;
    // carries. This forces the 32 bit integer to remain 32 bits as&lt;br /&gt;
    // I mask out any carry over 32 bits. this bring the output of the&lt;br /&gt;
    // decrypt routine to conform with the output of its LSL counterpart.&lt;br /&gt;
    // Subtrations are handled by using 2&#039;s compliment&lt;br /&gt;
&lt;br /&gt;
    // LSL does not have unsigned integers, so when shifting right we&lt;br /&gt;
    // have to mask out sign-extension bits.&lt;br /&gt;
&lt;br /&gt;
    // calculate ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    $v1a = $this-&amp;gt;binadd((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v0);&lt;br /&gt;
    // calculate ($sum + $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3])&lt;br /&gt;
    $v1b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]);&lt;br /&gt;
    //Calculate 2&#039;s compliment of ($v1a ^ $v1b) for subtraction&lt;br /&gt;
    $v1c = $this-&amp;gt;binadd((~($v1a ^ $v1b)) , 1);&lt;br /&gt;
    //Calculate ($v1 - ((($v0 &amp;lt;&amp;lt; 4) ^ (($v0 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v0)&lt;br /&gt;
    //            ^ ($sum + $this-&amp;gt;_xtea_key[($sum&amp;gt;&amp;gt;11) &amp;amp; 3]))&lt;br /&gt;
    $v1 = $this-&amp;gt;binadd($v1 , $v1c);&lt;br /&gt;
&lt;br /&gt;
    // Calculate new $sum based on $num_rounds - 1&lt;br /&gt;
    $tnr = $num_rounds - 1;  // Temp $num_rounds&lt;br /&gt;
    $sum = 0; // $this-&amp;gt;_XTEA_DELTA * ($num_rounds - 1);&lt;br /&gt;
    $tda = $this-&amp;gt;_XTEA_DELTA;&lt;br /&gt;
    do{ // Binary multiplication using binary manipulation&lt;br /&gt;
     if($tnr &amp;amp; 1){&lt;br /&gt;
      $sum = $this-&amp;gt;binadd($sum , $tda);&lt;br /&gt;
     }&lt;br /&gt;
     $tnr = $tnr &amp;gt;&amp;gt; 1;&lt;br /&gt;
     $tda = ($tda &amp;lt;&amp;lt; 1) &amp;amp; 0x0FFFFFFFF;&lt;br /&gt;
    }while($tnr);&lt;br /&gt;
&lt;br /&gt;
    //Calculate ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1)&lt;br /&gt;
    $v0a = $this-&amp;gt;binadd((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) , $v1);&lt;br /&gt;
    //Calculate ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3])&lt;br /&gt;
    $v0b = $this-&amp;gt;binadd($sum , $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]);&lt;br /&gt;
    //Calculate 2&#039;s compliment of ($v0a ^ $v0b) for subtraction&lt;br /&gt;
    $v0c = $this-&amp;gt;binadd((~($v0a ^ $v0b)) , 1);&lt;br /&gt;
    //Calculate ($v0 - ((($v1 &amp;lt;&amp;lt; 4) ^ (($v1 &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + $v1&lt;br /&gt;
    //           ^ ($sum + $this-&amp;gt;_xtea_key[$sum &amp;amp; 3]))&lt;br /&gt;
    $v0 = $this-&amp;gt;binadd($v0 , $v0c);&lt;br /&gt;
   } while ( $num_rounds = ~-$num_rounds );&lt;br /&gt;
&lt;br /&gt;
   return substr($this-&amp;gt;integer_base64($v0), 0, 5) . substr($this-&amp;gt;integer_base64($v1), 0, 5);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Test Vectors =&lt;br /&gt;
These are test vectors to verify that the implementation is working correctly. Although the LSL implementation is for six rounds only, it can easily be changed to verify that the implementation is working as expected. Having a proper implementation allows other systems to communicate using the LSL implementation of XTEA.&lt;br /&gt;
&lt;br /&gt;
==Bouncy Castle C# API==&lt;br /&gt;
These test vectors are taken from [http://www.bouncycastle.org/csharp/ The Bouncy Castle C# API].&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Rounds&lt;br /&gt;
! Data&lt;br /&gt;
! Key&lt;br /&gt;
! Vector&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0xDEE9D4D8|}} {{LSL Hex|0xF7131ED9|}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x01020304|}} {{LSL Hex|0x05060708|}}&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x065C1B89|}} {{LSL Hex|0x75C6A816|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x00000000|}} {{LSL Hex|0x00000000|}}&lt;br /&gt;
| {{LSL Hex|0x01234567|}} {{LSL Hex|0x12345678|}} {{LSL Hex|0x23456789|}} {{LSL Hex|0x3456789A|}}&lt;br /&gt;
| {{LSL Hex|0x1FF9A026|}} {{LSL Hex|0x1AC64264|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| {{LSL Hex|0x01020304|}} {{LSL Hex|0x05060708|}}&lt;br /&gt;
| {{LSL Hex|0x01234567|}} {{LSL Hex|0x12345678|}} {{LSL Hex|0x23456789|}} {{LSL Hex|0x3456789A|}}&lt;br /&gt;
| {{LSL Hex|0x8C67155B|}} {{LSL Hex|0x2EF91EAD|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Test Vectors for TEA and XTEA==&lt;br /&gt;
These test vectors used are from [http://www.cix.co.uk/~klockstone/teavect.htm Test Vectors for TEA and XTEA].&lt;br /&gt;
They are made by starting with a vector of 6 zeroes, data followed by key, and coding with one cycle then moving the six cyclically so that n becomes n-1 modulo 6.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Round&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|vector&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x9E3779B9|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
||{{LSL Hex|0xEC01A1DE|}}||{{LSL Hex|0xAAA0256D|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
||{{LSL Hex|0xBC3A7DE2|}}||{{LSL Hex|0x4E238EB9|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0x00000000|}}||{{LSL Hex|0xEC01A1DE|}}||{{LSL Hex|0x114F6D74|}}&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
||{{LSL Hex|0x31C5FA6C|}}||{{LSL Hex|0x241756D6|}}||{{LSL Hex|0xBC3A7DE2|}}||{{LSL Hex|0x845846CF|}}||{{LSL Hex|0x2794A127|}}||{{LSL Hex|0x6B8EA8B8|}}&lt;br /&gt;
|-&lt;br /&gt;
| 16&lt;br /&gt;
||{{LSL Hex|0x1D8E6992|}}||{{LSL Hex|0x9A478905|}}||{{LSL Hex|0x6A1D78C8|}}||{{LSL Hex|0x08C86D67|}}||{{LSL Hex|0x2A65BFBE|}}||{{LSL Hex|0xB4BD6E46|}}&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
||{{LSL Hex|0xD26428AF|}}||{{LSL Hex|0x0A202283|}}||{{LSL Hex|0x27F917B1|}}||{{LSL Hex|0xC1DA8993|}}||{{LSL Hex|0x60E2ACAA|}}||{{LSL Hex|0xA6EB923D|}}&lt;br /&gt;
|-&lt;br /&gt;
| 64&lt;br /&gt;
||{{LSL Hex|0x7A01CBC9|}}||{{LSL Hex|0xB03D6068|}}||{{LSL Hex|0x62EE209F|}}||{{LSL Hex|0x069B7AFC|}}||{{LSL Hex|0x376A8936|}}||{{LSL Hex|0xCDC9E923|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==LSL Test==&lt;br /&gt;
The following code has been imported to LSL to test the vectors with an XTEA implementation. It also makes use of a modified version of the [[Hex]] method on this wiki to display the data. Right Shift of signed integers is handed by techniques introduced in the [[Right_Shift]] method on this wiki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// XTEA is a version of slightly improved TEA&lt;br /&gt;
// The plain or cypher text is in v[0], v[1]&lt;br /&gt;
// The key is in k[n], where n = 0 - 3&lt;br /&gt;
// The number of coding cycles is given by N and&lt;br /&gt;
// the number of decoding cycles is given by -N&lt;br /&gt;
&lt;br /&gt;
list XTEA(list v, list k, integer N) // Replaces TEA&#039;s Code and Decode&lt;br /&gt;
{&lt;br /&gt;
    integer y = llList2Integer(v, 0);&lt;br /&gt;
    integer z = llList2Integer(v, 1);&lt;br /&gt;
    integer DELTA = 0x9E3779B9;&lt;br /&gt;
    integer limit = DELTA * N;&lt;br /&gt;
    integer sum = 0;&lt;br /&gt;
    &lt;br /&gt;
    if(N &amp;gt; 0) // encrypt&lt;br /&gt;
    {&lt;br /&gt;
        while(sum != limit)&lt;br /&gt;
        {&lt;br /&gt;
            y   += (z &amp;lt;&amp;lt; 4 ^ ((z &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum &amp;amp; 3);&lt;br /&gt;
            sum += DELTA;&lt;br /&gt;
            z   += (y &amp;lt;&amp;lt; 4 ^ ((y &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // decrypt&lt;br /&gt;
    {&lt;br /&gt;
         for(sum = -limit; sum; )&lt;br /&gt;
         {   z   -= (y &amp;lt;&amp;lt; 4 ^ ((y &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum &amp;gt;&amp;gt; 11) &amp;amp; 3);&lt;br /&gt;
             sum -= DELTA;&lt;br /&gt;
             y   -= (z &amp;lt;&amp;lt; 4 ^ ((z &amp;gt;&amp;gt; 5) &amp;amp; 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum &amp;amp; 3);&lt;br /&gt;
         }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return [y,z];&lt;br /&gt;
}&lt;br /&gt;
string hex(integer value)&lt;br /&gt;
{&lt;br /&gt;
    string h = &amp;quot;&amp;quot;;&lt;br /&gt;
    while (value)&lt;br /&gt;
    {&lt;br /&gt;
        string c = llGetSubString(&amp;quot;0123456789ABCDEF&amp;quot;, value &amp;amp; 0xF, value &amp;amp; 0xF);&lt;br /&gt;
        h = c + h;&lt;br /&gt;
        value = (value &amp;gt;&amp;gt; 4) &amp;amp; 0x0FFFFFFF;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;0x&amp;quot; + llGetSubString(&amp;quot;00000000&amp;quot; + h, -8, -1);&lt;br /&gt;
}&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        // Bouncy Castle C# API Test Vectors&lt;br /&gt;
        list v;&lt;br /&gt;
        v = XTEA([0x00000000, 0x00000000], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0xDEE9D4D8\t0xF7131ED9&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x01020304, 0x05060708], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x065C1B89\t0x75C6A816&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x00000000, 0x00000000], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x1FF9A026\t0x1AC64264&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        v = XTEA([0x01020304, 0x05060708], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);&lt;br /&gt;
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + &amp;quot;\t&amp;quot; + hex(llList2Integer(v, 1)) + &amp;quot;\texpected\t0x8C67155B\t0x2EF91EAD&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Test Vectors for XTEA&lt;br /&gt;
&lt;br /&gt;
        list pz = [0,0,0,0,0,0,0];&lt;br /&gt;
        integer n;&lt;br /&gt;
        for (n = 1; n &amp;lt; 65; n++)&lt;br /&gt;
        {  &lt;br /&gt;
            &lt;br /&gt;
            list a = XTEA(llList2List(pz, n, n + 1), llList2List(pz, n + 2, n + 5), n);&lt;br /&gt;
            &lt;br /&gt;
            pz = llListReplaceList(pz, a, n, n + 1);&lt;br /&gt;
&lt;br /&gt;
            if (n == (n &amp;amp; -n))                         // if n power of 2&lt;br /&gt;
                llSay(DEBUG_CHANNEL, &lt;br /&gt;
                    (string)n &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 0)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 1)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 2))&lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 3)) &lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 4))&lt;br /&gt;
                    + &amp;quot;\t&amp;quot; + hex(llList2Integer(pz, n + 5))&lt;br /&gt;
                );&lt;br /&gt;
            pz = llListReplaceList(pz, llList2List(pz, n, n + 5), n + 6, n + 11);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#vardefine:sort|XTEA Strong Encryption Implementation}}{{LSLC|Library}}{{LSLC|Examples}}&lt;br /&gt;
 [[Category:LSL Encryption]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=ZZText&amp;diff=794822</id>
		<title>ZZText</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=ZZText&amp;diff=794822"/>
		<updated>2010-03-09T09:36:46Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is it ==&lt;br /&gt;
&lt;br /&gt;
Scripting tools to allow display of text on a prim: [[XyText 1.5]] (aka XyText) , [[XyzzyText]], [[XyyyyzText]], [[XyzzyText-UTF8]], [[ZZText]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ZZText&#039;&#039;&#039; is a low-prim, low-lag, international variation of [[XyText]] with the following features:&lt;br /&gt;
* can be enhanced with new fonts or UTF-8 characters using GIMP and python-fu.&lt;br /&gt;
* uses only 35 textures instead of 66 for the 10 chars on prim solution (this gives a bit less quality then the original xytext, but under normal situations is acceptable.&lt;br /&gt;
&lt;br /&gt;
Rationale: if you have problems with prim usage, then you can accept this compromise.&lt;br /&gt;
&lt;br /&gt;
* this particular combination of textures gives something way more rapid than [[XyzzyText]], which is very slow for big boards, and less lagger than [[XyText]].&lt;br /&gt;
* small warning: there is still some slight improvements for this zzText to be reasonably acceptable (consider it in a Beta stage), will post soon when it will be fully acceptable.&lt;br /&gt;
&lt;br /&gt;
== Credits and copyright ==&lt;br /&gt;
ZZText is heavily dependent on [[XyText]] so it shares and extends credits and copyrights.&lt;br /&gt;
&lt;br /&gt;
Also this is a low prim variation of the [[XyzzyText-UTF8]] page but downgraded to use XyText lower quality paradigm instead than the 1 character face approach.&lt;br /&gt;
&lt;br /&gt;
== How to generate the textures ==&lt;br /&gt;
&lt;br /&gt;
* You need to have GIMP 2.0 with python-fu extension installed&lt;br /&gt;
**Here the instructions on windows to do that:&lt;br /&gt;
** Install python 2.6.2 from http://www.python.org/download/, &lt;br /&gt;
** &#039;&#039;&#039;RESTART the PC!!&#039;&#039;&#039;&lt;br /&gt;
** Install gtk+ run time environment from: http://sourceforge.net/project/showfiles.php?group_id=71914&lt;br /&gt;
** &#039;&#039;&#039;&#039;&#039;Install python extensions to graphic libs. Be sure to choose the 2.6.2 python compatibility&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*** Install pycairo from http://ftp.gnome.org/pub/GNOME/binaries/win32/pycairo/&lt;br /&gt;
*** Install pygobject from http://ftp.gnome.org/pub/GNOME/binaries/win32/pygobject/&lt;br /&gt;
*** Install pygtk from http://ftp.acc.umu.se/pub/GNOME/binaries/win32/pygtk/&lt;br /&gt;
** &#039;&#039;&#039;RESTART the PC!!&#039;&#039;&#039;&lt;br /&gt;
** Install gimp 2.6.6 from http://gimp.org/&lt;br /&gt;
** &#039;&#039;&#039;&#039;&#039;Verify launching gimp, filters, python-fu, console to see Python 2.6.2&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
* Use the mega-image maker python-fu script (see following sections)&lt;br /&gt;
* Use the splitter python-fu script to produce 512x512 guides for later splitting&lt;br /&gt;
* Use the filter/web/slice... button to produce 64 slices in png format to retain transparence (from 0-0 to 7-7)&lt;br /&gt;
* Manually remove the empty slices (the i-j where j&amp;gt;i for instance 2-3, 6-7) so you have only 35 images png.&lt;br /&gt;
* Manually convert each png to tga (this is solving some problems with sl uploading regarding transparence)&lt;br /&gt;
* Upload the textures keeping the order 0-0 1-0 1-1 2-0 2-1 2-3 .... until 7-7)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manual parts can be automated by another python-fu, but I was so exhausted with the others that it was ok for me doing manually :)&lt;br /&gt;
&lt;br /&gt;
There is still some fix needed to do on the python-fu script. Currently characters are still a bit unevenly put so that when displaying them&lt;br /&gt;
depending on which couple using we might see some slight asymmetric unbalancing. You can note this only when looking very closely to the chars.&lt;br /&gt;
Whenever I fix myself this problem I will post here.&lt;br /&gt;
&lt;br /&gt;
For those of you who already accept fonts I did last week, look at next sections for the 35 texture UUIDs:&lt;br /&gt;
&lt;br /&gt;
== So how can I use it? ==&lt;br /&gt;
&lt;br /&gt;
* Put the script named ZZText into each prim of your board naming each cell 1000 ---- 1099 as far as you need cells&lt;br /&gt;
* Have a main script doing the following: llMessageLinked(LINK_SET,1040,&amp;quot;çòàùè&amp;quot;,NULL_KEY) to write on cell named 1040&lt;br /&gt;
&lt;br /&gt;
To divide in rows, use simple modulus operations.&lt;br /&gt;
&lt;br /&gt;
== Variation on [[XyText 1.5]] standard script ==&lt;br /&gt;
&lt;br /&gt;
For not being so difficult to follow, I only publish differences between my script and [[XyText 1.5]] so that you might be able to understand better what I did:&lt;br /&gt;
=== Change CHARACTER_GRID with our full permission textures ===&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
list    CHARACTER_GRID  = [&lt;br /&gt;
        &amp;quot;96f4578b-879e-44ae-d223-427cc615f5a4&amp;quot;, // my slice-0-0&lt;br /&gt;
        &amp;quot;eab5360f-6653-593f-b679-69c68b0dd001&amp;quot;, // 1-0&lt;br /&gt;
        &amp;quot;367330be-717a-277d-5205-131cd6ded458&amp;quot;, // 1-1&lt;br /&gt;
        &amp;quot;32046675-6e7e-2425-ce77-69000b0b4d96&amp;quot;, // 2-0&lt;br /&gt;
        &amp;quot;40085901-bde6-2dd4-40cd-b6d48d242997&amp;quot;, // 2-1&lt;br /&gt;
        &amp;quot;205d318b-09b7-7ecc-922e-801c93a546c8&amp;quot;, // 2-2&lt;br /&gt;
        &amp;quot;841e7826-3645-d4f0-d48b-389586dd8e90&amp;quot;, // 3-0&lt;br /&gt;
        &amp;quot;e2db78c5-fb47-d767-4744-8cb6d84610d0&amp;quot;, // 3-1&lt;br /&gt;
        &amp;quot;15312c89-afd4-854c-9d9b-5b9e11844aed&amp;quot;, // 3-2&lt;br /&gt;
        &amp;quot;d180e771-0393-d09b-8cac-0af6d550ae4a&amp;quot;, // 3-3&lt;br /&gt;
        &amp;quot;c6c1d2c8-5dfd-b13a-7f1e-c3ede8126769&amp;quot;, // 4-0&lt;br /&gt;
        &amp;quot;bc100d0c-a445-947f-caa4-285d9cc8a9de&amp;quot;, // 4-1&lt;br /&gt;
        &amp;quot;0b31e862-75a4-9ed3-6331-e9e700a0fedb&amp;quot;, // 4-2&lt;br /&gt;
        &amp;quot;0eacc306-6bd5-ab31-de47-c686141a6733&amp;quot;, // 4-3&lt;br /&gt;
        &amp;quot;b68de1d9-4890-74a0-4d25-d4d5c83a0dba&amp;quot;, // 4-4&lt;br /&gt;
        &amp;quot;04b2bf9b-a8bb-0a39-1062-9b005229eba9&amp;quot;, // 5-0&lt;br /&gt;
        &amp;quot;be293f10-25ec-beb9-738b-fe1892b82aef&amp;quot;, // 5-1&lt;br /&gt;
        &amp;quot;5e9c8317-71f5-f073-76ab-7c412d3acb84&amp;quot;, // 5-2&lt;br /&gt;
        &amp;quot;030b441b-9022-2aba-f7a7-af6810c354b8&amp;quot;, // 5-3&lt;br /&gt;
        &amp;quot;9f455858-8ae6-3a9a-c2d4-bc5ee92430ac&amp;quot;, // 5-4&lt;br /&gt;
        &amp;quot;ee741143-f01e-f730-667e-66a3cd57d1cc&amp;quot;, // 5-5&lt;br /&gt;
        &amp;quot;710282bc-bd80-5a44-6987-0c4c11a4c294&amp;quot;, // 6-0&lt;br /&gt;
        &amp;quot;c9c410db-675a-1e98-4107-debd3c73a754&amp;quot;, // 6-1&lt;br /&gt;
        &amp;quot;486c2336-71c5-b962-266c-838a865c067c&amp;quot;, // 6-2&lt;br /&gt;
        &amp;quot;d4722155-0b6d-3673-0208-a727729bc117&amp;quot;, // 6-3&lt;br /&gt;
        &amp;quot;bc7af3cd-ee48-08df-fe8b-a6ca8a425733&amp;quot;, // 6-4&lt;br /&gt;
        &amp;quot;f23d7a73-00c3-1ffd-69a7-0cca031c939d&amp;quot;, // 6-5&lt;br /&gt;
        &amp;quot;aa95bfd1-ac80-f962-7acf-d6aeed9c7e81&amp;quot;, // 6-6&lt;br /&gt;
        &amp;quot;53fd52e3-0e8b-dcc8-42f8-332aef421bd2&amp;quot;, // 7-0&lt;br /&gt;
        &amp;quot;da3f6f09-3e3a-e156-8e2e-1040111a5635&amp;quot;, // 7-1&lt;br /&gt;
        &amp;quot;409a95c0-b685-2036-d0de-75e8ab654243&amp;quot;, // 7-2&lt;br /&gt;
        &amp;quot;14e05aca-3a61-b892-3632-dcde72324779&amp;quot;, // 7-3&lt;br /&gt;
        &amp;quot;546c0e4f-b678-895d-2035-0f39bb7f4979&amp;quot;, // 7-4&lt;br /&gt;
        &amp;quot;cf2fc337-109f-ba25-8ff5-786f7d6ceb5b&amp;quot;, // 7-5&lt;br /&gt;
        &amp;quot;9943204b-a4de-868a-3cdd-8785d1864ede&amp;quot;, // 7-6&lt;br /&gt;
        &amp;quot;765cfd9c-9703-b5ba-2c5d-f1c8bd44e0f4&amp;quot;  // 7-7&lt;br /&gt;
          ];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enabling answering to only a specific channel instead of DISPLAY_STRING channel ===&lt;br /&gt;
This heavily helps in producing multi cell boards:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
integer ME;&lt;br /&gt;
....&lt;br /&gt;
state_entry(){&lt;br /&gt;
....&lt;br /&gt;
 ME=(integer)llGetObjectName(); // need that each cell has its own number as object name starting from 1000 for instance&lt;br /&gt;
....&lt;br /&gt;
// be sure we are answering only to channel ME&lt;br /&gt;
link_message(integer sender, integer channel, string data, key id) {&lt;br /&gt;
        if (channel == (ME) {&lt;br /&gt;
            RenderString(data);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UTF-8 character specification ===&lt;br /&gt;
This must closely match what you produced with python-fu&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ResetCharIndex() {&lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;;&lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug.&lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
  //        cap cedille      u:         e/            a^         a:          a/         a ring      cedille     e^           e:&lt;br /&gt;
  decode=  [&amp;quot;%C3%87&amp;quot;, &amp;quot;%C3%BC&amp;quot;, &amp;quot;%C3%A9&amp;quot;, &amp;quot;%C3%A2&amp;quot;, &amp;quot;%C3%A4&amp;quot;, &amp;quot;%C3%A0&amp;quot;, &amp;quot;%C3%A5&amp;quot;, &amp;quot;%C3%A7&amp;quot;, &amp;quot;%C3%AA&amp;quot;, &amp;quot;%C3%AB&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
  //                    e\           i:               i^            i\                A:          A ring          E/              ae           AE           marker &amp;gt;&lt;br /&gt;
       &amp;quot;%C3%A8&amp;quot;, &amp;quot;%C3%AF&amp;quot;, &amp;quot;%C3%AE&amp;quot;, &amp;quot;%C3%AC&amp;quot;, &amp;quot;%C3%84&amp;quot;, &amp;quot;%C3%85&amp;quot;, &amp;quot;%C3%89&amp;quot;, &amp;quot;%C3%A6&amp;quot;, &amp;quot;%C3%86&amp;quot;, &amp;quot;%E2%96%B6&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
  //                 o:               o/           u^          u\              y:               O:             U:          cent           pound        yen&lt;br /&gt;
       &amp;quot;%C3%B6&amp;quot;, &amp;quot;%C3%B2&amp;quot;, &amp;quot;%C3%BB&amp;quot;, &amp;quot;%C3%B9&amp;quot;, &amp;quot;%C3%BF&amp;quot;, &amp;quot;%C3%96&amp;quot;, &amp;quot;%C3%9C&amp;quot;, &amp;quot;%C2%A2&amp;quot;, &amp;quot;%C2%A3&amp;quot;, &amp;quot;%C2%A5&amp;quot;,&lt;br /&gt;
   &lt;br /&gt;
  //                 A^              a/              i/                o/            u/              n~           E:            y/              inv ?         O^&lt;br /&gt;
       &amp;quot;%C3%82&amp;quot;, &amp;quot;%C3%A1&amp;quot;, &amp;quot;%C3%AD&amp;quot;, &amp;quot;%C3%B3&amp;quot;, &amp;quot;%C3%BA&amp;quot;, &amp;quot;%C3%B1&amp;quot;, &amp;quot;%C3%8B&amp;quot;, &amp;quot;%C3%BD&amp;quot;, &amp;quot;%C2%BF&amp;quot;, &amp;quot;%C3%94&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  //                   inv !             I\             I/           degree       E^              I^            o^            U^&lt;br /&gt;
       &amp;quot;%C2%A1&amp;quot;, &amp;quot;%C3%8C&amp;quot;, &amp;quot;%C3%8D&amp;quot;, &amp;quot;%C2%B0&amp;quot;, &amp;quot;%C3%8A&amp;quot;, &amp;quot;%C3%8E&amp;quot;, &amp;quot;%C3%B4&amp;quot;, &amp;quot;%C3%9B&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  //                     Y:          euro           german ss         E\              A\           A/              U\           U/               O\           O/&lt;br /&gt;
       &amp;quot;%C3%9D&amp;quot;, &amp;quot;%E2%82%AC&amp;quot;, &amp;quot;%C3%9F&amp;quot;, &amp;quot;%C3%88&amp;quot;, &amp;quot;%C3%80&amp;quot;, &amp;quot;%C3%81&amp;quot;, &amp;quot;%C3%99&amp;quot;, &amp;quot;%C3%9A&amp;quot;, &amp;quot;%C3%92&amp;quot;, &amp;quot;%C3%93&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  //                   Sv           sv             zv             Zv              Y:             I:&lt;br /&gt;
       &amp;quot;%C5%A0&amp;quot;, &amp;quot;%C5%A1&amp;quot;, &amp;quot;%C5%BE&amp;quot;, &amp;quot;%C5%BD&amp;quot;, &amp;quot;%C3%9D&amp;quot;, &amp;quot;%C3%8C&amp;quot; ];&lt;br /&gt;
     &lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Accessing the new characters from textures ===&lt;br /&gt;
This is the most difficult part. Still need to clean up offsets, since now they are still a bit wrong.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
vector GetGridOffset(vector grid_pos) {&lt;br /&gt;
    // Zoom in on the texture showing our character pair.&lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 40; // PK was 20&lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 20; // PK was 10&lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture.&lt;br /&gt;
    return &amp;lt;-0.45 + 0.025 * Col, 0.45 - 0.05 * Row, 0.0&amp;gt;; // PK was 0.05 and 0.1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) {&lt;br /&gt;
   // Set the primitive textures directly.&lt;br /&gt;
     &lt;br /&gt;
               &lt;br /&gt;
   llSetPrimitiveParams( [&lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.125, 0.05, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.0375-0.025-0.002, 0.025, 0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.05, 0.05, 0&amp;gt;, GetGridOffset(grid_pos2)+&amp;lt;-0.025-0.002, 0.025,0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-0.74, 0.05, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;-.34-0.002, 0.025, 0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.05, 0.05, 0&amp;gt;, GetGridOffset(grid_pos4)+&amp;lt;-0.025-0.002, 0.025,0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.125, 0.05, 0&amp;gt;, GetGridOffset(grid_pos5) + &amp;lt;0.0375-0.025-0.077-0.002, 0.025, 0&amp;gt;, 0.0&lt;br /&gt;
//        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0,&lt;br /&gt;
//        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0,&lt;br /&gt;
//        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0,&lt;br /&gt;
//        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0,&lt;br /&gt;
//        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0&lt;br /&gt;
        &lt;br /&gt;
        ]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer GetIndex(string char)&lt;br /&gt;
{&lt;br /&gt;
    integer  ret=llSubStringIndex(gCharIndex, char);&lt;br /&gt;
    if(ret&amp;gt;=0) return ret;&lt;br /&gt;
    &lt;br /&gt;
    // special char do nice trick :)&lt;br /&gt;
    string escaped=llEscapeURL(char);&lt;br /&gt;
    &lt;br /&gt;
    if(escaped==&amp;quot;%E2%80%99&amp;quot;) return 7; // remap ’&lt;br /&gt;
    //llSay(0,&amp;quot;Looking for &amp;quot;+escaped);&lt;br /&gt;
    integer found=llListFindList(decode, [escaped]);&lt;br /&gt;
    &lt;br /&gt;
    // not found&lt;br /&gt;
    if(found&amp;lt;0) return 0;&lt;br /&gt;
    &lt;br /&gt;
    // return correct index&lt;br /&gt;
    return llStringLength(gCharIndex)+found;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters.&lt;br /&gt;
    vector GridPos1 = GetGridPos( GetIndex(llGetSubString(str, 0, 0)),&lt;br /&gt;
                                  GetIndex(llGetSubString(str, 1, 1)) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( GetIndex(llGetSubString(str, 2, 2)),&lt;br /&gt;
                                  GetIndex(llGetSubString(str, 3, 3)) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( GetIndex(llGetSubString(str, 4, 4)),&lt;br /&gt;
                                  GetIndex(llGetSubString(str, 5, 5)) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( GetIndex(llGetSubString(str, 6, 6)),&lt;br /&gt;
                                  GetIndex(llGetSubString(str, 7, 7)) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( GetIndex(llGetSubString(str, 8, 8)),&lt;br /&gt;
                                  GetIndex(llGetSubString(str, 9, 9)) );                                   &lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Splitter python-fu script ==&lt;br /&gt;
You need to put this under the %USERPROFILE%\.gimp-2.6\plug-ins folder (in my case: \Documents and Settings\salahzar.SALAHZAR-PC\.gimp-2.6\plug-ins).&lt;br /&gt;
&lt;br /&gt;
To avoid problems with indents, spaces and tabs create the file with explorer guides.py and right clich use the IDLE edit to past the following source.&lt;br /&gt;
&lt;br /&gt;
Note: you need to restart GIMP to see it working.&lt;br /&gt;
&lt;br /&gt;
When running it is very simple just tell it &amp;quot;512&amp;quot; to split every 512 points.&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
&lt;br /&gt;
import math&lt;br /&gt;
from gimpfu import *&lt;br /&gt;
&lt;br /&gt;
def python_guides(timg, tdrawable, interval=100):&lt;br /&gt;
    timg.undo_group_start()&lt;br /&gt;
    for x in range(0, timg.width, interval):&lt;br /&gt;
       timg.add_vguide(x)&lt;br /&gt;
       &lt;br /&gt;
    for y in range(0, timg.height, interval):&lt;br /&gt;
       timg.add_hguide(y)&lt;br /&gt;
       &lt;br /&gt;
    timg.undo_group_end()&lt;br /&gt;
    &lt;br /&gt;
    gimp.displays_flush()&lt;br /&gt;
&lt;br /&gt;
register(&lt;br /&gt;
        &amp;quot;python_fu_guides&amp;quot;,&lt;br /&gt;
        &amp;quot;Guides: this will split the images in sections...&amp;quot;,&lt;br /&gt;
        &amp;quot;Guides: this will split the images in sections...&amp;quot;,&lt;br /&gt;
        &amp;quot;Salahzar Stenvaag&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        &amp;quot;2008&amp;quot;,&lt;br /&gt;
        &amp;quot;&amp;lt;Image&amp;gt;/Filters/Guides...&amp;quot;,&lt;br /&gt;
        &amp;quot;RGB*, GRAY*&amp;quot;,&lt;br /&gt;
        [&lt;br /&gt;
                (PF_INT, &amp;quot;interval&amp;quot;, &amp;quot;Interval&amp;quot;, 100)&lt;br /&gt;
        ],&lt;br /&gt;
        [],&lt;br /&gt;
        python_guides)&lt;br /&gt;
&lt;br /&gt;
main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the guides.py script is correctly installed you will see the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-utf8-Guides.jpg]]&lt;br /&gt;
&lt;br /&gt;
Options to choose:&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Guides2.jpg]]&lt;br /&gt;
&lt;br /&gt;
And the image with the lines in blue:&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Guides3.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Mega-image maker python-fu script ==&lt;br /&gt;
You need to put this under the %USERPROFILE%\.gimp-2.6\plug-ins folder (in my case: \Documents and Settings\salahzar.SALAHZAR-PC\.gimp-2.6\plug-ins).&lt;br /&gt;
&lt;br /&gt;
To avoid problems with indents, spaces and tabs create the file with explorer megaimages.py and right clich use the IDLE edit to past the following source.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you need your characters you need to change the UTF-8 codings in &amp;quot;decode&amp;quot; var&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#! /usr/bin/env python&lt;br /&gt;
from gimpfu import *&lt;br /&gt;
&lt;br /&gt;
# you can remove logging, I used it to be sure program was working since it can be a bit slow &lt;br /&gt;
# to generate all the combination&lt;br /&gt;
def python_log_init():&lt;br /&gt;
    fileHandle = open( &#039;python.log&#039;, &#039;w&#039;)&lt;br /&gt;
    fileHandle.close()&lt;br /&gt;
    &lt;br /&gt;
def python_log(s):&lt;br /&gt;
    fileHandle = open ( &#039;python.log&#039;, &#039;a&#039; )&lt;br /&gt;
    fileHandle.write(str(s)+&amp;quot;\n&amp;quot;)&lt;br /&gt;
    fileHandle.close() &lt;br /&gt;
&lt;br /&gt;
def python_xytext2(font,color,size,limit):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Print the arguments on standard output&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  python_log_init()&lt;br /&gt;
  python_log(&amp;quot;font: %s color: &amp;lt;%d,%d,%d&amp;gt; size: %d limit: %d&amp;quot; % ( font, color[0], color[1], color[2], size, limit ))&lt;br /&gt;
  chars = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  # &lt;br /&gt;
  &lt;br /&gt;
  #        cap cedille      u:         e/            a^         a:          a/         a ring      cedille     e^           e:&lt;br /&gt;
  decode=  [&amp;quot;\xC3\x87&amp;quot;, &amp;quot;\xC3\xBC&amp;quot;, &amp;quot;\xC3\xA9&amp;quot;, &amp;quot;\xC3\xA2&amp;quot;, &amp;quot;\xC3\xA4&amp;quot;, &amp;quot;\xC3\xA0&amp;quot;, &amp;quot;\xC3\xA5&amp;quot;, &amp;quot;\xC3\xA7&amp;quot;, &amp;quot;\xC3\xAA&amp;quot;, &amp;quot;\xC3\xAB&amp;quot; ]  &lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
  #                    e\           i:               i^            i\                A:          A ring          E/              ae           AE           marker &amp;gt;&lt;br /&gt;
  decode+=[&amp;quot;\xC3\xA8&amp;quot;, &amp;quot;\xC3\xAF&amp;quot;, &amp;quot;\xC3\xAE&amp;quot;, &amp;quot;\xC3\xAC&amp;quot;, &amp;quot;\xC3\x84&amp;quot;, &amp;quot;\xC3\x85&amp;quot;, &amp;quot;\xC3\x89&amp;quot;, &amp;quot;\xC3\xA6&amp;quot;, &amp;quot;\xC3\x86&amp;quot;, &amp;quot;\xE2\x96\xB6&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
  #                 o:               o/           u^          u\              y:               O:             U:          cent           pound        yen&lt;br /&gt;
  decode+=[&amp;quot;\xC3\xB6&amp;quot;, &amp;quot;\xC3\xB2&amp;quot;, &amp;quot;\xC3\xBB&amp;quot;, &amp;quot;\xC3\xB9&amp;quot;, &amp;quot;\xC3\xBF&amp;quot;, &amp;quot;\xC3\x96&amp;quot;, &amp;quot;\xC3\x9C&amp;quot;, &amp;quot;\xC2\xA2&amp;quot;, &amp;quot;\xC2\xA3&amp;quot;, &amp;quot;\xC2\xA5&amp;quot;]&lt;br /&gt;
   &lt;br /&gt;
  #                 A^              a/              i/                o/            u/              n~           E:            y/              inv ?         O^&lt;br /&gt;
  decode+=[&amp;quot;\xC3\x82&amp;quot;, &amp;quot;\xC3\xA1&amp;quot;, &amp;quot;\xC3\xAD&amp;quot;, &amp;quot;\xC3\xB3&amp;quot;, &amp;quot;\xC3\xBA&amp;quot;, &amp;quot;\xC3\xB1&amp;quot;, &amp;quot;\xC3\x8B&amp;quot;, &amp;quot;\xC3\xBD&amp;quot;, &amp;quot;\xC2\xBF&amp;quot;, &amp;quot;\xC3\x94&amp;quot; ] &lt;br /&gt;
&lt;br /&gt;
  #                   inv !             I\             I/           degree       E^              I^            o^            U^&lt;br /&gt;
  decode+=[&amp;quot;\xC2\xA1&amp;quot;, &amp;quot;\xC3\x8C&amp;quot;, &amp;quot;\xC3\x8D&amp;quot;, &amp;quot;\xC2\xB0&amp;quot;, &amp;quot;\xC3\x8A&amp;quot;, &amp;quot;\xC3\x8E&amp;quot;, &amp;quot;\xC3\xB4&amp;quot;, &amp;quot;\xC3\x9B&amp;quot; ]&lt;br /&gt;
&lt;br /&gt;
  #                     Y:          euro           german ss         E\              A\           A/              U\           U/               O\           O/&lt;br /&gt;
  decode+=[&amp;quot;\xC3\x9D&amp;quot;, &amp;quot;\xE2\x82\xAC&amp;quot;, &amp;quot;\xC3\x9F&amp;quot;, &amp;quot;\xC3\x88&amp;quot;, &amp;quot;\xC3\x80&amp;quot;, &amp;quot;\xC3\x81&amp;quot;, &amp;quot;\xC3\x99&amp;quot;, &amp;quot;\xC3\x9A&amp;quot;, &amp;quot;\xC3\x92&amp;quot;, &amp;quot;\xC3\x93&amp;quot;   ]                  &lt;br /&gt;
&lt;br /&gt;
  #                   Sv           sv             zv             Zv              Y:             I:&lt;br /&gt;
  decode+=[ &amp;quot;\xC5\xA0&amp;quot;, &amp;quot;\xC5\xA1&amp;quot;, &amp;quot;\xC5\xBE&amp;quot;, &amp;quot;\xC5\xBD&amp;quot;, &amp;quot;\xC3\x9D&amp;quot;, &amp;quot;\xC3\x8C&amp;quot; ]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  width=5120&lt;br /&gt;
  height=5120&lt;br /&gt;
  img = gimp.Image(width, height, RGB)&lt;br /&gt;
  layer = gimp.Layer(img, &amp;quot;my font&amp;quot;, width, height, RGB_IMAGE, 100, NORMAL_MODE)&lt;br /&gt;
  img.add_layer(layer, 0)&lt;br /&gt;
  layer.add_alpha()&lt;br /&gt;
  gimp.set_foreground(color)&lt;br /&gt;
  pdb.gimp_selection_all(img)&lt;br /&gt;
  pdb.gimp_edit_clear(layer)&lt;br /&gt;
  pdb.gimp_selection_none(img)&lt;br /&gt;
  size= 20 # 23 # 21.3 # 30&lt;br /&gt;
  &lt;br /&gt;
  index=0&lt;br /&gt;
  numtot=len(chars)+len(decode)&lt;br /&gt;
  #numtot=50&lt;br /&gt;
  if limit&amp;gt;0: numtot=limit&lt;br /&gt;
  deltay=12.8 # 13.8215 # 12.8 # 18&lt;br /&gt;
  deltax=25.6 # 27.6432 # 25.6 # 36&lt;br /&gt;
  maxchars=len(chars)&lt;br /&gt;
  for first in range(numtot):&lt;br /&gt;
  &lt;br /&gt;
     if first&amp;lt;maxchars: &lt;br /&gt;
        el1=chars[first]&lt;br /&gt;
     else:&lt;br /&gt;
        el1=decode[first-maxchars]&lt;br /&gt;
     &lt;br /&gt;
     python_log(str(first)+&amp;quot;/&amp;quot;+str(numtot)+&amp;quot;:  &amp;quot;+el1)&lt;br /&gt;
     for second in range(first+1):&lt;br /&gt;
&lt;br /&gt;
          # to save time removed function call&lt;br /&gt;
          if second&amp;lt;maxchars: &lt;br /&gt;
             el2=chars[second]&lt;br /&gt;
          else:&lt;br /&gt;
             el2=decode[second-maxchars]&lt;br /&gt;
                 &lt;br /&gt;
          y=second * deltay * 2 # horizontal distance&lt;br /&gt;
          x=first*deltax # line distance&lt;br /&gt;
          pdb.gimp_text_fontname(img,layer,y,x,el1,0,TRUE,size,PIXELS,font)&lt;br /&gt;
          pdb.gimp_text_fontname(img,layer,y+deltay,x,el2,0,TRUE,size,PIXELS,font)&lt;br /&gt;
          &lt;br /&gt;
          index+=1&lt;br /&gt;
          &lt;br /&gt;
  &lt;br /&gt;
  # Now ready to display this image&lt;br /&gt;
  img.merge_visible_layers(0)&lt;br /&gt;
  gimp.Display(img)&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
register(&lt;br /&gt;
  &amp;quot;xytext2&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;&amp;lt;Toolbox&amp;gt;/Xtns/_MegaImage&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
  [&lt;br /&gt;
  (PF_FONT, &amp;quot;font&amp;quot;, &amp;quot;Font to use&amp;quot;, &amp;quot;Arial&amp;quot;),&lt;br /&gt;
  (PF_COLOR,&amp;quot;color&amp;quot;,&amp;quot;Color to use&amp;quot;, (255,255,255) ),&lt;br /&gt;
  (PF_INT,    &amp;quot;size&amp;quot;, &amp;quot;Font size&amp;quot;, 45          ),&lt;br /&gt;
  (PF_INT,  &amp;quot;limit&amp;quot;, &amp;quot;limit font generation &amp;quot;, 0  ),&lt;br /&gt;
 &lt;br /&gt;
  ],&lt;br /&gt;
  [],&lt;br /&gt;
  python_xytext2&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
main()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here how the menu should appear:&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Megaimagechoose.jpg]]&lt;br /&gt;
&lt;br /&gt;
How to launch it: &#039;&#039;&#039;Note!! DON&#039;T USE PROPORTIONAL CHARACTERS!!! BUT MONOSPACE 43 MIGHT BE BETTER&#039;&#039;&#039;&lt;br /&gt;
Also when checking use the limit font generation to 10: the computing process for all 200 characters is VEEERY LOOONG!!!! 0 means all the characters.&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Megaimage2.jpg]]&lt;br /&gt;
&lt;br /&gt;
How to zoom on the megaimage (Zoom 100%) and check produced characters:&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Zoom11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you see the default is producing BAD characters.. Proportional cannot be used since characters cannot be computed with xytext optimized algorithm.&lt;br /&gt;
&lt;br /&gt;
[[Image:XyText-UTF8-Zoom2.jpg]]&lt;br /&gt;
&lt;br /&gt;
== What if I want the full script? ==&lt;br /&gt;
Here you are:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// ZZText (5 Face, Multi Texture)&lt;br /&gt;
//&lt;br /&gt;
// Originally Written by Xylor Baysklef&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon January 20, 2006&lt;br /&gt;
// Added Support for 5 Face Prim, based on modification&lt;br /&gt;
// of XyText v1.1.1 by Kermitt Quick for Single Texture.&lt;br /&gt;
//&lt;br /&gt;
// Modified by Salahzar Stenvaag for International and new textures&lt;br /&gt;
// produced with GIMP. See wiki page ZZText for further info&lt;br /&gt;
// Obtain ME (starting linking channel from Object name)&lt;br /&gt;
// thane can use all the other commands&lt;br /&gt;
// IDEAL for linked structures&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS ///////////////////&lt;br /&gt;
// XyText Message Map.&lt;br /&gt;
integer DISPLAY_STRING      = 0;&lt;br /&gt;
integer DISPLAY_EXTENDED    = 100;&lt;br /&gt;
integer REMAP_INDICES       = 200;&lt;br /&gt;
integer RESET_INDICES       = 300;&lt;br /&gt;
integer SET_CELL_INFO       = 400;&lt;br /&gt;
integer SET_THICKNESS       = 600;&lt;br /&gt;
integer SET_COLOR           = 700;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence.&lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character.&lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Face numbers.&lt;br /&gt;
integer FACE_1          = 3;&lt;br /&gt;
integer FACE_2          = 7;&lt;br /&gt;
integer FACE_3          = 4;&lt;br /&gt;
integer FACE_4          = 6;&lt;br /&gt;
integer FACE_5          = 1;&lt;br /&gt;
&lt;br /&gt;
list decode=[]; // to handle special characters from CP850 page for european countries&lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out.&lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;;&lt;br /&gt;
// This is a list of textures for all 2-character combinations.&lt;br /&gt;
list    CHARACTER_GRID  = [&lt;br /&gt;
    &amp;quot;96f4578b-879e-44ae-d223-427cc615f5a4&amp;quot;, // my slice-0-0&lt;br /&gt;
    &amp;quot;eab5360f-6653-593f-b679-69c68b0dd001&amp;quot;, // 1-0&lt;br /&gt;
    &amp;quot;367330be-717a-277d-5205-131cd6ded458&amp;quot;, // 1-1&lt;br /&gt;
    &amp;quot;32046675-6e7e-2425-ce77-69000b0b4d96&amp;quot;, // 2-0&lt;br /&gt;
    &amp;quot;40085901-bde6-2dd4-40cd-b6d48d242997&amp;quot;, // 2-1&lt;br /&gt;
    &amp;quot;205d318b-09b7-7ecc-922e-801c93a546c8&amp;quot;, // 2-2&lt;br /&gt;
    &amp;quot;841e7826-3645-d4f0-d48b-389586dd8e90&amp;quot;, // 3-0&lt;br /&gt;
    &amp;quot;e2db78c5-fb47-d767-4744-8cb6d84610d0&amp;quot;, // 3-1&lt;br /&gt;
    &amp;quot;15312c89-afd4-854c-9d9b-5b9e11844aed&amp;quot;, // 3-2&lt;br /&gt;
    &amp;quot;d180e771-0393-d09b-8cac-0af6d550ae4a&amp;quot;, // 3-3&lt;br /&gt;
    &amp;quot;c6c1d2c8-5dfd-b13a-7f1e-c3ede8126769&amp;quot;, // 4-0&lt;br /&gt;
    &amp;quot;bc100d0c-a445-947f-caa4-285d9cc8a9de&amp;quot;, // 4-1&lt;br /&gt;
    &amp;quot;0b31e862-75a4-9ed3-6331-e9e700a0fedb&amp;quot;, // 4-2&lt;br /&gt;
    &amp;quot;0eacc306-6bd5-ab31-de47-c686141a6733&amp;quot;, // 4-3&lt;br /&gt;
    &amp;quot;b68de1d9-4890-74a0-4d25-d4d5c83a0dba&amp;quot;, // 4-4&lt;br /&gt;
    &amp;quot;04b2bf9b-a8bb-0a39-1062-9b005229eba9&amp;quot;, // 5-0&lt;br /&gt;
    &amp;quot;be293f10-25ec-beb9-738b-fe1892b82aef&amp;quot;, // 5-1&lt;br /&gt;
    &amp;quot;5e9c8317-71f5-f073-76ab-7c412d3acb84&amp;quot;, // 5-2&lt;br /&gt;
    &amp;quot;030b441b-9022-2aba-f7a7-af6810c354b8&amp;quot;, // 5-3&lt;br /&gt;
    &amp;quot;9f455858-8ae6-3a9a-c2d4-bc5ee92430ac&amp;quot;, // 5-4&lt;br /&gt;
    &amp;quot;ee741143-f01e-f730-667e-66a3cd57d1cc&amp;quot;, // 5-5&lt;br /&gt;
    &amp;quot;710282bc-bd80-5a44-6987-0c4c11a4c294&amp;quot;, // 6-0&lt;br /&gt;
    &amp;quot;c9c410db-675a-1e98-4107-debd3c73a754&amp;quot;, // 6-1&lt;br /&gt;
    &amp;quot;486c2336-71c5-b962-266c-838a865c067c&amp;quot;, // 6-2&lt;br /&gt;
    &amp;quot;d4722155-0b6d-3673-0208-a727729bc117&amp;quot;, // 6-3&lt;br /&gt;
    &amp;quot;bc7af3cd-ee48-08df-fe8b-a6ca8a425733&amp;quot;, // 6-4&lt;br /&gt;
    &amp;quot;f23d7a73-00c3-1ffd-69a7-0cca031c939d&amp;quot;, // 6-5&lt;br /&gt;
    &amp;quot;aa95bfd1-ac80-f962-7acf-d6aeed9c7e81&amp;quot;, // 6-6&lt;br /&gt;
    &amp;quot;53fd52e3-0e8b-dcc8-42f8-332aef421bd2&amp;quot;, // 7-0&lt;br /&gt;
    &amp;quot;da3f6f09-3e3a-e156-8e2e-1040111a5635&amp;quot;, // 7-1&lt;br /&gt;
    &amp;quot;409a95c0-b685-2036-d0de-75e8ab654243&amp;quot;, // 7-2&lt;br /&gt;
    &amp;quot;14e05aca-3a61-b892-3632-dcde72324779&amp;quot;, // 7-3&lt;br /&gt;
    &amp;quot;546c0e4f-b678-895d-2035-0f39bb7f4979&amp;quot;, // 7-4&lt;br /&gt;
    &amp;quot;cf2fc337-109f-ba25-8ff5-786f7d6ceb5b&amp;quot;, // 7-5&lt;br /&gt;
    &amp;quot;9943204b-a4de-868a-3cdd-8785d1864ede&amp;quot;, // 7-6&lt;br /&gt;
    &amp;quot;765cfd9c-9703-b5ba-2c5d-f1c8bd44e0f4&amp;quot;  // 7-7&lt;br /&gt;
        ];&lt;br /&gt;
integer ME;&lt;br /&gt;
///////////// END CONSTANTS ////////////////&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES ///////////////&lt;br /&gt;
// All displayable characters.  Default to ASCII order.&lt;br /&gt;
string gCharIndex;&lt;br /&gt;
// This is the channel to listen on while acting&lt;br /&gt;
// as a cell in a larger display.&lt;br /&gt;
integer gCellChannel      = -1;&lt;br /&gt;
// This is the starting character position in the cell channel message&lt;br /&gt;
// to render.&lt;br /&gt;
integer gCellCharPosition = 0;&lt;br /&gt;
// This is whether or not to use the fade in/out special effect.&lt;br /&gt;
integer gCellUseFading      = FALSE;&lt;br /&gt;
// This is how long to display the text before fading out (if using&lt;br /&gt;
// fading special effect).&lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out.&lt;br /&gt;
float   gCellHoldDelay      = 1.0;&lt;br /&gt;
/////////// END GLOBAL VARIABLES ////////////&lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() {&lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;;&lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug.&lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;;&lt;br /&gt;
    //        cap cedille      u:         e/            a^         a:          a/         a ring      cedille     e^           e:&lt;br /&gt;
    decode=  [&amp;quot;%C3%87&amp;quot;, &amp;quot;%C3%BC&amp;quot;, &amp;quot;%C3%A9&amp;quot;, &amp;quot;%C3%A2&amp;quot;, &amp;quot;%C3%A4&amp;quot;, &amp;quot;%C3%A0&amp;quot;, &amp;quot;%C3%A5&amp;quot;, &amp;quot;%C3%A7&amp;quot;, &amp;quot;%C3%AA&amp;quot;, &amp;quot;%C3%AB&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //                    e\           i:               i^            i\                A:          A ring          E/              ae           AE           marker &amp;gt;&lt;br /&gt;
        &amp;quot;%C3%A8&amp;quot;, &amp;quot;%C3%AF&amp;quot;, &amp;quot;%C3%AE&amp;quot;, &amp;quot;%C3%AC&amp;quot;, &amp;quot;%C3%84&amp;quot;, &amp;quot;%C3%85&amp;quot;, &amp;quot;%C3%89&amp;quot;, &amp;quot;%C3%A6&amp;quot;, &amp;quot;%C3%86&amp;quot;, &amp;quot;%E2%96%B6&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
        //                 o:               o/           u^          u\              y:               O:             U:          cent           pound        yen&lt;br /&gt;
        &amp;quot;%C3%B6&amp;quot;, &amp;quot;%C3%B2&amp;quot;, &amp;quot;%C3%BB&amp;quot;, &amp;quot;%C3%B9&amp;quot;, &amp;quot;%C3%BF&amp;quot;, &amp;quot;%C3%96&amp;quot;, &amp;quot;%C3%9C&amp;quot;, &amp;quot;%C2%A2&amp;quot;, &amp;quot;%C2%A3&amp;quot;, &amp;quot;%C2%A5&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        //                 A^              a/              i/                o/            u/              n~           E:            y/              inv ?         O^&lt;br /&gt;
        &amp;quot;%C3%82&amp;quot;, &amp;quot;%C3%A1&amp;quot;, &amp;quot;%C3%AD&amp;quot;, &amp;quot;%C3%B3&amp;quot;, &amp;quot;%C3%BA&amp;quot;, &amp;quot;%C3%B1&amp;quot;, &amp;quot;%C3%8B&amp;quot;, &amp;quot;%C3%BD&amp;quot;, &amp;quot;%C2%BF&amp;quot;, &amp;quot;%C3%94&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        //                   inv !             I\             I/           degree       E^              I^            o^            U^&lt;br /&gt;
        &amp;quot;%C2%A1&amp;quot;, &amp;quot;%C3%8C&amp;quot;, &amp;quot;%C3%8D&amp;quot;, &amp;quot;%C2%B0&amp;quot;, &amp;quot;%C3%8A&amp;quot;, &amp;quot;%C3%8E&amp;quot;, &amp;quot;%C3%B4&amp;quot;, &amp;quot;%C3%9B&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        //                     Y:          euro           german ss         E\              A\           A/              U\           U/               O\           O/&lt;br /&gt;
        &amp;quot;%C3%9D&amp;quot;, &amp;quot;%E2%82%AC&amp;quot;, &amp;quot;%C3%9F&amp;quot;, &amp;quot;%C3%88&amp;quot;, &amp;quot;%C3%80&amp;quot;, &amp;quot;%C3%81&amp;quot;, &amp;quot;%C3%99&amp;quot;, &amp;quot;%C3%9A&amp;quot;, &amp;quot;%C3%92&amp;quot;, &amp;quot;%C3%93&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        //                   Sv           sv             zv             Zv              Y:             I:&lt;br /&gt;
        &amp;quot;%C5%A0&amp;quot;, &amp;quot;%C5%A1&amp;quot;, &amp;quot;%C5%BE&amp;quot;, &amp;quot;%C5%BD&amp;quot;, &amp;quot;%C3%9D&amp;quot;, &amp;quot;%C3%8C&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vector GetGridPos(integer index1, integer index2) {&lt;br /&gt;
    // There are two ways to use the lookup table...&lt;br /&gt;
    integer Col;&lt;br /&gt;
    integer Row;&lt;br /&gt;
    if (index1 &amp;gt;= index2) {&lt;br /&gt;
        // In this case, the row is the index of the first character:&lt;br /&gt;
        Row = index1;&lt;br /&gt;
        // And the col is the index of the second character (x2)&lt;br /&gt;
        Col = index2 * 2;&lt;br /&gt;
    }&lt;br /&gt;
    else { // Index1 &amp;lt; Index2&lt;br /&gt;
        // In this case, the row is the index of the second character:&lt;br /&gt;
        Row = index2;&lt;br /&gt;
        // And the col is the index of the first character, x2, offset by 1.&lt;br /&gt;
        Col = index1 * 2 + 1;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;lt;Col, Row, 0&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string GetGridTexture(vector grid_pos) {&lt;br /&gt;
    // Calculate the texture in the grid to use.&lt;br /&gt;
    integer GridCol = llRound(grid_pos.x) / 40; // PK was 20&lt;br /&gt;
    integer GridRow = llRound(grid_pos.y) / 20; // PK was 10&lt;br /&gt;
&lt;br /&gt;
    // Lookup the texture.&lt;br /&gt;
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);&lt;br /&gt;
    return Texture;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(vector grid_pos) {&lt;br /&gt;
    // Zoom in on the texture showing our character pair.&lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 40; // PK was 20&lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 20; // PK was 10&lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture.&lt;br /&gt;
    return &amp;lt;-0.45 + 0.025 * Col, 0.45 - 0.05 * Row, 0.0&amp;gt;; // PK was 0.05 and 0.1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) {&lt;br /&gt;
    // Set the primitive textures directly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    llSetPrimitiveParams( [&lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.125, 0.05, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.0375-0.025-0.002, 0.025, 0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.05, 0.05, 0&amp;gt;, GetGridOffset(grid_pos2)+&amp;lt;-0.025-0.002, 0.025,0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-0.74, 0.05, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;-.34-0.002, 0.025, 0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.05, 0.05, 0&amp;gt;, GetGridOffset(grid_pos4)+&amp;lt;-0.025-0.002, 0.025,0&amp;gt;, 0.0,&lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.125, 0.05, 0&amp;gt;, GetGridOffset(grid_pos5) + &amp;lt;0.0375-0.025-0.077-0.002, 0.025, 0&amp;gt;, 0.0&lt;br /&gt;
            //        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0,&lt;br /&gt;
            //        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0,&lt;br /&gt;
            //        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0,&lt;br /&gt;
            //        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0,&lt;br /&gt;
            //        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0&lt;br /&gt;
&lt;br /&gt;
            ]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer GetIndex(string char)&lt;br /&gt;
{&lt;br /&gt;
    integer  ret=llSubStringIndex(gCharIndex, char);&lt;br /&gt;
    if(ret&amp;gt;=0) return ret;&lt;br /&gt;
&lt;br /&gt;
    // special char do nice trick :)&lt;br /&gt;
    string escaped=llEscapeURL(char);&lt;br /&gt;
&lt;br /&gt;
    if(escaped==&amp;quot;%E2%80%99&amp;quot;) return 7; // remap ’&lt;br /&gt;
    //llSay(0,&amp;quot;Looking for &amp;quot;+escaped);&lt;br /&gt;
    integer found=llListFindList(decode, [escaped]);&lt;br /&gt;
&lt;br /&gt;
    // not found&lt;br /&gt;
    if(found&amp;lt;0) return 0;&lt;br /&gt;
&lt;br /&gt;
    // return correct index&lt;br /&gt;
    return llStringLength(gCharIndex)+found;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters.&lt;br /&gt;
    vector GridPos1 = GetGridPos( GetIndex(llGetSubString(str, 0, 0)),&lt;br /&gt;
        GetIndex(llGetSubString(str, 1, 1)) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( GetIndex(llGetSubString(str, 2, 2)),&lt;br /&gt;
        GetIndex(llGetSubString(str, 3, 3)) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( GetIndex(llGetSubString(str, 4, 4)),&lt;br /&gt;
        GetIndex(llGetSubString(str, 5, 5)) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( GetIndex(llGetSubString(str, 6, 6)),&lt;br /&gt;
        GetIndex(llGetSubString(str, 7, 7)) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( GetIndex(llGetSubString(str, 8, 8)),&lt;br /&gt;
        GetIndex(llGetSubString(str, 9, 9)) );&lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderWithEffects(string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters.&lt;br /&gt;
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),&lt;br /&gt;
        llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),&lt;br /&gt;
        llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),&lt;br /&gt;
        llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)),&lt;br /&gt;
        llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),&lt;br /&gt;
        llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );&lt;br /&gt;
&lt;br /&gt;
    // First set the alpha to the lowest possible.&lt;br /&gt;
    llSetAlpha(0.05, ALL_SIDES);&lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
&lt;br /&gt;
    float Alpha;&lt;br /&gt;
    for (Alpha = 0.10; Alpha &amp;lt;= 1.0; Alpha += 0.05)&lt;br /&gt;
        llSetAlpha(Alpha, ALL_SIDES);&lt;br /&gt;
    // See if we want to fade out as well.&lt;br /&gt;
    if (gCellHoldDelay &amp;lt; 0.0)&lt;br /&gt;
        // No, bail out. (Just keep showing the string at full strength).&lt;br /&gt;
        return;&lt;br /&gt;
    // Hold the text for a while.&lt;br /&gt;
    llSleep(gCellHoldDelay);&lt;br /&gt;
    // Now fade out.&lt;br /&gt;
    for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05)&lt;br /&gt;
        llSetAlpha(Alpha, ALL_SIDES);&lt;br /&gt;
    // Make the text transparent to fully hide it.&lt;br /&gt;
    llSetTexture(TRANSPARENT, ALL_SIDES);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderExtended(string str) {&lt;br /&gt;
    // Look for escape sequences.&lt;br /&gt;
    list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]);&lt;br /&gt;
    integer ParsedLen = llGetListLength(Parsed);&lt;br /&gt;
&lt;br /&gt;
    // Create a list of index values to work with.&lt;br /&gt;
    list Indices;&lt;br /&gt;
    // We start with room for 6 indices.&lt;br /&gt;
    integer IndicesLeft = 10;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    string Token;&lt;br /&gt;
    integer Clipped;&lt;br /&gt;
    integer LastWasEscapeSequence = FALSE;&lt;br /&gt;
    // Work from left to right.&lt;br /&gt;
    for (i = 0; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; i++) {&lt;br /&gt;
        Token = llList2String(Parsed, i);&lt;br /&gt;
&lt;br /&gt;
        // If this is an escape sequence, just set the flag and move on.&lt;br /&gt;
        if (Token == ESCAPE_SEQUENCE) {&lt;br /&gt;
            LastWasEscapeSequence = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else { // Token != ESCAPE_SEQUENCE&lt;br /&gt;
            // Otherwise this is a normal token.  Check its length.&lt;br /&gt;
            Clipped = FALSE;&lt;br /&gt;
            integer TokenLength = llStringLength(Token);&lt;br /&gt;
            // Clip if necessary.&lt;br /&gt;
            if (TokenLength &amp;gt; IndicesLeft) {&lt;br /&gt;
                Token = llGetSubString(Token, 0, IndicesLeft - 1);&lt;br /&gt;
                TokenLength = llStringLength(Token);&lt;br /&gt;
                IndicesLeft = 0;&lt;br /&gt;
                Clipped = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                IndicesLeft -= TokenLength;&lt;br /&gt;
&lt;br /&gt;
            // Was the previous token an escape sequence?&lt;br /&gt;
            if (LastWasEscapeSequence) {&lt;br /&gt;
                // Yes, the first character is an escape character, the rest are normal.&lt;br /&gt;
&lt;br /&gt;
                // This is the extended character.&lt;br /&gt;
                Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];&lt;br /&gt;
&lt;br /&gt;
                // These are the normal characters.&lt;br /&gt;
                integer j;&lt;br /&gt;
                for (j = 1; j &amp;lt; TokenLength; j++)&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
            }&lt;br /&gt;
            else { // Normal string.&lt;br /&gt;
                // Just add the characters normally.&lt;br /&gt;
                integer j;&lt;br /&gt;
                for (j = 0; j &amp;lt; TokenLength; j++)&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Unset this flag, since this was not an escape sequence.&lt;br /&gt;
            LastWasEscapeSequence = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Use the indices to create grid positions.&lt;br /&gt;
    vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );&lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) {&lt;br /&gt;
    // This converts from an ASCII based index to our indexing scheme.&lt;br /&gt;
    if (index &amp;gt;= 32) // &#039; &#039; or higher&lt;br /&gt;
        index -= 32;&lt;br /&gt;
    else { // index &amp;lt; 32&lt;br /&gt;
        // Quick bounds check.&lt;br /&gt;
        if (index &amp;gt; 15)&lt;br /&gt;
            index = 15;&lt;br /&gt;
&lt;br /&gt;
        index += 94; // extended characters&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return index;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        // Initialize the character index.&lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        ME=(integer)llGetObjectName();&lt;br /&gt;
        //llOwnerSay(&amp;quot;Channel:&amp;quot;+(string)ME);&lt;br /&gt;
        //llSay(0, &amp;quot;Free Memory: &amp;quot; + (string) llGetFreeMemory());&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) {&lt;br /&gt;
        if (channel == (ME+DISPLAY_STRING)) {&lt;br /&gt;
            RenderString(data);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+DISPLAY_EXTENDED)) {&lt;br /&gt;
            RenderExtended(data);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == gCellChannel) {&lt;br /&gt;
            // Extract the characters we are interested in, and use those to render.&lt;br /&gt;
            string TextToRender = llGetSubString(data, gCellCharPosition, gCellCharPosition + 9);&lt;br /&gt;
            if (gCellUseFading)&lt;br /&gt;
                RenderWithEffects( TextToRender );&lt;br /&gt;
            else // !gCellUseFading&lt;br /&gt;
                RenderString( TextToRender );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+REMAP_INDICES)) {&lt;br /&gt;
            // Parse the message, splitting it up into index values.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            integer i;&lt;br /&gt;
            // Go through the list and swap each pair of indices.&lt;br /&gt;
            for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) {&lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );&lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );&lt;br /&gt;
&lt;br /&gt;
                // Swap these index values.&lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+RESET_INDICES)) {&lt;br /&gt;
            // Restore the character index back to default settings.&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+SET_CELL_INFO)) {&lt;br /&gt;
            // Change the channel we listen to for cell commands, and the&lt;br /&gt;
            // starting character position to extract from.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            gCellChannel        = (integer) llList2String(Parsed, 0);&lt;br /&gt;
            gCellCharPosition   = (integer) llList2String(Parsed, 1);&lt;br /&gt;
            gCellUseFading      = (integer) llList2String(Parsed, 2);&lt;br /&gt;
            gCellHoldDelay      = (float)   llList2String(Parsed, 3);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+SET_THICKNESS)) {&lt;br /&gt;
            // Set our z scale to thickness, while staying fixed&lt;br /&gt;
            // in position relative the prim below us.&lt;br /&gt;
            vector Scale    = llGetScale();&lt;br /&gt;
            float Thickness = (float) data;&lt;br /&gt;
            // Reposition only if this isn&#039;t the root prim.&lt;br /&gt;
            integer ThisLink = llGetLinkNumber();&lt;br /&gt;
            if (ThisLink != 0 || ThisLink != 1) {&lt;br /&gt;
                // This is not the root prim.&lt;br /&gt;
                vector Up = llRot2Up(llGetLocalRot());&lt;br /&gt;
                float DistanceToMove = Thickness / 2.0 - Scale.z / 2.0;&lt;br /&gt;
                vector Pos = llGetLocalPos();&lt;br /&gt;
                llSetPos(Pos + DistanceToMove * Up);&lt;br /&gt;
            }&lt;br /&gt;
            // Apply the new thickness.&lt;br /&gt;
            Scale.z = Thickness;&lt;br /&gt;
            llSetScale(Scale);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (channel == (ME+SET_COLOR)) {&lt;br /&gt;
            vector newColor = (vector)data;&lt;br /&gt;
            llSetColor(newColor, ALL_SIDES);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Presence_Code_Python&amp;diff=794812</id>
		<title>Presence Code Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Presence_Code_Python&amp;diff=794812"/>
		<updated>2010-03-09T09:07:28Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extremely incomplete example of how to log an avatar in and establish a presence. So far it only sends enough to temporarily show in-world. More to come....&lt;br /&gt;
&lt;br /&gt;
N.B.: the packet ID number of a zero encoded pack is encoded and must be decoded before you can know what packet you are actually dealing with (Thanks John Hurliman/Eddy Stryker).&lt;br /&gt;
&lt;br /&gt;
(based on a sample login script found at [http://www.libsecondlife.org/wiki/Login libsl login].)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;from struct import *&lt;br /&gt;
from zerocode import  *&lt;br /&gt;
import md5&lt;br /&gt;
import xmlrpclib&lt;br /&gt;
import sys &lt;br /&gt;
&lt;br /&gt;
import re&lt;br /&gt;
import httplib, urllib        &lt;br /&gt;
from urlparse import urlparse    &lt;br /&gt;
import socket, sys, time&lt;br /&gt;
import uuid&lt;br /&gt;
from makepacketdict import makepacketdict&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mypacketdictionary = {}&lt;br /&gt;
outputstring = &#039;&#039;&lt;br /&gt;
ack_need_list = []&lt;br /&gt;
&lt;br /&gt;
logoutputflag = False&lt;br /&gt;
&lt;br /&gt;
if logoutputflag:&lt;br /&gt;
    temp = sys.stdout&lt;br /&gt;
    sys.stdout =open(&#039;alog.txt&#039;,&#039;w&#039;)&lt;br /&gt;
&lt;br /&gt;
def login(first, last, passwd, mac):&lt;br /&gt;
  passwd_md5 = &#039;$1$&#039; + md5.new(passwd).hexdigest()&lt;br /&gt;
 &lt;br /&gt;
  uri = &#039;http://127.0.0.1&#039;&lt;br /&gt;
  uri = &#039;https://login.agni.lindenlab.com/cgi-bin/login.cgi&#039;&lt;br /&gt;
  s = xmlrpclib.ServerProxy(uri)&lt;br /&gt;
 &lt;br /&gt;
  login_details = {&lt;br /&gt;
    &#039;first&#039;: first,&lt;br /&gt;
    &#039;last&#039;: last,&lt;br /&gt;
    &#039;passwd&#039;: passwd_md5,&lt;br /&gt;
    &#039;start&#039;: &#039;last&#039;,&lt;br /&gt;
    &#039;major&#039;: &#039;1&#039;,&lt;br /&gt;
    &#039;minor&#039;: &#039;18&#039;,&lt;br /&gt;
    &#039;patch&#039;: &#039;5&#039;,&lt;br /&gt;
    &#039;build&#039;: &#039;3&#039;,&lt;br /&gt;
    &#039;platform&#039;: &#039;Win&#039;,&lt;br /&gt;
    &#039;mac&#039;: mac,&lt;br /&gt;
    &#039;options&#039;: [],&lt;br /&gt;
    &#039;user-agent&#039;: &#039;sl.py 0.1&#039;,&lt;br /&gt;
    &#039;id0&#039;: &#039;&#039;,&lt;br /&gt;
    &#039;agree_to_tos&#039;: &#039;&#039;,&lt;br /&gt;
    &#039;viewer_digest&#039;: &#039;09d93740-8f37-c418-fbf2-2a78c7b0d1ea&#039;&lt;br /&gt;
  }&lt;br /&gt;
  results = s.login_to_simulator(login_details)&lt;br /&gt;
  print results&lt;br /&gt;
  &lt;br /&gt;
  return results&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def get_caps(results,cap_key, request_keys):&lt;br /&gt;
&lt;br /&gt;
  _, netloc, path, _, _, _ = urlparse(results[cap_key])&lt;br /&gt;
&lt;br /&gt;
  params = &amp;quot;&amp;lt;llsd&amp;gt;&amp;lt;array&amp;gt;&amp;lt;string&amp;gt;&amp;quot;+ request_keys[0]+&amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/array&amp;gt;&amp;lt;/llsd&amp;gt;&amp;quot;&lt;br /&gt;
  headers = {&amp;quot;content-type&amp;quot;: &amp;quot;application/xml&amp;quot;}&lt;br /&gt;
  conn = httplib.HTTPSConnection(netloc)&lt;br /&gt;
&lt;br /&gt;
  conn.request(&amp;quot;POST&amp;quot;, path, params, headers)&lt;br /&gt;
  response = conn.getresponse()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  data = response.read()&lt;br /&gt;
  conn.close()&lt;br /&gt;
  return data&lt;br /&gt;
  &lt;br /&gt;
def ExtractCap(cap_result):&lt;br /&gt;
  trim_xml = re.compile(r&amp;quot;&amp;lt;key&amp;gt;([a-zA-Z_]+)&amp;lt;/key&amp;gt;&amp;lt;string&amp;gt;([a-zA-Z_:/0-9-.]+)&amp;lt;/string&amp;gt;&amp;quot;)&lt;br /&gt;
  new_key = trim_xml.search(cap_result).group(1)&lt;br /&gt;
  new_cap = trim_xml.search(cap_result).group(2)&lt;br /&gt;
  return new_key, new_cap&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
def scheduleacknowledgemessage(data):&lt;br /&gt;
    if not ord(data[0])&amp;amp;0x40:&lt;br /&gt;
        print &amp;quot;OOOPS! Got asked to ack a message that shouldn&#039;t be acked&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        return&lt;br /&gt;
    else:&lt;br /&gt;
        ID = data[1:5]&lt;br /&gt;
        if (ord(data[0])&amp;amp;0x40) &amp;amp; 0x80: ID = zero_decode_ID(ID) #impossible&lt;br /&gt;
        ack_need_list.append(unpack(&amp;quot;&amp;gt;L&amp;quot;,ID)[0])&lt;br /&gt;
        #ack_need_list.append(unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])[0])&lt;br /&gt;
        #print &amp;quot;ack needed&amp;quot;,&amp;quot;insdie schedule ack_need_list&amp;quot;, ack_need_list&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
def packacks():&lt;br /&gt;
    acksequence = &amp;quot;&amp;quot;&lt;br /&gt;
    for msgnum in ack_need_list:&lt;br /&gt;
        acksequence += pack(&amp;quot;&amp;lt;L&amp;quot;, msgnum)&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    return acksequence&lt;br /&gt;
        &lt;br /&gt;
#def sendacks():&lt;br /&gt;
 #   if len(ack_need_list)&amp;gt;0:&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
#===============================================================================&lt;br /&gt;
# {&lt;br /&gt;
#    UUIDNameRequest Low NotTrusted Unencoded&lt;br /&gt;
#    {&lt;br /&gt;
#        UUIDNameBlock    Variable&lt;br /&gt;
#        {    ID            LLUUID    }&lt;br /&gt;
#    }&lt;br /&gt;
# }&lt;br /&gt;
#===============================================================================&lt;br /&gt;
&lt;br /&gt;
def sendUUIDNameRequest(sock, port, host, currentsequence,aUUID):&lt;br /&gt;
    &lt;br /&gt;
    packed_data = &amp;quot;&amp;quot;&lt;br /&gt;
    fix_ID = int(&amp;quot;ffff0000&amp;quot;,16)+ 235&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00) &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    for x in aUUID:&lt;br /&gt;
        packed_data += uuid.UUID(x).bytes&lt;br /&gt;
        &lt;br /&gt;
    packed_data += pack(&amp;quot;L&amp;quot;,fix_ID) + pack(&amp;quot;&amp;gt;B&amp;quot;,len(aUUID)) + packed_data&lt;br /&gt;
        &lt;br /&gt;
    sock.sendto(packed_data, (host, port)) &lt;br /&gt;
    return              &lt;br /&gt;
   &lt;br /&gt;
def sendRegionHandshakeReply(sock, port, host, currentsequence,agentUUID,sessionUUID):&lt;br /&gt;
    packed_data = &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    low_ID = &amp;quot;ffff00%2x&amp;quot; % 149&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00)&lt;br /&gt;
    packed_data += uuid.UUID(agentUUID).bytes+uuid.UUID(sessionUUID).bytes+ pack(&amp;quot;&amp;gt;L&amp;quot;,0x00)&lt;br /&gt;
    packed_data = data_header + pack(&amp;quot;&amp;gt;L&amp;quot;,int(low_ID,16))+packed_data&lt;br /&gt;
    sock.sendto(packed_data, (host, port)) &lt;br /&gt;
    #print &amp;quot;RegionHandshakeReply&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
    return&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
        &lt;br /&gt;
def sendAgentUpdate(sock, port, host, currentsequence, result):&lt;br /&gt;
&lt;br /&gt;
#AgentUpdate&lt;br /&gt;
&lt;br /&gt;
    tempacks = packacks()&lt;br /&gt;
    del ack_need_list[:]&lt;br /&gt;
    if tempacks == &amp;quot;&amp;quot;: &lt;br /&gt;
        flags = 0x00&lt;br /&gt;
    else:&lt;br /&gt;
        flags = 0x10&lt;br /&gt;
&lt;br /&gt;
    #print &amp;quot;tempacks is:&amp;quot;, ByteToHex(tempacks)  &lt;br /&gt;
        &lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, flags,currentsequence,0x00)&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;B&#039;,0x04)&lt;br /&gt;
    packed_data_ID = uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes&lt;br /&gt;
    packed_data_QuatRots = pack(&#039;&amp;lt;ffff&#039;, 0.0,0.0,0.0,0.0)+pack(&#039;&amp;lt;ffff&#039;, 0.0,0.0,0.0,0.0)  &lt;br /&gt;
    packed_data_State = pack(&#039;&amp;lt;B&#039;, 0x00)&lt;br /&gt;
    packed_data_Camera = pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)+pack(&#039;&amp;lt;fff&#039;, 0.0,0.0,0.0)&lt;br /&gt;
    packed_data_Flags = pack(&#039;&amp;lt;fLB&#039;, 0.0,0x00,0x00)&lt;br /&gt;
&lt;br /&gt;
    encoded_packed_data = zero_encode(packed_data_message_ID+packed_data_ID+packed_data_QuatRots+packed_data_State+packed_data_Camera+packed_data_Flags)&lt;br /&gt;
&lt;br /&gt;
    packed_data = data_header + encoded_packed_data+tempacks&lt;br /&gt;
&lt;br /&gt;
   # print &amp;quot;sending AgentUpdate to server&amp;quot;,ByteToHex(packed_data_header+zero_decode(encoded_packed_data)+ tempacks)&lt;br /&gt;
    &lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
def sendCompletePingCheck(sock, port, host, currentsequence,data,lastPingSent):&lt;br /&gt;
#    print &amp;quot;data from PingCHeck&amp;quot;, ByteToHex(data)&lt;br /&gt;
    &lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,currentsequence,0x00)&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;B&#039;,0x02)&lt;br /&gt;
    packed_data = data_header + packed_data_message_ID+pack(&#039;&amp;gt;B&#039;, lastPingSent)&lt;br /&gt;
    print &amp;quot;CompletePingCheck packet sent:&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
    &lt;br /&gt;
    return&lt;br /&gt;
    &lt;br /&gt;
def sendPacketAck(sock, port, host,currentsequence):&lt;br /&gt;
&lt;br /&gt;
    tempacks = packacks()&lt;br /&gt;
    templen = len(ack_need_list)&lt;br /&gt;
    del ack_need_list[:]&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;,0x00,currentsequence,0x00) &lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;L&#039;,0xFFFFFFFB)&lt;br /&gt;
    packed_ack_len = pack(&#039;&amp;gt;B&#039;,templen)&lt;br /&gt;
    &lt;br /&gt;
    packed_data = data_header + packed_data_message_ID + packed_ack_len + tempacks&lt;br /&gt;
#===============================================================================&lt;br /&gt;
#    t = datetime.now()&lt;br /&gt;
#    t.strftime(&amp;quot;%H:%M:%S&amp;quot;)&lt;br /&gt;
#    ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
#    print ti, &amp;quot;PacketAck packet sent:&amp;quot;, ByteToHex(packed_data)&lt;br /&gt;
#===============================================================================&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
def sendLogoutRequest(sock, port, host,seqnum,aUUID,sUUID):&lt;br /&gt;
    packed_data = &amp;quot;&amp;quot;&lt;br /&gt;
    packed_data_message_ID = pack(&#039;&amp;gt;L&#039;,0xffff00fc)&lt;br /&gt;
    data_header = pack(&#039;&amp;gt;BLB&#039;, 0x00,seqnum,0x00)&lt;br /&gt;
    packed_data += uuid.UUID(aUUID).bytes+uuid.UUID(sUUID).bytes+ pack(&amp;quot;&amp;gt;L&amp;quot;,0x00)&lt;br /&gt;
    &lt;br /&gt;
    packed_data = data_header + packed_data_message_ID + packed_data&lt;br /&gt;
    sock.sendto(packed_data, (host, port))&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def establishpresence(host, port, circuit_code):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)&lt;br /&gt;
#Sending packet UseCircuitCode &amp;lt;-- Inits the connection to the sim.&lt;br /&gt;
    data = pack(&#039;&amp;gt;BLBL&#039;,0x00,0x01,00,0xffff0003) + pack(&#039;&amp;lt;L&#039;,circuit_code) + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes+uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes&lt;br /&gt;
    sock.sendto(data, (host, port))&lt;br /&gt;
&lt;br /&gt;
#ISending packet CompleteAgentMovement &amp;lt;-- establishes the agent&#039;s presence&lt;br /&gt;
    data = pack(&#039;&amp;gt;BLBL&#039;,0x00,0x02,00,0xffff00f9) + uuid.UUID(result[&amp;quot;agent_id&amp;quot;]).bytes + uuid.UUID(result[&amp;quot;session_id&amp;quot;]).bytes + pack(&#039;&amp;lt;L&#039;, circuit_code)&lt;br /&gt;
    sock.sendto(data, (host, port))&lt;br /&gt;
&lt;br /&gt;
    sendAgentUpdate(sock, port, host, 3, result)&lt;br /&gt;
    aUUID = [result[&amp;quot;agent_id&amp;quot;]]&lt;br /&gt;
    sendUUIDNameRequest(sock, port, host, 4,aUUID)&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
    buf = 100&lt;br /&gt;
    i = 0&lt;br /&gt;
    trusted_count = 0&lt;br /&gt;
    ackable = 0&lt;br /&gt;
    trusted_and_ackable = 0&lt;br /&gt;
    ack_need_list_changed = False&lt;br /&gt;
    seqnum = 5&lt;br /&gt;
    lastPingSent = 0 &lt;br /&gt;
    trusted = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        if ack_need_list_changed:&lt;br /&gt;
            ack_need_list_changed = False&lt;br /&gt;
            seqnum += 1&lt;br /&gt;
            sendPacketAck(sock, port, host,seqnum)&lt;br /&gt;
            #sendAgentUpdate(sock, port, host, seqnum, result)&lt;br /&gt;
            seqnum += 1&lt;br /&gt;
        #sendacks()&lt;br /&gt;
        i += 1&lt;br /&gt;
        data,addr = sock.recvfrom(buf)&lt;br /&gt;
        t = datetime.now()&lt;br /&gt;
        t.strftime(&amp;quot;%H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if not data:&lt;br /&gt;
            print &amp;quot;Client has exited!&amp;quot;&lt;br /&gt;
            &lt;br /&gt;
            break&lt;br /&gt;
        else:&lt;br /&gt;
            test =  ByteToHex(data).split()&lt;br /&gt;
            #print test&lt;br /&gt;
            ID = data[6:12]&lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, ByteToHex(ID) &lt;br /&gt;
            if ord(data[0])&amp;amp;0x80: &lt;br /&gt;
                ID = zero_decode_ID(data[6:12])&lt;br /&gt;
                &lt;br /&gt;
            if ord(data[0])&amp;amp;0x40: &lt;br /&gt;
                scheduleacknowledgemessage(data); &lt;br /&gt;
                ack_need_list_changed = True&lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, ByteToHex(ID) &lt;br /&gt;
            #print &amp;quot;ID =&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;, ID[:4])&lt;br /&gt;
            if ID[0] == &#039;\xFF&#039;:&lt;br /&gt;
                if ID[1] == &#039;\xFF&#039;:&lt;br /&gt;
                    if ID[2] == &#039;\xFF&#039;:&lt;br /&gt;
                        myentry = mypacketdictionary[(&amp;quot;Fixed&amp;quot; , &amp;quot;0x&amp;quot;+ByteToHex(ID[0:4]).replace(&#039; &#039;, &#039;&#039;))]&lt;br /&gt;
                        if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                            trusted += 1;&lt;br /&gt;
                        ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                        print ti, &amp;quot;Message #&amp;quot;, i, &amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,  &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                            &lt;br /&gt;
                        #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
                    else:&lt;br /&gt;
                        myentry = mypacketdictionary[(&amp;quot;Low&amp;quot;,int(ByteToHex(ID[2:4]).replace(&#039; &#039;, &#039;&#039;),16))]&lt;br /&gt;
                        if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                            trusted += 1;&lt;br /&gt;
                        ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                        print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,   &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                        if myentry[0] == &amp;quot;UUIDNameReply&amp;quot;:&lt;br /&gt;
                            pass&lt;br /&gt;
                            #print ByteToHex(data)&lt;br /&gt;
                            #print data[:28]&lt;br /&gt;
                            #print data[28:36],data[38:45]&lt;br /&gt;
                        elif myentry[0] == &amp;quot;RegionHandshake&amp;quot;:&lt;br /&gt;
                            sendRegionHandshakeReply(sock, port, host, seqnum,result[&amp;quot;agent_id&amp;quot;],result[&amp;quot;session_id&amp;quot;])&lt;br /&gt;
                            seqnum += 1&lt;br /&gt;
                        &lt;br /&gt;
                        #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                        #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
                else:&lt;br /&gt;
                    myentry = mypacketdictionary[(&amp;quot;Medium&amp;quot;, int(ByteToHex(ID[1:2]).replace(&#039; &#039;, &#039;&#039;),16))]&lt;br /&gt;
                    if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                        trusted += 1;&lt;br /&gt;
                    ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                    print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,  &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                    &lt;br /&gt;
                    &lt;br /&gt;
                    #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                    #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;, trusted_and_ackable&lt;br /&gt;
                    #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
            else:&lt;br /&gt;
                myentry = mypacketdictionary[(&amp;quot;High&amp;quot;, int(ByteToHex(ID[0]), 16))]&lt;br /&gt;
                if myentry[0] == &amp;quot;StartPingCheck&amp;quot;: &lt;br /&gt;
                    print &amp;quot;data from StartPingCheck&amp;quot;, test&lt;br /&gt;
                    sendCompletePingCheck(sock, port, host, seqnum,data,lastPingSent)&lt;br /&gt;
                    lastPingSent += 1&lt;br /&gt;
                    seqnum += 1&lt;br /&gt;
                    &lt;br /&gt;
                if myentry[1] == &amp;quot;Trusted&amp;quot;:&lt;br /&gt;
                    trusted += 1;   &lt;br /&gt;
                ti = &amp;quot;%02d:%02d:%02d.%06d&amp;quot; % (t.hour,t.minute,t.second,t.microsecond)&lt;br /&gt;
                &lt;br /&gt;
                print ti, &amp;quot;Message #&amp;quot;, i,&amp;quot;trusted count is&amp;quot;, trusted,&amp;quot;Flags: 0x&amp;quot; + test[0], myentry,   &amp;quot;sequence #&amp;quot;, unpack(&amp;quot;&amp;gt;L&amp;quot;,data[1:5])&lt;br /&gt;
                &lt;br /&gt;
                #if myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_count += 1;print &amp;quot;number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
                #if ord(data[0])&amp;amp;0x40 and myentry[1] == &amp;quot;Trusted&amp;quot;: trusted_and_ackable += 1; print &amp;quot;trusted_and_ackable =&amp;quot;,  trusted_and_ackable&lt;br /&gt;
                #if ord(data[0])&amp;amp;0x40: ackable += 1; print &amp;quot;number of ackable messages = &amp;quot;, ackable&lt;br /&gt;
&lt;br /&gt;
    sendLogoutRequest(sock, port, host,seqnum,myAgentID,mySessionID)&lt;br /&gt;
&lt;br /&gt;
    sock.close()&lt;br /&gt;
    print &amp;quot;final number of trusted messages =&amp;quot;, trusted_count&lt;br /&gt;
    &lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
        &lt;br /&gt;
result = login(&amp;quot;first&amp;quot;, &amp;quot;last&amp;quot;, &amp;quot;password&amp;quot;, MAC)&lt;br /&gt;
&lt;br /&gt;
mypacketdictionary = makepacketdict()&lt;br /&gt;
&lt;br /&gt;
myhost = result[&amp;quot;sim_ip&amp;quot;]&lt;br /&gt;
myport = result[&amp;quot;sim_port&amp;quot;]&lt;br /&gt;
mycircuit_code = result[&amp;quot;circuit_code&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
establishpresence(myhost, myport, mycircuit_code)&lt;br /&gt;
&lt;br /&gt;
#cap_out = get_caps(result,&amp;quot;seed_capability&amp;quot;, [&amp;quot;ChatSessionRequest&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
[[Category: AW Groupies]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Jor3l_Boa/PHP/n2k.php&amp;diff=790932</id>
		<title>User:Jor3l Boa/PHP/n2k.php</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Jor3l_Boa/PHP/n2k.php&amp;diff=790932"/>
		<updated>2010-03-07T09:17:14Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PHP Based name2Key service.&lt;br /&gt;
&lt;br /&gt;
n2k.php:&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
//  PHP name2Key by Jor3l Boa&lt;br /&gt;
//  -------------------------&lt;br /&gt;
//  Released under Creative Commons 3.0&lt;br /&gt;
//  - support+n2k@sltools.biz&lt;br /&gt;
//  -------------------------&lt;br /&gt;
&lt;br /&gt;
        function getPage($web) {&lt;br /&gt;
		$html = &amp;quot;&amp;quot;;&lt;br /&gt;
		  $ch = curl_init($web);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_USERAGENT, &amp;quot;Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12&amp;quot;);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_AUTOREFERER, 1);&lt;br /&gt;
		  curl_setopt($ch, CURLOPT_TIMEOUT, 5);&lt;br /&gt;
		  $html = curl_exec($ch);&lt;br /&gt;
		  if(curl_errno($ch)) {&lt;br /&gt;
			  $html = &amp;quot;&amp;quot;;&lt;br /&gt;
		  }&lt;br /&gt;
		  curl_close ($ch);&lt;br /&gt;
		return $html;&lt;br /&gt;
	}&lt;br /&gt;
        function getBetween($content,$start,$end){&lt;br /&gt;
		//by Jor3l :)&lt;br /&gt;
		$a1 = strrpos($content,$start);&lt;br /&gt;
		$content = substr($content,$a1 + strlen($start));&lt;br /&gt;
		while($a2 = strrpos($content,$end))	{&lt;br /&gt;
			$content = substr($content,0,$a2);&lt;br /&gt;
		}&lt;br /&gt;
		return $content;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function name2Key($name)	{&lt;br /&gt;
		$SL_SEARCH = &#039;http://search.secondlife.com/client_search.php?session=00000000-0000-0000-0000-000000000000&amp;amp;q=&#039;;&lt;br /&gt;
		$sName = split(&#039; &#039;,$name);&lt;br /&gt;
		$data = getPage($SL_SEARCH.$sName[0].&#039;%2520&#039;.$sName[1]);&lt;br /&gt;
		$uuid = getBetween($data,&#039;secondlife:///app/agent/&#039;,&#039;/about&#039;);&lt;br /&gt;
		return $uuid;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?&lt;br /&gt;
require_once(&#039;n2k.php&#039;);&lt;br /&gt;
$uuid = name2key(&#039;FirstName LastName&#039;);&lt;br /&gt;
echo $uuid;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOTE ON HOSTING PROVIDERS:&amp;lt;/b&amp;gt;&lt;br /&gt;
Some hosting providers, notably GoDaddy, do not allow outbound traffic from their servers.  If you find that this script returns nothing, no matter what you try, that may be your issue.  The only fix is to switch providers to one that does allow outbound traffic.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;I&amp;gt;For an LSL version, see also: [[Name2Key_in_LSL]]&amp;lt;/i&amp;gt;&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples/kellys_stupid_web_status_updater&amp;diff=782803</id>
		<title>LSL HTTP server/examples/kellys stupid web status updater</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples/kellys_stupid_web_status_updater&amp;diff=782803"/>
		<updated>2010-03-05T19:10:31Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What ==&lt;br /&gt;
This is a dead stupid, insecure and simple system that will update the floating text above a prim according to what is entered in the web form.  Uses html forms, python and LSL.  This is about as simple as it gets, I think.&lt;br /&gt;
&lt;br /&gt;
== index.html ==&lt;br /&gt;
A simple webform that sends the input to our cgi.&lt;br /&gt;
&amp;lt;html4strict&amp;gt;&amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
      &amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
         &amp;lt;form ACTION=&amp;quot;cgi-bin/post.cgi&amp;quot; METHOD=&amp;quot;GET&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;textarea name=&amp;quot;Message&amp;quot; rows=&amp;quot;5&amp;quot; cols=&amp;quot;40&amp;quot; onfocus=&amp;quot;this.value=&#039;&#039;; this.onfocus=null;&amp;quot;&amp;gt;Enter your status update here.&amp;lt;/textarea&amp;gt;&lt;br /&gt;
            &amp;lt;P&amp;gt;&lt;br /&gt;
            &amp;lt;INPUT TYPE=&amp;quot;submit&amp;quot; title=&amp;quot;FOO&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;/form&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
== post.cgi ==&lt;br /&gt;
A simple CGI that takes GETs and looks for two parameters:&lt;br /&gt;
* URL: if found will write the value to a file&lt;br /&gt;
* Message: if found will read from the file and send the contents to the url in the file&lt;br /&gt;
Bugs:&lt;br /&gt;
* Entering no text in the form will cause the cgi to error.&lt;br /&gt;
Errata:&lt;br /&gt;
* This is probably really insecure.&lt;br /&gt;
* You need to create the file &#039;my_url&#039; (or whatever you set file_name as) in your cgi-bin directory.&lt;br /&gt;
* That file needs to be readable and writable by your cgi.  Depending on your setup something like this might work:&lt;br /&gt;
: touch my_url&lt;br /&gt;
: chmod 600 my_url&lt;br /&gt;
* You may need to be more permissive depending on your server configuration, but this worked on my shared hosting system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import cgi, urllib2, urllib&lt;br /&gt;
import cgitb&lt;br /&gt;
cgitb.enable()&lt;br /&gt;
&lt;br /&gt;
# This file needs to be readable and writable from this cgi&lt;br /&gt;
file_name = &amp;quot;my_url&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# If we have Message then this is a status update.&lt;br /&gt;
if &amp;quot;Message&amp;quot; in form:&lt;br /&gt;
        # Redirect back to the form&lt;br /&gt;
        print &amp;quot;Status: 302 Moved&amp;quot;&lt;br /&gt;
        print &amp;quot;Location: http://www.myurl.com/path/to/form&amp;quot;&lt;br /&gt;
        print&lt;br /&gt;
&lt;br /&gt;
        # Read in the url from the file&lt;br /&gt;
        f = open(file_name,&#039;r&#039;)&lt;br /&gt;
        base_url = f.read()&lt;br /&gt;
&lt;br /&gt;
        # Build the complete url with query args.&lt;br /&gt;
        message = form[&amp;quot;Message&amp;quot;].value&lt;br /&gt;
        args = &amp;quot;?Message=%s&amp;quot; % urllib.quote(message)&lt;br /&gt;
&lt;br /&gt;
        # Make the request, giving the status to the script.&lt;br /&gt;
        response = urllib2.urlopen(base_url + args)&lt;br /&gt;
&lt;br /&gt;
# If we have URL then this is an URL update&lt;br /&gt;
if &amp;quot;URL&amp;quot; in form:&lt;br /&gt;
        # Write the url to the file, overwriting the existing file.&lt;br /&gt;
        f = open(file_name,&#039;w&#039;)&lt;br /&gt;
        f.write(form[&amp;quot;URL&amp;quot;].value)&lt;br /&gt;
&lt;br /&gt;
        # Let the caller know it worked.&lt;br /&gt;
        print &amp;quot;Content-Type: text/html&amp;quot;&lt;br /&gt;
        print&lt;br /&gt;
        print &amp;quot;OK&amp;quot;&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== status.lsl ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Set this to whatever text you want above your status&lt;br /&gt;
string header = &amp;quot;My Status:\n&amp;quot;;&lt;br /&gt;
// This is the url to the post.cgi from above&lt;br /&gt;
string updater_url = &amp;quot;http://mywebsite.com/cgi-bin/post.cgi&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// The magic changed flags to know when to re-request an url&lt;br /&gt;
// CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT&lt;br /&gt;
integer CHANGED_URL = 1792;&lt;br /&gt;
&lt;br /&gt;
// Setup run anytime we think our url has been lost.&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server: Status Updates&amp;quot;);&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Debug incoming requests to see all header information.&lt;br /&gt;
debug(key id, string method, string body)&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(method + &amp;quot;: &amp;quot; + body);&lt;br /&gt;
    list headers = [&amp;quot;x-script-url&amp;quot;,&amp;quot;x-path-info&amp;quot;,&amp;quot;x-query-string&amp;quot;,&amp;quot;x-remote-ip&amp;quot;,&amp;quot;user-agent&amp;quot;];&lt;br /&gt;
    integer i;&lt;br /&gt;
    for (i=0;i&amp;lt;5;++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(headers,i) + &amp;quot;: &amp;quot; + llGetHTTPHeader(id,llList2String(headers,i)));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    // These events mean we have lost any urls we had and need to run setup()&lt;br /&gt;
    state_entry() { setup(); }&lt;br /&gt;
    on_rez(integer n) { setup(); }&lt;br /&gt;
    changed(integer c) { if (c &amp;amp; (CHANGED_URL) ) setup(); }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        // debug(id, method, body);&lt;br /&gt;
        &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            // Register our url for new status updates.&lt;br /&gt;
            llHTTPRequest(updater_url + &amp;quot;?URL=&amp;quot; + body + &amp;quot;/&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            // Might be good to have this email.&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            // Process a status update by parsing the query string&lt;br /&gt;
            string t = llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;);&lt;br /&gt;
            list l = llParseString2List(t,[&amp;quot;?&amp;quot;,&amp;quot;=&amp;quot;,&amp;quot;&amp;amp;&amp;quot;],[]);&lt;br /&gt;
&lt;br /&gt;
            // We want the value after Message&lt;br /&gt;
            integer i = llListFindList(l,[&amp;quot;Message&amp;quot;]) + 1;&lt;br /&gt;
&lt;br /&gt;
            // If there was no Message argument then i = (-1) + 1 =&amp;gt; 0.&lt;br /&gt;
            // As long as i &amp;gt; 0 we found Message so put up whatever came next as the status.&lt;br /&gt;
            if (i &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                llSetText(header + llUnescapeURL(llList2String(l,i)),&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
                llHTTPResponse(id,200,&amp;quot;OK&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llHTTPResponse(id,400,&amp;quot;Must Specify a message!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples/kurais_stupid_web_status_updater&amp;diff=782793</id>
		<title>LSL HTTP server/examples/kurais stupid web status updater</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples/kurais_stupid_web_status_updater&amp;diff=782793"/>
		<updated>2010-03-05T19:09:11Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What ==&lt;br /&gt;
*Based on [[LSL_http_server/examples/kellys_stupid_web_status_updater|Kellys stupid web status updater]].&lt;br /&gt;
*Isn&#039;t so stupid as Kellys, i hope. *lol*&lt;br /&gt;
: Kills me not, this is my first try with python xD&lt;br /&gt;
*Uses html forms, python and LSL.&lt;br /&gt;
*Fixed the cgi error bug with empty messages&lt;br /&gt;
*Add status reports for write to file error und success URL update&lt;br /&gt;
&lt;br /&gt;
== index.html ==&lt;br /&gt;
A simple webform that sends the input to our cgi.&lt;br /&gt;
&amp;lt;html4strict&amp;gt;&amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
      &amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
         &amp;lt;form ACTION=&amp;quot;cgi-bin/post.cgi&amp;quot; METHOD=&amp;quot;GET&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;textarea name=&amp;quot;Message&amp;quot; rows=&amp;quot;5&amp;quot; cols=&amp;quot;40&amp;quot; onfocus=&amp;quot;this.value=&#039;&#039;; this.onfocus=null;&amp;quot;&amp;gt;Enter your status update here.&amp;lt;/textarea&amp;gt;&lt;br /&gt;
            &amp;lt;P&amp;gt;&lt;br /&gt;
            &amp;lt;INPUT TYPE=&amp;quot;submit&amp;quot; title=&amp;quot;FOO&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;/form&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&amp;lt;/html4strict&amp;gt;&lt;br /&gt;
== post.cgi ==&lt;br /&gt;
* That file needs to be readable and writable by your cgi.  Depending on your setup something like this might work:&lt;br /&gt;
: touch my_url&lt;br /&gt;
: chmod 600 my_url&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
##############################################&lt;br /&gt;
# Original written by Kelly Linden           #&lt;br /&gt;
# Modified by Kuraiko Yoshikawa (2009/07/28) #&lt;br /&gt;
##############################################&lt;br /&gt;
&lt;br /&gt;
import cgi, urllib2, urllib&lt;br /&gt;
import cgitb&lt;br /&gt;
cgitb.enable()&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
# This file needs to be readable and writable from this cgi&lt;br /&gt;
file_name = &amp;quot;my_url&amp;quot;&lt;br /&gt;
&lt;br /&gt;
form = cgi.FieldStorage()&lt;br /&gt;
&lt;br /&gt;
# Set the URL of your form&lt;br /&gt;
url = &amp;quot;enter your form url&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# If we haven&#039;t a Message or URL let the user know it and redirect to the form&lt;br /&gt;
if &amp;quot;Message&amp;quot; not in form and &amp;quot;URL&amp;quot; not in form:&lt;br /&gt;
        &lt;br /&gt;
        print &amp;quot;Content-Type: text/html&amp;quot;&lt;br /&gt;
        print&lt;br /&gt;
        print &amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;meta http-equiv=\&amp;quot;refresh\&amp;quot; content=\&amp;quot;5; URL=%s\&amp;quot;&amp;gt;&amp;lt;/head&amp;gt;&amp;quot; %url&lt;br /&gt;
        print &amp;quot;&amp;lt;body style=\&amp;quot;text-align: center; margin-top: 20px;\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
        print &amp;quot;Please fill in the message field.&amp;lt;br&amp;gt;&amp;lt;a href=\&amp;quot;%s\&amp;quot;&amp;gt;Redirection to the form in 5 seconds&amp;lt;/a&amp;gt;&amp;quot; %url&lt;br /&gt;
        print &amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# If we have URL param then this is an URL update&lt;br /&gt;
elif &amp;quot;URL&amp;quot; in form: &lt;br /&gt;
        # Intercept errors&lt;br /&gt;
        try:&lt;br /&gt;
                # Write the url to the file, overwriting the existing file. &lt;br /&gt;
                f = open(file_name,&#039;w&#039;)&lt;br /&gt;
                f.write(form[&amp;quot;URL&amp;quot;].value)&lt;br /&gt;
 &lt;br /&gt;
                # Let the caller know it worked.&lt;br /&gt;
                print &amp;quot;Content-Type: text/html&amp;quot;&lt;br /&gt;
                print&lt;br /&gt;
                print &amp;quot;OK&amp;quot;&lt;br /&gt;
        except:&lt;br /&gt;
                # it has an error.&lt;br /&gt;
                print &amp;quot;Content-Type: text/html&amp;quot;&lt;br /&gt;
                print&lt;br /&gt;
                print &amp;quot;ERROR|%s&amp;quot; %file_name&lt;br /&gt;
 &lt;br /&gt;
# We have Message then this is a status update.&lt;br /&gt;
else:&lt;br /&gt;
        # Redirect back to the form&lt;br /&gt;
        print &amp;quot;Status: 302 Moved&amp;quot;&lt;br /&gt;
        print &amp;quot;Location: %s&amp;quot; %url&lt;br /&gt;
        print&lt;br /&gt;
 &lt;br /&gt;
        # Read in the url from the file&lt;br /&gt;
        f = open(file_name,&#039;r&#039;)&lt;br /&gt;
        base_url = f.read()&lt;br /&gt;
 &lt;br /&gt;
        # Build the complete url with query args.&lt;br /&gt;
        message = form[&amp;quot;Message&amp;quot;].value&lt;br /&gt;
        args = &amp;quot;?Message=%s&amp;quot; % urllib.quote(message)&lt;br /&gt;
 &lt;br /&gt;
        # Make the request, giving the status to the script.&lt;br /&gt;
        response = urllib2.urlopen(base_url + args)&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== status.lsl ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////////&lt;br /&gt;
// Original written by Kelly Linden           //&lt;br /&gt;
// Modified by Kuraiko Yoshikawa (2009/07/28) //&lt;br /&gt;
////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// Set this to whatever text you want above your status&lt;br /&gt;
string header = &amp;quot;My Status:\n&amp;quot;;&lt;br /&gt;
// This is the url to the post.cgi from above&lt;br /&gt;
string updater_url = &amp;quot;&amp;lt;url to your python script&amp;gt;&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
// The magic changed flags to know when to re-request an url&lt;br /&gt;
// CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT&lt;br /&gt;
integer CHANGED_URL = 1792;&lt;br /&gt;
&lt;br /&gt;
key request;&lt;br /&gt;
// Setup run anytime we think our url has been lost.&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server: Status Updates&amp;quot;);&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Debug incoming requests to see all header information.&lt;br /&gt;
debug(key id, string method, string body)&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(method + &amp;quot;: &amp;quot; + body);&lt;br /&gt;
    list headers = [&amp;quot;x-script-url&amp;quot;,&amp;quot;x-path-info&amp;quot;,&amp;quot;x-query-string&amp;quot;,&amp;quot;x-remote-ip&amp;quot;,&amp;quot;user-agent&amp;quot;];&lt;br /&gt;
    integer i;&lt;br /&gt;
    for (i=0;i&amp;lt;5;++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(headers,i) + &amp;quot;: &amp;quot; + llGetHTTPHeader(id,llList2String(headers,i)));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    // These events mean we have lost any urls we had and need to run setup()&lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        setup(); &lt;br /&gt;
    }&lt;br /&gt;
    on_rez(integer n) &lt;br /&gt;
    { &lt;br /&gt;
        setup(); &lt;br /&gt;
    }&lt;br /&gt;
    changed(integer c) &lt;br /&gt;
    { &lt;br /&gt;
        if (c &amp;amp; (CHANGED_URL) ) setup(); &lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
         //debug(id, method, body);&lt;br /&gt;
 &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            // Register our url for new status updates.&lt;br /&gt;
            request = llHTTPRequest(updater_url + &amp;quot;?URL=&amp;quot; + body + &amp;quot;/&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            // Might be good to have this email.&lt;br /&gt;
            llSay(0,&amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            // Process a status update by parsing the query string&lt;br /&gt;
            string t = llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;);&lt;br /&gt;
            list l = llParseString2List(t,[&amp;quot;?&amp;quot;,&amp;quot;=&amp;quot;,&amp;quot;&amp;amp;&amp;quot;],[]);&lt;br /&gt;
            &lt;br /&gt;
            // We want the value after Message&lt;br /&gt;
            integer i = llListFindList(l,[&amp;quot;Message&amp;quot;]) + 1;&lt;br /&gt;
 &lt;br /&gt;
            // If there was no Message argument then i = (-1) + 1 =&amp;gt; 0.&lt;br /&gt;
            // As long as i &amp;gt; 0 we found Message so put up whatever came next as the status.&lt;br /&gt;
            if (i &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                llSetText(header + llUnescapeURL(llList2String(l,i)),&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
                llHTTPResponse(id,200,&amp;quot;OK&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llHTTPResponse(id,400,&amp;quot;Must Specify a message!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_response(key request_id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if(request_id == request)&lt;br /&gt;
        {&lt;br /&gt;
            list t = llParseString2List(body, [&amp;quot;|&amp;quot;], [&amp;quot;&amp;quot;]);&lt;br /&gt;
            string t0 = llStringTrim(llList2String(t, 0), STRING_TRIM);&lt;br /&gt;
            string t1 = llStringTrim(llList2String(t, 1), STRING_TRIM);&lt;br /&gt;
            if(t0 == &amp;quot;OK&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llSay(0, &amp;quot;URL successfully updated.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (t0 == &amp;quot;ERROR&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llSay(0, &amp;quot;Can&#039;t write the URL to the file &#039;&amp;quot; + t1 + &lt;br /&gt;
                &amp;quot;&#039;. Please check if the file exists and the script has write permissions.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llSay(0, &amp;quot;Something went wrong.\n&amp;quot; + body);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Takat_Su/Name2Key&amp;diff=782783</id>
		<title>User:Takat Su/Name2Key</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Takat_Su/Name2Key&amp;diff=782783"/>
		<updated>2010-03-05T19:07:00Z</updated>

		<summary type="html">&lt;p&gt;New Spore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}__NOTOC__&lt;br /&gt;
&lt;br /&gt;
== Name2Key ==&lt;br /&gt;
&#039;&#039;&#039;This is an update to Maeva Anatine&#039;s excellent suggestion for an updated name2key function.  Rather than overwrite all her work, I created this page.  The idea is DEFINITELY hers - I just am creating an alternate implementation.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Still missing Name2Key functions in your code? Still relying on external databases that are not always up to date with latests SL subscribers? &lt;br /&gt;
&lt;br /&gt;
Well now you can solve this by yourself, within your LSL script! All you have to do is to rely on LL Search engine! &lt;br /&gt;
&lt;br /&gt;
I put a kind of &amp;quot;library&amp;quot; and a sample of usage for your convenience&lt;br /&gt;
&lt;br /&gt;
To use, you make an llHttpRequest to the application running on the Google Application Server (a free service for moderate users).  The URL looks like this: http://name2key.appspot.com/?name=firstname%20lastname i.e. the first name of the person you want to look up is separated from their last name by &amp;quot;%20&amp;quot; (this is how the space character is coded in URLs).  The application doesn&#039;t care if you get the case correct.  The application will format the body of the return as follows:  firstname lastname:key, where firstname and lastname will be capitalized correctly and the key is either the key for the person or the null key (00000000-0000-0000-0000-000000000000). It really isn&#039;t much code if you prefer to code it into your main script rather than rely on an external script for the lookup.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Library ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
integer cmdName2Key = 19790;&lt;br /&gt;
integer cmdName2KeyResponse = 19791;&lt;br /&gt;
&lt;br /&gt;
list gRequests;&lt;br /&gt;
&lt;br /&gt;
key requestName2Key( string inName ) {&lt;br /&gt;
    list lNameParts = llParseString2List( inName, [&amp;quot; &amp;quot;], [] );&lt;br /&gt;
    string lFirstName = llList2String( lNameParts, 0 );&lt;br /&gt;
    string lLastName = llList2String( lNameParts, 1 );&lt;br /&gt;
    return llHTTPRequest( &amp;quot;http://name2key.appspot.com/?name=&amp;quot; + lFirstName + &amp;quot;%20&amp;quot; + lLastName, [], &amp;quot;&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
    link_message( integer inFromPrim, integer inCommand, string inName, key inKey ) {&lt;br /&gt;
        if( inCommand == cmdName2Key )&lt;br /&gt;
            gRequests += [requestName2Key( inName ), inKey ];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_response(key inKey, integer inStatus, list inMetaData, string inBody ) {&lt;br /&gt;
        integer lPosition = llListFindList( gRequests, [inKey]);&lt;br /&gt;
        if( lPosition != -1 ) {&lt;br /&gt;
            llMessageLinked( LINK_SET, cmdName2KeyResponse, inBody, llList2Key( gRequests, lPosition+1 ) );&lt;br /&gt;
            gRequests = llDeleteSubList( gRequests, lPosition, lPosition + 1 );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt; &lt;br /&gt;
== Usage sample ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
integer cmdName2Key = 19790;&lt;br /&gt;
integer cmdName2KeyResponse = 19791;&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        llMessageLinked( LINK_SET, cmdName2Key, &amp;quot;Test Name&amp;quot;, NULL_KEY );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message( integer inFromPrim, integer inCommand, string inKeyData, key inReturnedKey ) {&lt;br /&gt;
        if( inCommand == cmdName2KeyResponse ) {&lt;br /&gt;
            list lParts = llParseString2List( inKeyData, [&amp;quot;:&amp;quot;], [] );&lt;br /&gt;
            string lName = llList2String( lParts, 0 );&lt;br /&gt;
            key lKey = (key)llList2String(lParts, 1 );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
== Google App Python Code ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
from google.appengine.ext import webapp&lt;br /&gt;
from google.appengine.ext.webapp.util import run_wsgi_app&lt;br /&gt;
import urllib, urlparse&lt;br /&gt;
&lt;br /&gt;
kURL = &#039;http://vwrsearch.secondlife.com/client_search.php?session=00000000-0000-0000-0000-000000000000&amp;amp;q=&#039;&lt;br /&gt;
kProfile = &amp;quot;Resident profile&amp;quot;&lt;br /&gt;
kResult = &amp;quot;secondlife:///app/agent/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MainPage( webapp.RequestHandler ):&lt;br /&gt;
    def get(self):&lt;br /&gt;
        inName = self.request.get(&amp;quot;name&amp;quot;).upper()&lt;br /&gt;
        name = inName.replace(&amp;quot; &amp;quot;, &amp;quot;%20&amp;quot;)&lt;br /&gt;
        data = urllib.urlopen(kURL + name).read()&lt;br /&gt;
        start = data.index( kProfile )&lt;br /&gt;
        foundName = data[start+18:start+18+len(inName)]&lt;br /&gt;
	key = &#039;00000000-0000-0000-0000-000000000000&#039;&lt;br /&gt;
        if foundName.upper() == inName:&lt;br /&gt;
            start = data.index( kResult )&lt;br /&gt;
            key = data[start+len(kResult):start+len(kResult)+36]&lt;br /&gt;
        else:&lt;br /&gt;
            foundName =	inName&lt;br /&gt;
&lt;br /&gt;
        self.response.out.write(&amp;quot;%s:%s&amp;quot; % (foundName, key))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
application = webapp.WSGIApplication(&lt;br /&gt;
    [(&#039;/&#039;, MainPage)],&lt;br /&gt;
    debug = True)&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    run_wsgi_app(application)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
== app.yaml file ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
application: name2key&lt;br /&gt;
version: 1&lt;br /&gt;
runtime: python&lt;br /&gt;
api_version: 1&lt;br /&gt;
&lt;br /&gt;
handlers:&lt;br /&gt;
- url: .*&lt;br /&gt;
  script: name2key.py&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt; &lt;br /&gt;
== Comments ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
The main difference is that I wrote a an app for the google app engine that act as a relay.  Since I was going that far, it also parses the return, strips out all the extraneous stuff and just returns you the name and key separated by a colon.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
[[User:Takat Su|Takat Su]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}{{LSLC|Examples|Name2Key}}&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Reg_API_Examples&amp;diff=782773</id>
		<title>Linden Lab Official:Reg API Examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Reg_API_Examples&amp;diff=782773"/>
		<updated>2010-03-05T19:05:06Z</updated>

		<summary type="html">&lt;p&gt;New Spore: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{:Web Services Portal/navigation}}&lt;br /&gt;
&lt;br /&gt;
The following examples illustrate using the Reg API to register a new user with a specified Second Life first name and last name.  The example code first checks to determine the availability of the selected first and last name, and either registers the user or returns an error message if the name is already taken.&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LLSD library downloads ==&lt;br /&gt;
&lt;br /&gt;
To use a library:&lt;br /&gt;
# Remove the -lib suffix from the file name.&lt;br /&gt;
# Put the file in the same directory as the application code, such as the examples below.&lt;br /&gt;
&lt;br /&gt;
* [https://secure-web10.secondlife.com/developers/third_party_reg/llsd_libs/llsd.rb-lib Ruby LLSD library] (version 1.3)&lt;br /&gt;
* [https://secure-web10.secondlife.com/developers/third_party_reg/llsd_libs/llsd.php-lib PHP LLSD library] (version 1.0)&lt;br /&gt;
* [https://secure-web10.secondlife.com/developers/third_party_reg/llsd_libs/llsd.py-lib Python LLSD library] (version 1.2)&lt;br /&gt;
* [https://secure-web10.secondlife.com/developers/third_party_reg/llsd_libs/llsd.pm-lib Perl LLSD library] (version 1.0)&lt;br /&gt;
&lt;br /&gt;
NOTE: The PHP scripts only work with PHP4. &lt;br /&gt;
&lt;br /&gt;
An externally developed Java implementation of LLSD and RegAPI is available at http://mimuve.cs.st-andrews.ac.uk/llsd-java/src/llsd-java-0.2.1.zip . Code written by Xugu Madison, copyright held by University of St Andrews, and made available under the BSD license. Tested with Java 1.5.&lt;br /&gt;
&lt;br /&gt;
Question: what version of each language is required?&lt;br /&gt;
&lt;br /&gt;
== Example code ==&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
This ruby example shows how to use the Registration API. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;ruby&amp;gt;require &#039;llsd&#039;&lt;br /&gt;
&lt;br /&gt;
# 0 - get capability urls&lt;br /&gt;
# 1 - get error codes&lt;br /&gt;
# 2 - get the available last names&lt;br /&gt;
# 3 - check to see of a username + last name combo is taken&lt;br /&gt;
# 4 - register the user with this username + last name combo&lt;br /&gt;
&lt;br /&gt;
get_capabilities_url = &amp;quot;https://cap.secondlife.com/get_reg_capabilities&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# grab command line args&lt;br /&gt;
if ARGV.length == 3&lt;br /&gt;
  first_name = ARGV[0]&lt;br /&gt;
  last_name = ARGV[1]&lt;br /&gt;
  password = ARGV[2]&lt;br /&gt;
else&lt;br /&gt;
  puts &amp;quot;Please pass in your second life first name, last name, and password as arguments.&amp;quot;&lt;br /&gt;
  puts &amp;quot;For example: ruby registration_api.rb joe linden 1234&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  exit&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# 0 - Get Capability URLS  ##############################################&lt;br /&gt;
puts &amp;quot;========== Getting capabilities ===========\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
post_body = &amp;quot;first_name=#{first_name}&amp;amp;last_name=#{last_name}&amp;amp;password=#{password}&amp;quot; &lt;br /&gt;
# create a url-encoded string to POST&lt;br /&gt;
response_xml = LLSD.post_urlencoded_data get_capabilities_url, post_body &lt;br /&gt;
# POST the capability url to get capabilities&lt;br /&gt;
&lt;br /&gt;
puts &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
puts response_xml&lt;br /&gt;
&lt;br /&gt;
puts &amp;quot;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
capability_urls = LLSD.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
capability_urls.each { |k,v| puts &amp;quot;#{k} =&amp;gt; #{v}&amp;quot;} # print out capabilities&lt;br /&gt;
&lt;br /&gt;
# 1 - Print out error codes  ##############################################&lt;br /&gt;
puts &amp;quot;\n\n========== Get Error Codes Example ===========\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if capability_urls[&#039;get_error_codes&#039;]  &lt;br /&gt;
  response_xml = LLSD.http_raw capability_urls[&#039;get_error_codes&#039;] &lt;br /&gt;
  # GET the capability url for getting error codes&lt;br /&gt;
  &lt;br /&gt;
  puts &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
  puts response_xml&lt;br /&gt;
  &lt;br /&gt;
  error_codes = LLSD.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
  error_codes.each {|error| puts &amp;quot;#{error[0]} =&amp;gt; #{error[1]}&amp;quot;} &lt;br /&gt;
  # print out all error codes&lt;br /&gt;
else&lt;br /&gt;
  puts &amp;quot;Get_error_codes capability not granted to #{first_name} #{last_name}.  Exiting Prematurely ...&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# 2 - Get Last Names Example  ##############################################&lt;br /&gt;
puts &amp;quot;\n\n========== Get Last Names Example ===========\n&amp;quot;&lt;br /&gt;
if capability_urls[&#039;get_last_names&#039;]&lt;br /&gt;
  response_xml = LLSD.http_raw capability_urls[&#039;get_last_names&#039;] &lt;br /&gt;
  # GET the capability url for getting last names and ids&lt;br /&gt;
&lt;br /&gt;
  puts &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
  puts response_xml&lt;br /&gt;
  &lt;br /&gt;
  last_names = LLSD.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
  last_names.each {|k,v| puts &amp;quot;#{k} =&amp;gt; #{v}&amp;quot;} # print out last names&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  # 3 - Check Name Example  ##############################################&lt;br /&gt;
  print &amp;quot;\n\n========== Check Name Example ===========\n&amp;quot;&lt;br /&gt;
  if capability_urls[&#039;check_name&#039;]&lt;br /&gt;
    random_username = &#039;tester&#039; + Kernel.rand(10000).to_s # Generate a random username&lt;br /&gt;
    valid_last_name_id = last_names.keys.first # Get the first valid last name id&lt;br /&gt;
    params_hash = {&amp;quot;username&amp;quot; =&amp;gt; random_username, &amp;quot;last_name_id&amp;quot; =&amp;gt; valid_last_name_id } &lt;br /&gt;
    # put it in a hash&lt;br /&gt;
&lt;br /&gt;
    xml_to_post = LLSD.to_xml(params_hash) # convert it to llsd xml&lt;br /&gt;
&lt;br /&gt;
    response_xml = LLSD.post_xml(capability_urls[&#039;check_name&#039;], xml_to_post)&lt;br /&gt;
&lt;br /&gt;
    puts &amp;quot;posted xml:&amp;quot; # Print out response xml&lt;br /&gt;
    puts xml_to_post&lt;br /&gt;
&lt;br /&gt;
    puts &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
    puts response_xml&lt;br /&gt;
&lt;br /&gt;
    is_name_available = LLSD.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
    puts &amp;quot;Result (is name available?): #{is_name_available}&amp;quot; # Print the result&lt;br /&gt;
    &lt;br /&gt;
    # 4 - Create User Example  ##############################################&lt;br /&gt;
    puts &amp;quot;\n\n========== Create User Example ===========\n&amp;quot;&lt;br /&gt;
    if is_name_available and capability_urls[&#039;create_user&#039;]:&lt;br /&gt;
      # fill in the rest of the hash we started in example 2 with valid data&lt;br /&gt;
      params_hash[&amp;quot;email&amp;quot;] = random_username + &amp;quot;@ben.com&amp;quot;&lt;br /&gt;
      params_hash[&amp;quot;password&amp;quot;] = &amp;quot;123123abc&amp;quot;&lt;br /&gt;
      params_hash[&amp;quot;dob&amp;quot;] = &amp;quot;1980-01-01&amp;quot;&lt;br /&gt;
      &lt;br /&gt;
      xml_to_post = LLSD.to_xml(params_hash) # convert it to llsd xml&lt;br /&gt;
&lt;br /&gt;
      response_xml = LLSD.post_xml(capability_urls[&#039;create_user&#039;], xml_to_post)&lt;br /&gt;
&lt;br /&gt;
      puts &amp;quot;posted xml:&amp;quot; # Print out response xml&lt;br /&gt;
      puts xml_to_post&lt;br /&gt;
&lt;br /&gt;
      puts &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
      puts response_xml&lt;br /&gt;
&lt;br /&gt;
      result_hash = LLSD.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
      puts &amp;quot;New agent id: #{result_hash[&#039;agent_id&#039;]}&amp;quot; # Print the result&lt;br /&gt;
      &lt;br /&gt;
      # ALL DONE!!&lt;br /&gt;
    else&lt;br /&gt;
      puts &amp;quot;Create_user capability not granted to #{first_name} #{last_name}. Exiting Prematurely ...&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    puts &amp;quot;Check_name capability not granted to #{first_name} #{last_name}. Exiting Prematurely ...&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
else&lt;br /&gt;
  puts &amp;quot;Get_last_names capability not granted to #{first_name} #{last_name}. Exiting Prematurely...&amp;quot;&lt;br /&gt;
end&amp;lt;/ruby&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;import llsd&lt;br /&gt;
import urllib2, random, sys&lt;br /&gt;
&lt;br /&gt;
# This python example shows how to use the Registration API. The example goes as follows:&lt;br /&gt;
&lt;br /&gt;
# 0 - get capability urls&lt;br /&gt;
# 1 - get error codes&lt;br /&gt;
# 2 - get the available last names&lt;br /&gt;
# 3 - check to see of a username + last name combo is taken&lt;br /&gt;
# 4 - register the user with this username + last name combo&lt;br /&gt;
&lt;br /&gt;
get_capabilities_url = &amp;quot;https://cap.secondlife.com/get_reg_capabilities&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# grab command line args&lt;br /&gt;
if len(sys.argv) == 4:&lt;br /&gt;
  first_name = sys.argv[1]&lt;br /&gt;
  last_name = sys.argv[2]&lt;br /&gt;
  password = sys.argv[3]&lt;br /&gt;
else:&lt;br /&gt;
  print &amp;quot;Please pass in your second life first name, last name, and password as arguments. For example:&amp;quot;&lt;br /&gt;
  print &amp;quot;python registration_api.py registration mackay 1234&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  sys.exit()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# 0 - Get Capability URLS #################################################################&lt;br /&gt;
print &amp;quot;========== Getting capabilities ===========&amp;quot;&lt;br /&gt;
&lt;br /&gt;
post_body = &amp;quot;first_name=%s&amp;amp;last_name=%s&amp;amp;password=%s&amp;quot; % (first_name, last_name, password) # create a url-encoded string to POST&lt;br /&gt;
response_xml = urllib2.urlopen(get_capabilities_url, post_body).read() # POST the capability url to get capabilities&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
print response_xml&lt;br /&gt;
&lt;br /&gt;
capability_urls = llsd.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
for id, name in capability_urls.items(): # Print out capabilities&lt;br /&gt;
    print &amp;quot;%s =&amp;gt; %s&amp;quot; % (id, name)&lt;br /&gt;
    &lt;br /&gt;
# 1 - Print out error codes ###############################################################&lt;br /&gt;
if &#039;get_error_codes&#039; in capability_urls:&lt;br /&gt;
    print &amp;quot;\n\n========== Get Error Codes Example ===========\n&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    response_xml = urllib2.urlopen(capability_urls[&#039;get_error_codes&#039;]).read() # GET the capability url for getting error codes&lt;br /&gt;
  &lt;br /&gt;
    print &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
    print response_xml&lt;br /&gt;
  &lt;br /&gt;
    error_codes = llsd.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
    for error in error_codes: # Print out capabilities&lt;br /&gt;
        print &amp;quot;%s =&amp;gt; %s&amp;quot; % (error[0], error[1])&lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;Get_error_codes capability not granted to %s %s. Now Exiting Prematurely ...&amp;quot; % (first_name, last_name)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
# 2 - Get Last Names Example ##############################################################&lt;br /&gt;
if &#039;get_last_names&#039; in capability_urls:&lt;br /&gt;
    print &amp;quot;\n\n========== Get Last Names Example ===========&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    response_xml = urllib2.urlopen(capability_urls[&#039;get_last_names&#039;]).read() # GET the capability url for getting last names and ids&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
    print response_xml&lt;br /&gt;
    &lt;br /&gt;
    last_names = llsd.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
    for id, name in last_names.items(): # Print out last names&lt;br /&gt;
        print &amp;quot;%s =&amp;gt; %s&amp;quot; % (id, name)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    # 3 - Check Name Example ##################################################################&lt;br /&gt;
    if &#039;check_name&#039; in capability_urls:&lt;br /&gt;
        print &amp;quot;\n\n========== Check Name Example ===========&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        random_username = &#039;benny&#039; + str(random.randrange(100,10000)) # Generate a random username&lt;br /&gt;
        valid_last_name_id = last_names.keys()[0] # Get the first valid last name id&lt;br /&gt;
        params_hash = {&amp;quot;username&amp;quot;: random_username, &amp;quot;last_name_id&amp;quot;: valid_last_name_id } # put it in a hash&lt;br /&gt;
&lt;br /&gt;
        xml_to_post = llsd.toXML(params_hash) # convert it to llsd xml&lt;br /&gt;
&lt;br /&gt;
        response_xml = urllib2.urlopen(capability_urls[&#039;check_name&#039;], xml_to_post).read() &lt;br /&gt;
&lt;br /&gt;
        print &amp;quot;posted xml &amp;quot; # Print out response xml&lt;br /&gt;
        print xml_to_post&lt;br /&gt;
&lt;br /&gt;
        print &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
        print response_xml&lt;br /&gt;
&lt;br /&gt;
        is_name_available = llsd.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
        print &amp;quot;Result (is name available?): %s&amp;quot; % (is_name_available) # Print the result&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        # 4 - Create User Example #################################################################&lt;br /&gt;
        if is_name_available and &#039;create_user&#039; in capability_urls:&lt;br /&gt;
            print &amp;quot;\n\n========== Create User Example ===========&amp;quot;&lt;br /&gt;
&lt;br /&gt;
            # fill in the rest of the hash we started in example 2 with valid data&lt;br /&gt;
            params_hash[&amp;quot;email&amp;quot;] = random_username + &amp;quot;@ben.com&amp;quot;&lt;br /&gt;
            params_hash[&amp;quot;password&amp;quot;] = &amp;quot;123123abc&amp;quot;&lt;br /&gt;
            params_hash[&amp;quot;dob&amp;quot;] = &amp;quot;1980-01-01&amp;quot;&lt;br /&gt;
            &lt;br /&gt;
            xml_to_post = llsd.toXML(params_hash) # convert it to llsd xml&lt;br /&gt;
&lt;br /&gt;
            response_xml = urllib2.urlopen(capability_urls[&#039;create_user&#039;], xml_to_post).read() &lt;br /&gt;
&lt;br /&gt;
            print &amp;quot;posted xml &amp;quot; # Print out response xml&lt;br /&gt;
            print xml_to_post&lt;br /&gt;
&lt;br /&gt;
            print &amp;quot;xml response:&amp;quot; # Print out response xml&lt;br /&gt;
            print response_xml&lt;br /&gt;
&lt;br /&gt;
            result_hash = llsd.parse(response_xml) # Parse the xml&lt;br /&gt;
&lt;br /&gt;
            print &amp;quot;New agent id: %s&amp;quot; % (result_hash[&amp;quot;agent_id&amp;quot;]) # Print the result&lt;br /&gt;
    &lt;br /&gt;
            &lt;br /&gt;
            # ALL DONE!!&lt;br /&gt;
        else:&lt;br /&gt;
            print &amp;quot;create_user capability not granted to %s %s. Now Exiting Prematurely ...&amp;quot; % (first_name, last_name)&lt;br /&gt;
            &lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;check_name capability not granted to %s %s. Now Exiting Prematurely ...&amp;quot; % (first_name, last_name)&lt;br /&gt;
        &lt;br /&gt;
else:&lt;br /&gt;
    print &amp;quot;get_last_names capability not granted to %s %s. Now Exiting Prematurely ...&amp;quot; % (first_name, last_name)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
NOTE: This uses PHP4.  See also [[Registration_API#Guidelines_and_tips|Guidelines and tips]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
require_once(&#039;llsd.php&#039;);&lt;br /&gt;
&lt;br /&gt;
// FILL THESE IN WITH YOUR OWN CAPABILITY URLS&lt;br /&gt;
define(&#039;URI_CREATE_USER&#039;, &#039;?????????&#039;);&lt;br /&gt;
define(&#039;URI_GET_LAST_NAMES&#039;, &#039;?????????&#039;);&lt;br /&gt;
define(&#039;URI_CHECK_NAME&#039;, &#039;?????????&#039;);&lt;br /&gt;
&lt;br /&gt;
if ($_SERVER[&#039;REQUEST_METHOD&#039;] == &#039;POST&#039;)&lt;br /&gt;
{&lt;br /&gt;
    if (is_name_available($_POST[&#039;username&#039;], $_POST[&#039;last_name_id&#039;]))&lt;br /&gt;
    {&lt;br /&gt;
        $user = array&lt;br /&gt;
        (&lt;br /&gt;
            &#039;username&#039;     =&amp;gt; $_POST[&#039;username&#039;],&lt;br /&gt;
            &#039;last_name_id&#039; =&amp;gt; (int)$_POST[&#039;last_name_id&#039;],&lt;br /&gt;
            &#039;email&#039;        =&amp;gt; $_POST[&#039;email&#039;],&lt;br /&gt;
            &#039;password&#039;     =&amp;gt; $_POST[&#039;password&#039;],&lt;br /&gt;
            &#039;dob&#039;          =&amp;gt; $_POST[&#039;dob_year&#039;].&#039;-&#039;.$_POST[&#039;dob_month&#039;].&#039;-&#039;.$_POST[&#039;dob_day&#039;]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        $result = llsd_post(URI_CREATE_USER, $user);&lt;br /&gt;
        print $result[&#039;agent_id&#039;];&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        print &#039;SL name not available.&#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Create Second Life Account&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;lt;?php print $_SERVER[&#039;PHP_SELF&#039;]; ?&amp;gt;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;First name:&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;username&amp;quot; size=&amp;quot;25&amp;quot; maxlength=&amp;quot;31&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Last name:&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
  &amp;lt;select name=&amp;quot;last_name_id&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;?php&lt;br /&gt;
  $last_names = llsd_get(URI_GET_LAST_NAMES);&lt;br /&gt;
  foreach ($last_names as $last_name_id =&amp;gt; $name)&lt;br /&gt;
  {&lt;br /&gt;
      print &#039;&amp;lt;option value=&amp;quot;&#039;.$last_name_id.&#039;&amp;quot;&amp;gt;&#039;.$name.&#039;&amp;lt;/option&amp;gt;&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  ?&amp;gt;&lt;br /&gt;
  &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Password:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot; size=&amp;quot;20&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Email:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;email&amp;quot; size=&amp;quot;35&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Date of brith:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;dob_day&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;?php&lt;br /&gt;
    $days = get_days();&lt;br /&gt;
    foreach ($days as $key =&amp;gt; $value) { print &#039;&amp;lt;option value=&amp;quot;&#039;.$key.&#039;&amp;quot; &#039;.$selected.&#039;&amp;gt;&#039;.$value.&#039;&amp;lt;/option&amp;gt;&#039;; }&lt;br /&gt;
    ?&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;select name=&amp;quot;dob_month&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;?php&lt;br /&gt;
    $months = get_months();&lt;br /&gt;
    foreach ($months as $key =&amp;gt; $value) { print &#039;&amp;lt;option value=&amp;quot;&#039;.$key.&#039;&amp;quot; &#039;.$selected.&#039;&amp;gt;&#039;.$value.&#039;&amp;lt;/option&amp;gt;&#039;; }&lt;br /&gt;
    ?&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;select name=&amp;quot;dob_year&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;?php&lt;br /&gt;
    $years = get_years();&lt;br /&gt;
    foreach ($years as $key =&amp;gt; $value) { print &#039;&amp;lt;option value=&amp;quot;&#039;.$key.&#039;&amp;quot; &#039;.$selected.&#039;&amp;gt;&#039;.$value.&#039;&amp;lt;/option&amp;gt;&#039;; } &lt;br /&gt;
    ?&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Create SL Account&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
function get_months()&lt;br /&gt;
{&lt;br /&gt;
    $months = array();&lt;br /&gt;
    for ($i = 1; $i &amp;lt;= 12; $i++)&lt;br /&gt;
    {&lt;br /&gt;
        $key = date(&#039;n&#039;, mktime(0, 0, 0, $i, 1, 2000));&lt;br /&gt;
        $value = date(&#039;M.&#039;, mktime(0, 0, 0, $i, 1, 2000));&lt;br /&gt;
        $months[sprintf(&amp;quot;%02d&amp;quot;, $key)] = $value;&lt;br /&gt;
    }&lt;br /&gt;
    return $months;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function get_years()&lt;br /&gt;
{&lt;br /&gt;
    $today = getdate();&lt;br /&gt;
    $max_year = $today[&#039;year&#039;] - 90;&lt;br /&gt;
    $min_year = $today[&#039;year&#039;] - 13;&lt;br /&gt;
&lt;br /&gt;
    $years = array();&lt;br /&gt;
    for ($i = $min_year; $i &amp;gt;= $max_year; $i--)&lt;br /&gt;
    {&lt;br /&gt;
        $years[$i] = $i;&lt;br /&gt;
    }&lt;br /&gt;
    return $years;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function get_days()&lt;br /&gt;
{&lt;br /&gt;
    $days = array();&lt;br /&gt;
    for ($i = 1; $i &amp;lt;= 31; $i++)&lt;br /&gt;
    {&lt;br /&gt;
        $days[sprintf(&amp;quot;%02d&amp;quot;, $i)] = sprintf(&amp;quot;%02d&amp;quot;, $i);&lt;br /&gt;
    }&lt;br /&gt;
    return $days;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function is_name_available($username, $last_name_id)&lt;br /&gt;
{&lt;br /&gt;
    $params = array(&#039;username&#039; =&amp;gt; $username, &#039;last_name_id&#039; =&amp;gt; (int)$last_name_id);&lt;br /&gt;
    if (llsd_post(URI_CHECK_NAME, $params) == &#039;true&#039;)&lt;br /&gt;
    {&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
    return false;&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RegAPI|Sample Code]]&lt;br /&gt;
[[Category:Web Service APIs]]&lt;/div&gt;</summary>
		<author><name>New Spore</name></author>
	</entry>
</feed>