Difference between revisions of "String2Hex"

From Second Life Wiki
Jump to navigation Jump to search
(updated <lsl> tags to <source> tags)
 
(4 intermediate revisions by 2 users not shown)
Line 3: Line 3:
Uses UTF-8 encoding of characters. If you can get the character into a string in LSL, this will encode that character in hex.
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>
For performance reasons you should really just get used to using Base64. Since LSL has no hex functions, implementing them comes at a great performance cost.
 
<source lang="lsl2">
string String2Hex(string str){
string String2Hex(string str){
     string b64 = (string)llParseString2List(llStringToBase64(str), ["="], []);
     string b64 = (string)llParseString2List(llStringToBase64(str), ["="], []);
     integer length = (llStringLength(b64) * 3) >> 2;
     integer length = ((llStringLength(b64) * 3) >> 1) & -2;
     b64 += "AAAAAAA"; // we will trim these off in the end, this works around SVC-104.
     b64 += "AAAAAAA"; // we will trim these off in the end, this works around SVC-104.
     integer count = -3;
     integer count = -3;
     integer position = -4;
     integer position = -4;
     string out;
     string out;
     while ((count += 3) < length) {
     while ((count += 6) < length) {
         integer I = llBase64ToInteger(llGetSubString(b64, position += 4, position + 7));
         integer I = llBase64ToInteger(llGetSubString(b64, position += 4, position + 7)) | 1;//This is a bottle neck
        //This takes the first 4 base64 characters (the other 4 are ignored), gets the integer
         string T = "";
        //Takes the integer and remaps the values so when the two integers are converted back to base64
         do {
        //The base64 value is the same a the original 4 base64 characters hex value.
            integer A = (I >>  2) & 0x3C000000; //28 -> 26
         //This should be converted into a loop.
            integer B = (I >>  4) & 0x00F00000; //24 -> 20
         integer A = (I >>  2) & 0x3C000000; //28 -> 26
            integer C = (I >>  6) & 0x0003C000; //20 -> 14
        integer B = (I >>  4) & 0x00F00000; //24 -> 20
            T += llGetSubString( //ABC
        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(
                 llIntegerToBase64(
                     A + B + C + 0xD34D0000
                     A + B + C + 0xD34D0000
Line 30: Line 26:
                     - (0x03E00000 * (B / 0x00A00000)) //lowercase=0x02400000, uppercase=0x03E00000
                     - (0x03E00000 * (B / 0x00A00000)) //lowercase=0x02400000, uppercase=0x03E00000
                     - (0x000F8000 * (C / 0x00028000)) //lowercase=0x00090000, uppercase=0x000F8000
                     - (0x000F8000 * (C / 0x00028000)) //lowercase=0x00090000, uppercase=0x000F8000
                 ),
                 ), 0, 3);
                3, //4 b64 -> 3 bytes -> 6 hex char ~> 6 b4 -> 36 bits, integer < 36 bits
        } while (((I = (I << 12)) & 0x1EE7);
                llIntegerToBase64(  
        out += T;//This is a bottle neck
                    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);
     return llGetSubString(out, 0, length - 1);
}
}


Line 49: Line 39:
     return llUnescapeURL(hex); //lol
     return llUnescapeURL(hex); //lol
}
}
</lsl>
</source>


==Limited ASCII-7 Support==
==Limited ASCII-7 Support==
Line 55: Line 45:
These functions only works for ASCII-7 non-control characters.  
These functions only works for ASCII-7 non-control characters.  


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


Line 95: Line 85:
}
}
}
}
</lsl>
</source>

Latest revision as of 18:00, 5 April 2015

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 used to using Base64. Since LSL has no hex functions, implementing them comes at a great performance cost.

string String2Hex(string str){
    string b64 = (string)llParseString2List(llStringToBase64(str), ["="], []);
    integer length = ((llStringLength(b64) * 3) >> 1) & -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 += 6) < length) {
        integer I = llBase64ToInteger(llGetSubString(b64, position += 4, position + 7)) | 1;//This is a bottle neck
        string T = "";
        do {
            integer A = (I >>  2) & 0x3C000000; //28 -> 26
            integer B = (I >>  4) & 0x00F00000; //24 -> 20
            integer C = (I >>  6) & 0x0003C000; //20 -> 14
            T += llGetSubString( //ABC
                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
                ), 0, 3);
        } while (((I = (I << 12)) & 0x1EE7);
        out += T;//This is a bottle neck
    }
    return llGetSubString(out, 0, length - 1);
}

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

Limited ASCII-7 Support

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

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"));
	}
}