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