1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 // Creator:   Dominik
  5 // Date:      11.11.2010
  6 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  7 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
  9 // ==========================================================================
 10 
 11 m_require('core/utility/cypher_algorithms/base64.js');
 12 m_require('core/utility/cypher_algorithms/sha256.js');
 13 
 14 /**
 15  * @class
 16  *
 17  * M.Cypher defines a prototype for handling decoding, encoding and hashing of string
 18  * based values.
 19  *
 20  * @extends M.Object
 21  */
 22 M.Cypher = M.Object.extend(
 23 /** @scope M.Cypher.prototype */ {
 24 
 25     /**
 26      * The type of this object.
 27      *
 28      * @type String
 29      */
 30     type: 'M.Cypher',
 31 
 32     /**
 33      * The default decoder.
 34      *
 35      * @type M.Base64
 36      */
 37     defaultDecoder: M.Base64,
 38 
 39     /**
 40      * The default encoder.
 41      *
 42      * @type M.Base64
 43      */
 44 
 45     defaultEncoder: M.Base64,
 46 
 47     /**
 48      * The default hash algorithm.
 49      *
 50      * @type M.SHA256
 51      */
 52 
 53     defaultHasher: M.SHA256,
 54 
 55     /**
 56      * This method is the one that initiates the decoding of a given string, based on either
 57      * the default decoder or a custom decoder.
 58      *
 59      * @param {String} input The input string to be decoded.
 60      * @param {Object} algorithm The algorithm object containing a decode method.
 61      * @returns {String} The decoded string.
 62      */
 63     decode: function(input, algorithm) {
 64 
 65         if(algorithm && algorithm.decode) {
 66             return algorithm.decode(input);
 67         } else {
 68             return this.defaultDecoder.decode(input);
 69         }
 70         
 71     },
 72 
 73     /**
 74      * This method is the one that initiates the encoding of a given string, based on either
 75      * the default encoder or a custom encoder.
 76      *
 77      * @param {String} input The input string to be decoded.
 78      * @param {Object} algorithm The algorithm object containing a encode method.
 79      * @returns {String} The encoded string.
 80      */
 81     encode: function(input, algorithm) {
 82 
 83         if(algorithm && algorithm.encode) {
 84             return algorithm.encode(input);
 85         } else {
 86             return this.defaultEncoder.encode(input);
 87         }
 88 
 89     },
 90 
 91     /**
 92      * This method is the one that initiates the hashing of a given string, based on either
 93      * the default hashing algorithm or a custom hashing algorithm.
 94      *
 95      * @param {String} input The input string to be hashed.
 96      * @param {Object} algorithm The algorithm object containing a hash method.
 97      * @returns {String} The hashed string.
 98      */
 99     hash: function(input, algorithm) {
100 
101         if(algorithm && algorithm.hash) {
102             return algorithm.hash(input);
103         } else {
104             return this.defaultHasher.hash(input);
105         }
106 
107     },
108 
109     /**
110      * Private method for UTF-8 encoding
111      *
112      * @private
113      * @param {String} string The string to be encoded.
114      * @returns {String} The utf8 encoded string.
115      */
116     utf8_encode : function (string) {
117         string = string.replace(/\r\n/g, '\n');
118         var utf8String = '';
119 
120         for (var n = 0; n < string.length; n++) {
121 
122             var c = string.charCodeAt(n);
123 
124             if (c < 128) {
125                 utf8String += String.fromCharCode(c);
126             }
127             else if((c > 127) && (c < 2048)) {
128                 utf8String += String.fromCharCode((c >> 6) | 192);
129                 utf8String += String.fromCharCode((c & 63) | 128);
130             }
131             else {
132                 utf8String += String.fromCharCode((c >> 12) | 224);
133                 utf8String += String.fromCharCode(((c >> 6) & 63) | 128);
134                 utf8String += String.fromCharCode((c & 63) | 128);
135             }
136 
137         }
138 
139         return utf8String;
140     },
141 
142     /**
143      * Private method for UTF-8 decoding
144      *
145      * @private
146      * @param {String} string The string to be decoded.
147      * @returns {String} The utf8 decoded string.
148      */
149     utf8_decode : function (utf8String) {
150         var string = '';
151         var i = 0;
152         var c = c1 = c2 = 0;
153 
154         while ( i < utf8String.length ) {
155 
156             c = utf8String.charCodeAt(i);
157 
158             if (c < 128) {
159                 string += String.fromCharCode(c);
160                 i++;
161             }  else if((c > 191) && (c < 224)) {
162                 c2 = utf8String.charCodeAt(i+1);
163                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
164                 i += 2;
165             } else {
166                 c2 = utf8String.charCodeAt(i+1);
167                 c3 = utf8String.charCodeAt(i+2);
168                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
169                 i += 3;
170             }
171 
172         }
173 
174         return string;
175     }
176 
177 });