String2Hex

From Second Life Wiki
Revision as of 13:13, 13 March 2014 by Strife Onizuka (talk | contribs) (→‎Full Unicode Support: keeps the code from choking on badly formed input, no idea what it does in this case.)
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.

<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;
   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 a the original 4 base64 characters 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>