UNPKG

@sskmy1024y/react-native-hash

Version:
205 lines (182 loc) 5.38 kB
/* eslint linebreak-style: ["error", "windows"] */ /* eslint-disable no-use-before-define */ import Base from './Base.js'; import Hex from './Hex.js'; /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ export default class WordArray extends Base { /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ constructor(words = [], sigBytes = words.length * 4) { super(); let typedArray = words; // Convert buffers to uint8 if (typedArray instanceof ArrayBuffer) { typedArray = new Uint8Array(typedArray); } // Convert other array views to uint8 if ( typedArray instanceof Int8Array || typedArray instanceof Uint8ClampedArray || typedArray instanceof Int16Array || typedArray instanceof Uint16Array || typedArray instanceof Int32Array || typedArray instanceof Uint32Array || typedArray instanceof Float32Array || typedArray instanceof Float64Array ) { typedArray = new Uint8Array( typedArray.buffer, typedArray.byteOffset, typedArray.byteLength, ); } // Handle Uint8Array if (typedArray instanceof Uint8Array) { // Shortcut const typedArrayByteLength = typedArray.byteLength; // Extract bytes const _words = []; for (let i = 0; i < typedArrayByteLength; i += 1) { _words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8); } // Initialize this word array this.words = _words; this.sigBytes = typedArrayByteLength; } else { // Else call normal init this.words = words; this.sigBytes = sigBytes; } } /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ static random(nBytes) { const words = []; const r = (m_w) => { let _m_w = m_w; let _m_z = 0x3ade68b1; const mask = 0xffffffff; return () => { _m_z = (0x9069 * (_m_z & 0xffff) + (_m_z >> 0x10)) & mask; _m_w = (0x4650 * (_m_w & 0xffff) + (_m_w >> 0x10)) & mask; let result = ((_m_z << 0x10) + _m_w) & mask; result /= 0x100000000; result += 0.5; return result * (Math.random() > 0.5 ? 1 : -1); }; }; for (let i = 0, rcache; i < nBytes; i += 4) { const _r = r((rcache || Math.random()) * 0x100000000); rcache = _r() * 0x3ade67b7; words.push((_r() * 0x100000000) | 0); } return new WordArray(words, nBytes); } /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString(encoder = Hex) { return encoder.stringify(this); } /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat(wordArray) { // Shortcuts const thisWords = this.words; const thatWords = wordArray.words; const thisSigBytes = this.sigBytes; const thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (let i = 0; i < thatSigBytes; i += 1) { const thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else { // Copy one word at a time for (let i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } this.sigBytes += thatSigBytes; // Chainable return this; } /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp() { // Shortcuts const { words, sigBytes } = this; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); } /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone() { const clone = super.clone.call(this); clone.words = this.words.slice(0); return clone; } }