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 */
2958function 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 - z 0 - 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