Skip to content

Commit 2547b7e

Browse files
author
Nicholas C. Zakas
committed
Added base64 decode
1 parent 7e2fdbd commit 2547b7e

File tree

2 files changed

+140
-20
lines changed

2 files changed

+140
-20
lines changed

encodings/base64/base64.htm

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
</head>
1212
<body>
13-
<h1>Doubly Linked List Tests</h1>
13+
<h1>Base64 Encoding/Decoding Tests</h1>
1414
<script type="text/javascript">
1515

1616
YAHOO.namespace("test");
@@ -26,7 +26,7 @@ <h1>Doubly Linked List Tests</h1>
2626
var suite = new YAHOO.tool.TestSuite("Base64 Tests");
2727

2828
//-------------------------------------------------------------------------
29-
// Test Case for adding
29+
// Test Case for encoding
3030
//-------------------------------------------------------------------------
3131

3232
suite.add(new YAHOO.tool.TestCase({
@@ -54,6 +54,58 @@ <h1>Doubly Linked List Tests</h1>
5454
}
5555
}));
5656

57+
//-------------------------------------------------------------------------
58+
// Test Case for decoding
59+
//-------------------------------------------------------------------------
60+
61+
suite.add(new YAHOO.tool.TestCase({
62+
63+
name : "Base 64 Decoding Tests",
64+
65+
_should: {
66+
error: {
67+
testInvalidChar: new Error("Not a base64-encode string.")
68+
}
69+
},
70+
71+
//---------------------------------------------------------------------
72+
// Tests
73+
//---------------------------------------------------------------------
74+
75+
testMan: function(){
76+
var result = base64Decode("TWFu");
77+
assert.areEqual("Man", result);
78+
},
79+
80+
testHelloWorld: function(){
81+
var result = base64Decode("SGVsbG8gd29ybGQ=");
82+
assert.areEqual("Hello world", result);
83+
},
84+
85+
testPhrase: function(){
86+
var result = base64Decode("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
87+
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.";
88+
assert.areEqual(expected, result);
89+
},
90+
91+
testPhraseWithWhitespace: function(){
92+
var result = base64Decode("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24 sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHB hc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYn kgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aW\ndhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG\t9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
93+
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.";
94+
assert.areEqual(expected, result);
95+
},
96+
97+
testA: function(){
98+
var expected = "a";
99+
var result = base64Decode("YQ==");
100+
assert.areEqual(expected, result);
101+
},
102+
103+
testInvalidChar: function(){
104+
base64Decode("TWF,JFU");
105+
}
106+
107+
}));
108+
57109

58110
//return it
59111
return suite;

encodings/base64/base64.js

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,42 @@
2121
* THE SOFTWARE.
2222
*/
2323

24+
/**
25+
* Accepts an array of bits and pads with zeros to the left up to a certain
26+
* length.
27+
* @param {Array} bits An array of bits (strings either "0" or "1").
28+
* @param {int} length The length that the array of bits should be.
29+
* @return {Array} The array of bits.
30+
*/
31+
function padLeft(bits, length){
32+
while (bits.length < length){
33+
bits.unshift("0");
34+
}
35+
return bits;
36+
}
37+
38+
/**
39+
* Accepts an array of bits and pads with zeros to the right up to a certain
40+
* length.
41+
* @param {Array} bits An array of bits (strings either "0" or "1").
42+
* @param {int} length The length that the array of bits should be.
43+
* @return {Array} The array of bits.
44+
*/
45+
function padRight(bits, length){
46+
while (bits.length < length){
47+
bits.push("0");
48+
}
49+
return bits;
50+
}
51+
52+
2453
/**
2554
* Base64-encodes a string of text.
26-
* @param {String} text The text to encode
55+
* @param {String} text The text to encode.
2756
* @return {String} The base64-encoded string.
2857
*/
2958
function base64Encode(text){
3059

31-
//helper function to left-pad an array with zeros
32-
function padLeft(bits, length){
33-
while (bits.length < length){
34-
bits.unshift("0");
35-
}
36-
return bits;
37-
}
38-
39-
//helper function to right-pad an array with zeros
40-
function padRight(bits, length){
41-
while (bits.length < length){
42-
bits.push("0");
43-
}
44-
return bits;
45-
}
46-
4760
//local variables
4861
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
4962
part, index,
@@ -54,9 +67,10 @@ function base64Encode(text){
5467
result = [];
5568

5669
//create an array of binary digits representing the text
57-
for (; i < text.length; i++){
70+
while(i < text.length){
5871
part = text.charCodeAt(i).toString(2);
5972
bits = bits.concat(padLeft(part.split(""), 8));
73+
i++;
6074
}
6175

6276
//figure out how many 24-bit quanta are in the array
@@ -95,4 +109,58 @@ function base64Encode(text){
95109
//return a string
96110
return result.join("");
97111

112+
}
113+
114+
/**
115+
* Base64-decodes a string of text.
116+
* @param {String} text The text to decode.
117+
* @return {String} The base64-decoded string.
118+
*/
119+
function base64Decode(text){
120+
121+
//local variables
122+
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
123+
part, code,
124+
i=0, j=0,
125+
padCount=0,
126+
bits = [],
127+
result = [];
128+
129+
//first check for any unexpected input
130+
if(!(/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text))){
131+
throw new Error("Not a base64-encode string.");
132+
}
133+
134+
//remove any whitespace
135+
text = text.replace(/\s/g, "");
136+
137+
//determine if there's any padding
138+
while(text.charAt(text.length-1) == "="){
139+
140+
//increment pad count
141+
padCount += 2;
142+
143+
//remove last character and try again
144+
text = text.substr(0, text.length-1);
145+
}
146+
147+
//create an array of binary digits representing the text
148+
while (i < text.length){
149+
part = digits.indexOf(text.charAt(i)).toString(2);
150+
bits = bits.concat(padLeft(part.split(""), 6));
151+
i++;
152+
}
153+
154+
//remove padding
155+
bits = bits.slice(0, bits.length - padCount);
156+
157+
//transform what remains back into characters
158+
while(bits.length){
159+
part = bits.splice(0, 8).join("");
160+
result.push(String.fromCharCode(parseInt(part, 2)));
161+
}
162+
163+
//return a string
164+
return result.join("");
165+
98166
}

0 commit comments

Comments
 (0)