Page 1 of 1

[JS] UCS2 safe base64 decoder/encoder for Gecko browsers

Posted: Tue Aug 08, 2006 2:01 pm
by Weirdan

Code: Select all

UCS2B64 = {
    splitStream : function(str) {
        var stream = str.toString();
        var ret = '';
        for(var i = 0, l = stream.length; i < l; i++) {
            ret += String.fromCharCode(stream.charCodeAt(i) >> 8);
            ret += String.fromCharCode(stream.charCodeAt(i) & 0x00FF);
        }
        return ret;
    },
    joinStream : function(stream) {
        var ret = '';   
        if(stream.length % 2)
            throw '[UCS2B64.joinStream] Invalid stream, must consist of even number of elements';
        for(var i = 0, l = stream.length; i < l; i += 2) {
            ret += String.fromCharCode((stream.charCodeAt(i) << 8) + stream.charCodeAt(i+1));
        }
        return ret;
    },
    encode : function(input) {
        if(!input && (input !== 0)) return '';
        return btoa(UCS2B64.splitStream(input));
    },
    decode : function(input) {
        return UCS2B64.joinStream(atob(input.toString()));
    }
} 

Posted: Tue Aug 08, 2006 6:39 pm
by Ollie Saunders
Looks very nice, does it work?

Posted: Tue Aug 08, 2006 7:58 pm
by Weirdan
of course it doesImage

Posted: Tue Aug 08, 2006 8:00 pm
by Ollie Saunders
OK. Then I have no criticism, you may collect 200 dollars. 8)

Posted: Tue Aug 08, 2006 8:15 pm
by Weirdan
PayPal them to weirdan@mgail.com please Image

Posted: Tue Aug 08, 2006 9:07 pm
by feyd
mgail? .. not gmail? Image

Posted: Tue Aug 08, 2006 9:09 pm
by Ambush Commander
Whatever it is, it's obviously AJAX. I mean, come on, can you get more minimal than this?

Code: Select all

<script language="JavaScript" type="text/javascript">
		if(window.top != window) { document.write('<img src="/frame/track.gif" style="height : 0; width : 0; border-width : 0; display: none">'); }
		</script><script type="text/javascript">
document.write('<img src="/unique/track.gif?referrer=about%3Ablank" style="height : 0; width : 0; border-width : 0; display: none">');
</script>

Posted: Tue Aug 08, 2006 9:25 pm
by Weirdan
feyd, don't spoil my e-mail to these evil spiders :)

AC, I think I don't follow you here... what has the snippet you posted to do with base64 encoding?

edit: and no, it wasn't intended for use in AJAX enviroment (we have escape() function for that). I used it to encode russian strings in one of my greasemonkey scripts.

Posted: Tue Aug 08, 2006 9:29 pm
by Ambush Commander
No, I was just saying that was what the http://mgail.com/ website was. Loaded it up and got a blank screen. So yes, Off-Topic.

Hmm... I'd like to see some JavaScript unit tests for that. Do they even have unit testing for JS?

Posted: Tue Aug 08, 2006 9:31 pm
by Weirdan
Do they even have unit testing for JS?
Yes, we do ;) http://jsunit.net/

Yet I don't really see what to test here...

Posted: Tue Aug 08, 2006 9:32 pm
by Ambush Commander
The functions. I mean, you've probably hand-checked it, but unit tests are forever.

Posted: Tue Aug 08, 2006 9:45 pm
by Weirdan
The functions. I mean, you've probably hand-checked it, but unit tests are forever.
The only test I see is that it should throw an exception on uneven input streams when decoding (for example, when decoding data encoded with unwrapped btoa())

Do you see any other edge cases I should test for?

Posted: Tue Aug 08, 2006 11:12 pm
by Weirdan
here is unit test:

Code: Select all

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>UCS2B64 tests</title>
<link rel="stylesheet" type="text/css" href="../jsunit/css/jsUnitStyle.css">
<script language="JavaScript" type="text/javascript" src="../jsunit/app/jsUnitCore.js"></script>
<script language="JavaScript" type="text/javascript" src="UCS2B64.js"></script>
<script language="JavaScript" type="text/javascript">
<![CDATA[
function testEncodingUndefinedReturnsEmptyString() {
    assertEquals(UCS2B64.encode(undefined), '');
}
function testEncodingZeroDoesNotReturnEmptyString() {
    assertNotEquals(UCS2B64.encode(0), '');
}
function testEncodingObjectCallsObjectsToStringMethod() {
    var q = {
        callcount:0,
        toString: function() {
            this.callcount++;
            return 'object q';
        }
    };
    UCS2B64.encode(q);
    assertEquals(q.callcount, 1);
}
function testEncodingAsciiCharacter() {
    assertEquals('AEE=', UCS2B64.encode('A'));
}
function testEncodingRussianCharacter() {
    assertEquals('BBA=', UCS2B64.encode('А'));
}
function testCanDecodeWhatIEncoded() {
    var str = 'QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM' +
              '<>?~!@#$%^&*()_+`1234567890-=q' +
              'wertyuiop[]asdfghjkl;\'zxcvbnm' + 
              ',./ёйцукенгшщзхъфывапролджэячс' + 
              'митьбю.Ё"ЙЦУКЕНГШЩЗХЪФЫВАПРОЛД' + 
              'ЖЭЯЧСМИТЬБЮ,';
    assertEquals(str, UCS2B64.decode(UCS2B64.encode(str)));
}
function testDecodingBreaksOnUnEvenInput() {
    var q = undefined;
    try {
        UCS2B64.decode(btoa('asd'));
    } catch(e) {
        q = e.toString();
    }
    assertEquals("exception must be thrown on uneven length after atob()", '[UCS2B64.joinStream] Invalid stream, must consist of even number of elements', q);
}
]]>
</script>
</head>

<body>
<h1>UCS2B64 Tests</h1>

<p>This page contains tests for the UCS2B64 
    functions. To see them, take a look at the source.</p>
</body>
</html>
and thanks for heads up, I didn't handle encoding of 0 properly

Posted: Tue Aug 08, 2006 11:17 pm
by Weirdan
unfortunately, GeSHi trying to be smart =|

Posted: Tue Aug 08, 2006 11:44 pm
by Jenk
off topic again.. the mgail site is tracking refferers... if you haven't guessed:

Code: Select all

document.write('<img src="/unique/track.gif?referrer=about%3Ablank" style="height : 0; width : 0; border-width : 0; display: none">');