String2Hex

From Second Life Wiki
Jump to navigation Jump to search

Full Unicode Support

Uses UTF-8 encoding of characters. If you can get the character into a string in LSL, this will encode that character in hex.

For performance reasons you should really just get use to using Base64. Since LSL has no hex functions, implementing them comes at a great performance cost.

<lsl> string String2Hex(string str){

   string b64 = (string)llParseString2List(llStringToBase64(str), ["="], []);
   integer length = (llStringLength(b64) * 3) >> 2;
   b64 += "AAAAAAA"; // we will trim these off in the end, this works around SVC-104.
   integer count = -3;
   integer position = -4;
   string out;
   while ((count += 3) < length) {
       integer I = llBase64ToInteger(llGetSubString(b64, position += 4, position + 7));
       //This takes the first 4 base64 characters (the other 4 are ignored), gets the integer
       //Takes the integer and remaps the values so when the two integers are converted back to base64
       //The base64 value is the same as the original 4 base64 character's hex value.
       //This should be converted into a loop.
       integer A = (I >>  2) & 0x3C000000; //28 -> 26
       integer B = (I >>  4) & 0x00F00000; //24 -> 20
       integer C = (I >>  6) & 0x0003C000; //20 -> 14
       integer D = (I << 10) & 0x3C000000; //16 -> 26
       integer E = (I <<  8) & 0x00F00000; //12 -> 20
       integer F = (I <<  6) & 0x0003C000; // 8 -> 14
       out += llGetSubString( //ABCDEF
           llInsertString(
               llIntegerToBase64(
                   A + B + C + 0xD34D0000
                   - (0xF8000000 * (A / 0x28000000)) //lowercase=0x90000000, uppercase=0xF8000000
                   - (0x03E00000 * (B / 0x00A00000)) //lowercase=0x02400000, uppercase=0x03E00000
                   - (0x000F8000 * (C / 0x00028000)) //lowercase=0x00090000, uppercase=0x000F8000
               ),
               3, //4 b64 -> 3 bytes -> 6 hex char ~> 6 b4 -> 36 bits, integer < 36 bits
               llIntegerToBase64( 
                   D + E + F + 0xD34D0000
                   - (0xF8000000 * (D / 0x28000000)) //lowercase=0x90000000, uppercase=0xF8000000
                   - (0x03E00000 * (E / 0x00A00000)) //lowercase=0x02400000, uppercase=0x03E00000
                   - (0x000F8000 * (F / 0x00028000)) //lowercase=0x00090000, uppercase=0x000F8000
               )
           ), 0, 5);
   }
   return llGetSubString(out, 0, length + length - 1);

}

string Hex2String(string hex) {

   integer length = (llStringLength(hex) + 1) & -2;
   while(length)
       hex = llInsertString(hex, length -= 2, "%");
   return llUnescapeURL(hex); //lol

} </lsl>

Limited ASCII-7 Support

These functions only works for ASCII-7 non-control characters.

<lsl> string c_chr=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";


// http://wiki.secondlife.com/wiki/Int2Hex string int2hex(integer x){ string toret; do{ toret=llGetSubString("0123456789ABCDEF",x&0x0000000F,x&0x0000000F)+toret; }while (x=x>>4&0x0FFFFFFF); return toret; }

string str2hex(string str){ string ret=""; integer strlen=llStringLength(str); integer i=0; for(;i<strlen;++i){ ret+=int2hex(32+llSubStringIndex(c_chr,llGetSubString(str,i,i))); } return ret; }

string hex2str(string str){ string ret=""; integer strlen=llStringLength(str); integer i=0;integer index; for(;i<strlen;i+=2){ index=((integer)("0x"+llGetSubString(str,i,i+1)))-32; ret+=llGetSubString(c_chr,index,index); } return ret; }

default{ state_entry(){ llOwnerSay(str2hex("test ~")); llOwnerSay(hex2str("74657374207E")); } } </lsl>