/* GZIP on the fly by Raccoon Framework http://www.wt.com.mx/ */ /** * @version 1.9 (23/May/2007/1600) * @author Alejandro -aztkgeek- Galindo * @copyright Copyright (C) 2007 Web Technologies Networks S.A. de C.V. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php * Raccoon is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * See COPYRIGHT.php for copyright notices and details. * * @class RCN * Esta libreria se llama RCN por que es la abreviacion de Raccoon * * @requires Prototype */ /* var $ = function () { return true; }; var Event = {}; var $H = {}; var Ajax = {}; */ var RCN = {}; /** * Configuracion */ RCN.config = { debug: false, url: '', version: "1.9.1", lang: 'es_MX' }; /** * Acceso a la consola de debug, en IE es una ventana que se crea, en FFX se utiliza la del Firebug */ RCN.log = function (message) { if (RCN.config.debug) { if (typeof(console) !== "undefined") { console.log(message); } else { if (navigator.appName.indexOf("Explorer") > -1) { if (typeof(RCN.console) === "undefined") { RCN.console = window.open("", "console", "width=600,height=300,scrollbars=yes,resizable=yes"); } if (RCN.console) { RCN.console.document.write(message + "
\n"); } } } } }; /** * Contraccion de Event.observe */ RCN.on = function (element, my_event, callback) { Event.observe(element, my_event, callback); }; RCN.location = { goTo: function (config) { var url = RCN.location.getURL(); var arg_name = null; if (!url) { return false; } if (config.page) { url.page = config.page; config.page = null; url.args = {}; } for (arg_name in config) { if (config[arg_name] !== null && !RCN.isFunction(config[arg_name])) { url.args[arg_name] = config[arg_name]; } } var args = []; for (arg_name in url.args) { if (url.args[arg_name] !== null && !RCN.isFunction(url.args[arg_name])) { args.push(arg_name.replace(/\ /g, "_") + "," + encodeURIComponent(url.args[arg_name])); } } var new_url = url.base + "page/" + url.page + "/"; if (Object.keys(url.args).length > 0) { new_url += args.join("/") + "/"; } window.location.href = new_url; }, getURL: function () { var url = {}; url.source = window.location.href; //document.getElementById("url").value; if (url.source.indexOf("/index.php/page/") < 0) { return false; } url.positions = {}; url.positions.base = url.source.indexOf("/index.php/") + 11; url.positions.page = url.positions.base + 5; url.base = url.source.substring(0, url.positions.base); url.page = url.source.substring(url.positions.page, url.source.indexOf("/", url.positions.page)); url.positions.args = url.positions.page + url.page.length; url.args_string = url.source.substring(url.positions.args, url.source.length); url.args_string = url.args_string.replace(/^\//, ""); url.args_string = url.args_string.replace(/\/$/, ""); url.args = {}; var args_tmp = url.args_string.split("/"); for (var index_tmp in args_tmp) { if (RCN.isString(args_tmp[index_tmp])) { var arg_array = args_tmp[index_tmp].split(","); var arg_name = ""; var arg_value = ""; if (arg_array[0]) { arg_name = arg_array[0]; } if (arg_array[1]) { arg_value = arg_array[1]; } if (arg_name.length > 0) { url.args[arg_name] = arg_value; } } } return url; } }; RCN.iframe = { getContent: function(id) { var iframe = document.getElementById(id); var content = ''; if (iframe.contentDocument) { content = iframe.contentDocument.body.innerHTML; } else if (iframe.document) { content = iframe.document.body.innerHTML; } else if (iframe.contentWindow) { content = iframe.contentWindow.document.body.innerHTML; } else { return false; } return content; }, setContent: function(id, content) { var iframe = document.getElementById(id); if (iframe.contentDocument) { iframe.contentDocument.body.innerHTML = content; } else if (iframe.document) { iframe.document.body.innerHTML = content; } else if (iframe.contentWindow) { iframe.contentWindow.document.body.innerHTML = content; } }, print: function(id) { document.getElementById(id).contentWindow.focus(); document.getElementById(id).contentWindow.print(); } }; /** * Convierte una cadena normal en utf8, util para cuando se envian * caracteres no ascii al servidor, como acentos, ñ * @param {Object} value_tmp */ RCN.encodeUTF8 = function (value_tmp) { var value_out = ""; for (var i = 0; i < value_tmp.length; i++) { if ( (value_tmp.charCodeAt(i) > 0 && value_tmp.charCodeAt(i) < 48) || (value_tmp.charCodeAt(i) > 57 && value_tmp.charCodeAt(i) < 65) || (value_tmp.charCodeAt(i) > 90 && value_tmp.charCodeAt(i) < 97) || (value_tmp.charCodeAt(i) > 122) ) { value_out += '\\u00' + RCN.dec2hex(value_tmp.charCodeAt(i)); } else { value_out += value_tmp[i]; } } if (RCN.config.debug) { RCN.log("Encode UTF8 Old: " + value_tmp + " New: " + value_out); } return value_out; }; /** * Decimal a Hexadecimal * @param {Object} dec */ RCN.dec2hex = function (dec) { var Char_hexadecimales = "0123456789abcdef"; var low = dec % 16; var high = (dec - low) / 16; var hex = "" + Char_hexadecimales.charAt(high) + Char_hexadecimales.charAt(low); return hex; }; /** * Contraccion de Element.getStyle */ RCN.style = function (elementos, propiedad, valor) { if (!RCN.isUndefined(valor)) { if (RCN.isArray(elementos)) { elementos.each(function (elemento) { $(elemento).style[propiedad] = valor; }); return true; } else if (RCN.isString(elementos)) { $(elementos).style[propiedad] = valor; } else { elementos.style[propiedad] = valor; } } else { if (RCN.isArray(elementos)) { var elementos_tmp = []; elementos.each(function (elemento) { elementos_tmp[elementos_tmp.length] = $(elemento).getStyle(propiedad); }); return elementos_tmp; } else if (RCN.isString(elementos)) { return $(elementos).getStyle(propiedad); } else { return elementos.getStyle(propiedad); } } return true; }; /** * Purga el contenido o los nodos hijos de un nodo, util para cuando un elmento * funje como contenedor y se necesita que se limpie cada ves que se usa */ RCN.clean = function (elemento) { elemento = $(elemento); while (elemento.firstChild) { RCN.purgeEvent(elemento.firstChild); elemento.removeChild(elemento.firstChild); } }; /** * @author Douglas Crockford (2006) * From: "The Theory of the DOM" * Recorre los hijos de un nodo de manera recursiva y cada vez que visita un nodo * ejecuta la funcion que se le paso por parametro */ RCN.walkDOM = function (node, func) { func(node); node = node.firstChild; while (node) { RCN.walkDOM(node, func); node = node.nextSibling; } }; /** * @author Douglas Crockford (2006) * From: "The Theory of the DOM" * Elimina los manejadores de eventos que tiene registrados un elemento, util a la * hora de borrar un elemento, ya que el no hacer esto conlleva a que se genere basura * en la memoria */ RCN.purgeEvent = function (node) { RCN.walkDOM(node, function (e) { for (var n in e) { if (n === "selectionStart") { return true; } if (typeof(e[n]) === 'function') { e[n] = null; } } }); }; /** * Reemplaza un elemento sin necesidad de senalar el padre que lo contiene * util para los navegadores que se basan en el estandar, donde en algunas ocaciones el nodo padre * es un caracter de espacio */ RCN.replaceChild = function (new_child, old_child) { RCN.purgeEvent(old_child); old_child.parentNode.replaceChild(new_child, old_child); }; /** * Borra un elemento junto con sus manejadores de eventos */ RCN.removeChild = function (old_child) { RCN.purgeEvent(old_child); old_child.parentNode.removeChild(old_child); }; /** * Creacion de elementos en el DOM a traves de un objeto * Forma clasica para crear una imagen: *
 *   var img = document.createElement("img");
 *   img.setAttribute("src", "ruta de la imagen");
 *   img.className = "nombre de la clase";
 * 
* Nueva forma: *
 *   var img = RCN.create({_type:'img', src:'ruta de la imagen', _class:'nombre de la clase'});
 * 
*/ RCN.create = function (config) { var element = false; if (config._type) { element = document.createElement(config._type); for (var property in config) { if (RCN.isString(property)) { if (property !== "_type" && property !== "_class") { element.setAttribute(property, config[property]); } } if (RCN.isFunction(config[property])) { RCN.listener(element, property, config[property]); } } if (config._class) { element.className = config._class; } return element; } else { return element; } }; /** * Crea un nodo de texto */ RCN.createText = function (string_to_create) { return document.createTextNode(string_to_create); }; /** * Recorre un arreglo y valida si tiene o no el elemento del parametro */ RCN.inArray = function (needle, haystack) { for (var i = 0; i < haystack.length; i++) { if (haystack[i] === needle) { return true; } } return false; }; /** * Copyright Crockford * http://javascript.crockford.com/remedial.html */ RCN.isAlien = function (a) { return RCN.isObject(a) && typeof a.constructor !== 'function'; }; RCN.isArray = function (a) { return RCN.isObject(a) && a.constructor === Array; }; RCN.isBoolean = function (a) { return typeof a === 'boolean'; }; RCN.isEmpty = function (o) { var i, v; if (RCN.isObject(o)) { for (i in o) { v = o[i]; if (RCN.isUndefined(v) && RCN.isFunction(v)) { return false; } } } return true; }; RCN.isFunction = function (a) { return typeof a === 'function'; }; RCN.isNull = function (a) { return a === null; }; RCN.isSet = function (a) { return !RCN.isNull(a); }; RCN.isNumber = function (a) { return typeof a === 'number' && isFinite(a); }; RCN.isObject = function (a) { return (a && typeof a === 'object') || RCN.isFunction(a); }; RCN.isString = function (a) { return typeof a === 'string'; }; RCN.isUndefined = function (a) { return typeof a === 'undefined'; }; /** * http://www.quirksmode.org/js/cookies.html */ RCN.cookies = { create : function (name,value,days) { var expires = null; if (days) { var date = new Date(); date.setTime( date.getTime() + (days * 24 * 60 * 60 * 1000) ); expires = "; expires=" + date.toGMTString(); } else { expires = ""; } document.cookie = name + "=" + value + expires + "; path=/"; }, read : function (name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) === ' ') { c = c.substring(1, c.length); } if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); } } return null; }, erase : function (name) { RCN.cookies.create(name, "", -1); } }; /** * Centra un elemento en la ventana, solo se pasa el id del elemento * al cargar y al hacer resize se modifica */ RCN.centerIntoBody = function (element) { var scope = {}; RCN.on(window, "load", function () { scope.center(element); }, scope); RCN.on(window, "resize", function () { scope.center(element); }, scope); scope.center = function (element) { element = $(element); var sizes = RCN.getWindowDimentions(); sizes.left = (sizes.width / 2) - (element.clientWidth / 2); sizes.top = (sizes.height / 2) - (element.clientHeight / 2); if (sizes.top < 0) { sizes.top = 0; } if (sizes.left < 0) { sizes.left = 0; } RCN.style(element, "position", "absolute"); RCN.style(element, "left", sizes.left + "px"); RCN.style(element, "top", sizes.top + "px"); }; }; /** * Obtiene el tamaño del body de la ventana */ RCN.toBodySize = function (element) { var scope = {}; RCN.on(window, "load", function () { scope.resize(element); }, scope); RCN.on(window, "resize", function () { scope.resize(element); }, scope); scope.resize = function (element) { element = $(element); var sizes = RCN.getWindowDimentions(); RCN.style(element, "position", "absolute"); RCN.style(element, "width", sizes.width + "px"); RCN.style(element, "height", sizes.height + "px"); }; }; /** * Se obtienen las dimensiones de lo que se ve de la pantalla */ RCN.getWindowDimentions = function () { var sizes = { width : 0, height : 0 }; if (window.innerWidth) { sizes.width = window.innerWidth; sizes.height = window.innerHeight; } else if (document.documentElement.clientWidth) { sizes.width = document.documentElement.clientWidth; sizes.height = document.documentElement.clientHeight; } return sizes; }; /** * Regresa las dimensiones de todo el documento */ RCN.getBodyDimentions = function () { var sizes = {}; sizes.width = document.body.clientWidth; sizes.height = document.body.clientHeight; return sizes; }; /** * Devuelve un numero aleatorio entre un rango de numeros * por ejemplo, para obtener un numero aleatorio entre el 1 y el 10 * se manda llamar así: * * var num = RCN.getRandom(1, 10); */ RCN.getRandom = function (min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }; /** * Se pasa un URL y le agrega un token para hacer que el recurso * que se esta solicitando sea unico y por lo tanto se salte el cache, * por ejemplo para solicitar una imagen: * * var url_imagen = RCN.token("imagen.jpg"); */ RCN.token = function (to_set_token) { var token_value = ( (new Date()).valueOf() ); if (!RCN.isUndefined(to_set_token)) { token_value = to_set_token + "?token=" + token_value; } return token_value; }; /** * Version de Raccoon de la propuesta de JSONRequest * * Realiza una solicitud a un recurso remoto y el resultado lo intenta convertir a JSON * * Uso: *
 *   RCN.request({
 *     method : "GET",
 *     recurso : "script.php",
 *     variable : "valor de la variable", // Esta variable se pasa por query string
 *     callbacks : {
 *       success : function (o) {
 *         // responseRaccoon es el objeto que contiene el resultado del servidor
 *         RCN.log(o.responseRaccoon.toSource());
 *       }
 *     }
 *   });
 * 
* * Basado sobre Prototype.Ajax */ RCN.request = function (config) { var request = null; var ajax_config = $H({ parameters : $H({ lang : RCN.config.lang, token : RCN.token() }) }); $H(config).each(function (iterator) { if (iterator.key !== "toSource" && iterator.key !== "callbacks" && iterator.key !== "method" && iterator.key !== "resource" && iterator.key !== "extend" && iterator.key !== "toSource" && iterator.key.length > 0 && !RCN.isFunction(iterator.value)) { ajax_config.parameters[iterator.key] = iterator.value; } }); if (config.method) { ajax_config.method = config.method; } ajax_config.onComplete = function (transport) { if (transport.status >= 200 && transport.status <= 299) { if (config.callbacks.success && RCN.isFunction(config.callbacks.success)) { if (transport.responseText.match("^RDATA")) { var RDATA = {}; eval(transport.responseText); config.callbacks.success({ status : transport.status, statusText : transport.statusText, responseText : "", responseRaccoon : RDATA }); } else { config.callbacks.success(transport); } } } else if (transport.status === 12150) { RCN.log("RCN Request Error. IE error 12150"); alert("Tiene una versión de Internet Explorer muy antigua, por favor instale una más reciente."); } else { RCN.log("RCN Request Error. Code: " + transport.status + ", Message: " + transport.statusText); if (config.callbacks.failure && RCN.isFunction(config.callbacks.failure)) { transport.responseRaccoon = $H({ status : "NO", statusText : "RCN.request error. Code: " + transport.status + ", Message: " + transport.statusText }); config.callbacks.failure(transport); } } }; if (config.callbacks.failure && RCN.isFunction(config.callbacks.failure)) { ajax_config.onFailure = config.callbacks.failure; } if (config.resource.length > 0) { request = new Ajax.Request(RCN.config.requestPath + config.resource, ajax_config); } }; RCN.includeHTMLInto = function (file, into) { RCN.request({ resource : file, callbacks : { success : function (o) { RCN.getBy(into).innerHTML = o.responseText; } } }); }; RCN.MD5 = { /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ /** * hex output format. 0 - lowercase; 1 - uppercase * @type int */ hexcase : 0, /** * base-64 pad character. "=" for strict RFC compliance * @type string */ b64pad : "", /** * bits per input character. 8 - ASCII; 16 - Unicode * @type int */ chrsz : 8, /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ hex_md5 : function (s) { return this.binl2hex(this.core_md5(this.str2binl(s), s.length * this.chrsz)); }, b64_md5 : function (s) { return this.binl2b64(this.core_md5(this.sstr2binl(s), s.length * this.chrsz)); }, str_md5 : function (s) { return this.binl2str(this.core_md5(this.str2binl(s), s.length * this.chrsz)); }, hex_hmac_md5 : function (key, data) { return this.binl2hex(this.core_hmac_md5(key, data)); }, b64_hmac_md5 : function (key, data) { return this.binl2b64(this.core_hmac_md5(key, data)); }, str_hmac_md5 : function (key, data) { return this.binl2str(this.core_hmac_md5(key, data)); }, /** * Perform a simple self-test to see if the VM is working */ md5_vm_test : function () { return this.hex_md5("abc") === "900150983cd24fb0d6963f7d28e17f72"; }, /** * Calculate the MD5 of an array of little-endian words, and a bit length */ core_md5 : function (x, len) { /* append padding */ x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for (var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = this.md5_ff(a, b, c, d, x[i + 0], 7 , -680876936); d = this.md5_ff(d, a, b, c, x[i + 1], 12, -389564586); c = this.md5_ff(c, d, a, b, x[i + 2], 17, 606105819); b = this.md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); a = this.md5_ff(a, b, c, d, x[i + 4], 7 , -176418897); d = this.md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); c = this.md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); b = this.md5_ff(b, c, d, a, x[i + 7], 22, -45705983); a = this.md5_ff(a, b, c, d, x[i + 8], 7 , 1770035416); d = this.md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); c = this.md5_ff(c, d, a, b, x[i + 10], 17, -42063); b = this.md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); a = this.md5_ff(a, b, c, d, x[i + 12], 7 , 1804603682); d = this.md5_ff(d, a, b, c, x[i + 13], 12, -40341101); c = this.md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); b = this.md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); a = this.md5_gg(a, b, c, d, x[i + 1], 5 , -165796510); d = this.md5_gg(d, a, b, c, x[i + 6], 9 , -1069501632); c = this.md5_gg(c, d, a, b, x[i + 11], 14, 643717713); b = this.md5_gg(b, c, d, a, x[i + 0], 20, -373897302); a = this.md5_gg(a, b, c, d, x[i + 5], 5 , -701558691); d = this.md5_gg(d, a, b, c, x[i + 10], 9 , 38016083); c = this.md5_gg(c, d, a, b, x[i + 15], 14, -660478335); b = this.md5_gg(b, c, d, a, x[i + 4], 20, -405537848); a = this.md5_gg(a, b, c, d, x[i + 9], 5 , 568446438); d = this.md5_gg(d, a, b, c, x[i + 14], 9 , -1019803690); c = this.md5_gg(c, d, a, b, x[i + 3], 14, -187363961); b = this.md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); a = this.md5_gg(a, b, c, d, x[i + 13], 5 , -1444681467); d = this.md5_gg(d, a, b, c, x[i + 2], 9 , -51403784); c = this.md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); b = this.md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); a = this.md5_hh(a, b, c, d, x[i + 5], 4 , -378558); d = this.md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); c = this.md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); b = this.md5_hh(b, c, d, a, x[i + 14], 23, -35309556); a = this.md5_hh(a, b, c, d, x[i + 1], 4 , -1530992060); d = this.md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); c = this.md5_hh(c, d, a, b, x[i + 7], 16, -155497632); b = this.md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); a = this.md5_hh(a, b, c, d, x[i + 13], 4 , 681279174); d = this.md5_hh(d, a, b, c, x[i + 0], 11, -358537222); c = this.md5_hh(c, d, a, b, x[i + 3], 16, -722521979); b = this.md5_hh(b, c, d, a, x[i + 6], 23, 76029189); a = this.md5_hh(a, b, c, d, x[i + 9], 4 , -640364487); d = this.md5_hh(d, a, b, c, x[i + 12], 11, -421815835); c = this.md5_hh(c, d, a, b, x[i + 15], 16, 530742520); b = this.md5_hh(b, c, d, a, x[i + 2], 23, -995338651); a = this.md5_ii(a, b, c, d, x[i + 0], 6 , -198630844); d = this.md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); c = this.md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); b = this.md5_ii(b, c, d, a, x[i + 5], 21, -57434055); a = this.md5_ii(a, b, c, d, x[i + 12], 6 , 1700485571); d = this.md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); c = this.md5_ii(c, d, a, b, x[i + 10], 15, -1051523); b = this.md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); a = this.md5_ii(a, b, c, d, x[i + 8], 6 , 1873313359); d = this.md5_ii(d, a, b, c, x[i + 15], 10, -30611744); c = this.md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); b = this.md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); a = this.md5_ii(a, b, c, d, x[i + 4], 6 , -145523070); d = this.md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); c = this.md5_ii(c, d, a, b, x[i + 2], 15, 718787259); b = this.md5_ii(b, c, d, a, x[i + 9], 21, -343485551); a = this.safe_add(a, olda); b = this.safe_add(b, oldb); c = this.safe_add(c, oldc); d = this.safe_add(d, oldd); } return [a, b, c, d]; }, /* * These functions implement the four basic operations the algorithm uses. */ md5_cmn : function (q, a, b, x, s, t) { return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s),b); }, md5_ff : function (a, b, c, d, x, s, t) { return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }, md5_gg : function (a, b, c, d, x, s, t) { return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }, md5_hh : function (a, b, c, d, x, s, t) { return this.md5_cmn(b ^ c ^ d, a, b, x, s, t); }, md5_ii : function (a, b, c, d, x, s, t) { return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }, /** * Calculate the HMAC-MD5, of a key and some data */ core_hmac_md5 : function (key, data) { var bkey = this.str2binl(key); if (bkey.length > 16) { bkey = this.core_md5(bkey, key.length * this.chrsz); } var ipad = new Array(16), opad = new Array(16); for (var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = this.core_md5(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz); return this.core_md5(opad.concat(hash), 512 + 128); }, /** * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ safe_add : function (x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); }, /** * Bitwise rotate a 32-bit number to the left. */ bit_rol : function (num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); }, /** * Convert a string to an array of little-endian words * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. */ str2binl : function (str) { var bin = []; var mask = (1 << this.chrsz) - 1; for (var i = 0; i < str.length * this.chrsz; i += this.chrsz) { bin[i >> 5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i % 32); } return bin; }, /** * Convert an array of little-endian words to a string */ binl2str : function (bin) { var str = ""; var mask = (1 << this.chrsz) - 1; for (var i = 0; i < bin.length * 32; i += this.chrsz) { str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask); } return str; }, /** * Convert an array of little-endian words to a hex string. */ binl2hex : function (binarray) { var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for (var i = 0; i < binarray.length * 4; i++) { str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 )) & 0xF); } return str; }, /** * Convert an array of little-endian words to a base-64 string */ binl2b64 : function (binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for (var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> 8 * ( i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8 ) | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF); for (var j = 0; j < 4; j++) { if (i * 8 + j * 6 > binarray.length * 32) { str += this.b64pad; } else { str += tab.charAt((triplet >> 6 * ( 3 - j )) & 0x3F); } } } return str; } };