Path: blob/trunk/third_party/closure/goog/crypt/crypt.js
2868 views
// Copyright 2008 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Namespace with crypto related helper functions.16*/1718goog.provide('goog.crypt');1920goog.require('goog.array');21goog.require('goog.asserts');222324/**25* Turns a string into an array of bytes; a "byte" being a JS number in the26* range 0-255.27* @param {string} str String value to arrify.28* @return {!Array<number>} Array of numbers corresponding to the29* UCS character codes of each character in str.30*/31goog.crypt.stringToByteArray = function(str) {32var output = [], p = 0;33for (var i = 0; i < str.length; i++) {34var c = str.charCodeAt(i);35while (c > 0xff) {36output[p++] = c & 0xff;37c >>= 8;38}39output[p++] = c;40}41return output;42};434445/**46* Turns an array of numbers into the string given by the concatenation of the47* characters to which the numbers correspond.48* @param {!Uint8Array|!Array<number>} bytes Array of numbers representing49* characters.50* @return {string} Stringification of the array.51*/52goog.crypt.byteArrayToString = function(bytes) {53var CHUNK_SIZE = 8192;5455// Special-case the simple case for speed's sake.56if (bytes.length <= CHUNK_SIZE) {57return String.fromCharCode.apply(null, bytes);58}5960// The remaining logic splits conversion by chunks since61// Function#apply() has a maximum parameter count.62// See discussion: http://goo.gl/LrWmZ96364var str = '';65for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {66var chunk = goog.array.slice(bytes, i, i + CHUNK_SIZE);67str += String.fromCharCode.apply(null, chunk);68}69return str;70};717273/**74* Turns an array of numbers into the hex string given by the concatenation of75* the hex values to which the numbers correspond.76* @param {Uint8Array|Array<number>} array Array of numbers representing77* characters.78* @return {string} Hex string.79*/80goog.crypt.byteArrayToHex = function(array) {81return goog.array82.map(83array,84function(numByte) {85var hexByte = numByte.toString(16);86return hexByte.length > 1 ? hexByte : '0' + hexByte;87})88.join('');89};909192/**93* Converts a hex string into an integer array.94* @param {string} hexString Hex string of 16-bit integers (two characters95* per integer).96* @return {!Array<number>} Array of {0,255} integers for the given string.97*/98goog.crypt.hexToByteArray = function(hexString) {99goog.asserts.assert(100hexString.length % 2 == 0, 'Key string length must be multiple of 2');101var arr = [];102for (var i = 0; i < hexString.length; i += 2) {103arr.push(parseInt(hexString.substring(i, i + 2), 16));104}105return arr;106};107108109/**110* Converts a JS string to a UTF-8 "byte" array.111* @param {string} str 16-bit unicode string.112* @return {!Array<number>} UTF-8 byte array.113*/114goog.crypt.stringToUtf8ByteArray = function(str) {115// TODO(user): Use native implementations if/when available116var out = [], p = 0;117for (var i = 0; i < str.length; i++) {118var c = str.charCodeAt(i);119if (c < 128) {120out[p++] = c;121} else if (c < 2048) {122out[p++] = (c >> 6) | 192;123out[p++] = (c & 63) | 128;124} else if (125((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&126((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {127// Surrogate Pair128c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);129out[p++] = (c >> 18) | 240;130out[p++] = ((c >> 12) & 63) | 128;131out[p++] = ((c >> 6) & 63) | 128;132out[p++] = (c & 63) | 128;133} else {134out[p++] = (c >> 12) | 224;135out[p++] = ((c >> 6) & 63) | 128;136out[p++] = (c & 63) | 128;137}138}139return out;140};141142143/**144* Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.145* @param {Uint8Array|Array<number>} bytes UTF-8 byte array.146* @return {string} 16-bit Unicode string.147*/148goog.crypt.utf8ByteArrayToString = function(bytes) {149// TODO(user): Use native implementations if/when available150var out = [], pos = 0, c = 0;151while (pos < bytes.length) {152var c1 = bytes[pos++];153if (c1 < 128) {154out[c++] = String.fromCharCode(c1);155} else if (c1 > 191 && c1 < 224) {156var c2 = bytes[pos++];157out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);158} else if (c1 > 239 && c1 < 365) {159// Surrogate Pair160var c2 = bytes[pos++];161var c3 = bytes[pos++];162var c4 = bytes[pos++];163var u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) -1640x10000;165out[c++] = String.fromCharCode(0xD800 + (u >> 10));166out[c++] = String.fromCharCode(0xDC00 + (u & 1023));167} else {168var c2 = bytes[pos++];169var c3 = bytes[pos++];170out[c++] =171String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);172}173}174return out.join('');175};176177178/**179* XOR two byte arrays.180* @param {!Uint8Array|!Int8Array|!Array<number>} bytes1 Byte array 1.181* @param {!Uint8Array|!Int8Array|!Array<number>} bytes2 Byte array 2.182* @return {!Array<number>} Resulting XOR of the two byte arrays.183*/184goog.crypt.xorByteArray = function(bytes1, bytes2) {185goog.asserts.assert(186bytes1.length == bytes2.length, 'XOR array lengths must match');187188var result = [];189for (var i = 0; i < bytes1.length; i++) {190result.push(bytes1[i] ^ bytes2[i]);191}192return result;193};194195196