Skip to content

Instantly share code, notes, and snippets.

@qbyt
Created January 12, 2011 15:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qbyt/776329 to your computer and use it in GitHub Desktop.
Save qbyt/776329 to your computer and use it in GitHub Desktop.
A CoffeeScript port of the Javascript version by Nicholas C. Zakas(2009) - https://github.com/nzakas/computer-science-in-javascript
/*
Base 64 implementation in CoffeeScript (Compiled JS)
Converted from Base 64 implementation in JavaScript - Nicholas C. Zakas (2009)
(https://github.com/nzakas/computer-science-in-javascript)
*/
/*
Base64-encodes a string of text.
@param {String} text The text to encode.
@return {String} The base64-encoded string.
*/window.base64Encode = function(text) {
var byteNum, cur, digits, i, prev, result;
if (/([^\u0000-\u00ff])/.test(text)) {
throw new Error("Can't base64 encode non-ASCII characters.");
}
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
i = 0;
result = [];
while (i < text.length) {
cur = text.charCodeAt(i);
byteNum = i % 3;
switch (byteNum) {
case 0:
result.push(digits.charAt(cur >> 2));
break;
case 1:
result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
break;
case 2:
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
result.push(digits.charAt(cur & 0x3f));
}
prev = cur;
i++;
}
if (byteNum === 0) {
result.push(digits.charAt((prev & 3) << 4));
result.push("==");
} else if (byteNum === 1) {
result.push(digits.charAt((prev & 0x0f) << 2));
result.push("=");
}
return result.join("");
};
/*
Base64-decodes a string of text.
@param {String} text The text to decode.
@return {String} The base64-decoded string.
*/
window.base64Decode = function(text) {
var cur, digitNum, digits, i, prev, result;
text = text.replace(/\s/g, "");
if (!/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text) || text.length % 4 > 0) {
throw new Error("Not a base64-encoded string.");
}
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
i = 0;
result = [];
text = text.replace(/=/g, "");
while (i < text.length) {
cur = digits.indexOf(text.charAt(i));
digitNum = i % 4;
switch (digitNum) {
case 1:
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
case 2:
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3:
result.push(String.fromCharCode((prev & 3) << 6 | cur));
}
prev = cur;
i++;
}
return result.join("");
};
<html>
<head>
<title>Base64 Tests</title>
<!-- Combo-handled YUI CSS files: -->
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.7.0/build/logger/assets/logger.css&2.7.0/build/yuitest/assets/testlogger.css">
<!-- Combo-handled YUI JS files: -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo-dom-event/yahoo-dom-event.js&2.7.0/build/logger/logger-min.js&2.7.0/build/yuitest/yuitest-min.js"></script>
<script type="text/javascript" src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<!-- CoffeeScript Base64 Implementation -->
<script type="text/coffeescript">
###
Base 64 implementation in CoffeeScript
Converted from Base 64 implementation in JavaScript - Nicholas C. Zakas (2009)
(https://github.com/nzakas/computer-science-in-javascript)
###
###
Base64-encodes a string of text.
@param {String} text The text to encode.
@return {String} The base64-encoded string.
###
window.base64Encode = (text) ->
if /([^\u0000-\u00ff])/.test(text)
throw new Error "Can't base64 encode non-ASCII characters."
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
i = 0
result = []
while i < text.length
cur = text.charCodeAt(i)
byteNum = i % 3
switch byteNum
when 0 then result.push(digits.charAt(cur >> 2)) # first byte
when 1 then result.push(digits.charAt((prev & 3) << 4 | (cur >> 4))) # second byte
when 2 #third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)))
result.push(digits.charAt(cur & 0x3f))
prev = cur
i++
if byteNum is 0
result.push(digits.charAt((prev & 3) << 4))
result.push("==")
else if byteNum is 1
result.push(digits.charAt((prev & 0x0f) << 2))
result.push("=")
# return a string
result.join("")
###
Base64-decodes a string of text.
@param {String} text The text to decode.
@return {String} The base64-decoded string.
###
window.base64Decode = (text) ->
# ignore white space
text = text.replace(/\s/g,"")
# first check for any unexpected input
if not /^[a-z0-9\+\/\s]+\={0,2}$/i.test(text) or text.length % 4 > 0
throw new Error "Not a base64-encoded string."
# local variables
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
i = 0
result = []
# remove any equals signs
text = text.replace(/=/g, "")
# loop over each character
while i < text.length
cur = digits.indexOf(text.charAt(i))
digitNum = i % 4;
switch digitNum
# when 0: first digit - do nothing, not enough info to work with
when 1 then result.push(String.fromCharCode(prev << 2 | cur >> 4)) # second digit
when 2 then result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2)) # third digit
when 3 then result.push(String.fromCharCode((prev & 3) << 6 | cur))
prev = cur
i++
# return a string
result.join("")
</script>
</head>
<body>
<h1>Base64 Encoding/Decoding Tests</h1>
<script type="text/javascript">
YAHOO.namespace("test");
YAHOO.test.Base64 = (function(){
var assert = YAHOO.util.Assert;
//-------------------------------------------------------------------------
// Base Test Suite
//-------------------------------------------------------------------------
var suite = new YAHOO.tool.TestSuite("Base64 Tests");
//-------------------------------------------------------------------------
// Test Case for encoding
//-------------------------------------------------------------------------
suite.add(new YAHOO.tool.TestCase({
name : "Base 64 Encoding Tests",
_should: {
error: {
testInvalidChar: new Error("Can't base64 encode non-ASCII characters.")
}
},
//---------------------------------------------------------------------
// Tests
//---------------------------------------------------------------------
testMan: function(){
var result = base64Encode("Man");
assert.areEqual("TWFu", result);
},
testHelloWorld: function(){
var result = base64Encode("Hello world");
assert.areEqual("SGVsbG8gd29ybGQ=", result);
},
testPhrase: function(){
var expected = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
var result = base64Encode("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.");
assert.areEqual(expected, result);
},
testInvalidChar: function(){
base64Encode(String.fromCharCode(256) + "Hello!");
}
}));
//-------------------------------------------------------------------------
// Test Case for decoding
//-------------------------------------------------------------------------
suite.add(new YAHOO.tool.TestCase({
name : "Base 64 Decoding Tests",
_should: {
error: {
testInvalidChar: new Error("Not a base64-encoded string."),
testInvalidString: new Error("Not a base64-encoded string."),
testMissingPaddingIndicator: new Error("Not a base64-encoded string.")
}
},
//---------------------------------------------------------------------
// Tests
//---------------------------------------------------------------------
testMan: function(){
var result = base64Decode("TWFu");
assert.areEqual("Man", result);
},
testHelloWorld: function(){
var result = base64Decode("SGVsbG8gd29ybGQ=");
assert.areEqual("Hello world", result);
},
testPhrase: function(){
var result = base64Decode("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
var expected = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
assert.areEqual(expected, result);
},
testPhraseWithWhitespace: function(){
var result = base64Decode("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24 sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHB hc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYn kgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aW\ndhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG\t9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
var expected = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
assert.areEqual(expected, result);
},
testA: function(){
var expected = "a";
var result = base64Decode("YQ==");
assert.areEqual(expected, result);
},
testMissingPaddingIndicator: function(){
var expected = "hatch";
var result = base64Decode("aGF0Y2g");
assert.areEqual(expected, result);
},
testInvalidChar: function(){
base64Decode("aGF,0Y2g");
},
testInvalidString: function(){
base64Decode("aGF0Y2g==");
}
}));
//return it
return suite;
})();
(function (){
//create the logger
var logger = new YAHOO.tool.TestLogger();
//add the tests
YAHOO.tool.TestRunner.add(YAHOO.test.Base64);
YAHOO.tool.TestRunner.run();
})();
</script>
</body>
</html>
###
Base 64 conversion implementation in CoffeeScript
Converted from Base 64 implementation in JavaScript - Nicholas C. Zakas (2009)
(https://github.com/nzakas/computer-science-in-javascript)
###
###
Base64-encodes a string of text.
@param {String} text The text to encode.
@return {String} The base64-encoded string.
###
window.base64Encode = (text) ->
if /([^\u0000-\u00ff])/.test(text)
throw new Error "Can't base64 encode non-ASCII characters."
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
i = 0
result = []
while i < text.length
cur = text.charCodeAt(i)
byteNum = i % 3
switch byteNum
when 0 then result.push(digits.charAt(cur >> 2)) # first byte
when 1 then result.push(digits.charAt((prev & 3) << 4 | (cur >> 4))) # second byte
when 2 #third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)))
result.push(digits.charAt(cur & 0x3f))
prev = cur
i++
if byteNum is 0
result.push(digits.charAt((prev & 3) << 4))
result.push("==")
else if byteNum is 1
result.push(digits.charAt((prev & 0x0f) << 2))
result.push("=")
# return a string
result.join("")
###
Base64-decodes a string of text.
@param {String} text The text to decode.
@return {String} The base64-decoded string.
###
window.base64Decode = (text) ->
# ignore white space
text = text.replace(/\s/g,"")
# first check for any unexpected input
if not /^[a-z0-9\+\/\s]+\={0,2}$/i.test(text) or text.length % 4 > 0
throw new Error "Not a base64-encoded string."
# local variables
digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
i = 0
result = []
# remove any equals signs
text = text.replace(/=/g, "")
# loop over each character
while i < text.length
cur = digits.indexOf(text.charAt(i))
digitNum = i % 4;
switch digitNum
# when 0: first digit - do nothing, not enough info to work with
when 1 then result.push(String.fromCharCode(prev << 2 | cur >> 4)) # second digit
when 2 then result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2)) # third digit
when 3 then result.push(String.fromCharCode((prev & 3) << 6 | cur))
prev = cur
i++
# return a string
result.join("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment