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

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

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

Post 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()));
    }
} 
Last edited by Weirdan on Tue Aug 08, 2006 11:20 pm, edited 2 times in total.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Looks very nice, does it work?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

of course it doesImage
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

OK. Then I have no criticism, you may collect 200 dollars. 8)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

PayPal them to weirdan@mgail.com please Image
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

mgail? .. not gmail? Image
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post 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>
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post 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.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post 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?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post 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...
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

The functions. I mean, you've probably hand-checked it, but unit tests are forever.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post 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?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post 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
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

unfortunately, GeSHi trying to be smart =|
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post 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">');
Post Reply