-
-
Save artjomb/7ef1ee574a411ba0dd1933c1ef4690d1 to your computer and use it in GitHub Desktop.
function byteArrayToWordArray(ba) { | |
var wa = [], | |
i; | |
for (i = 0; i < ba.length; i++) { | |
wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i); | |
} | |
return CryptoJS.lib.WordArray.create(wa, ba.length); | |
} | |
function wordToByteArray(word, length) { | |
var ba = [], | |
i, | |
xFF = 0xFF; | |
if (length > 0) | |
ba.push(word >>> 24); | |
if (length > 1) | |
ba.push((word >>> 16) & xFF); | |
if (length > 2) | |
ba.push((word >>> 8) & xFF); | |
if (length > 3) | |
ba.push(word & xFF); | |
return ba; | |
} | |
function wordArrayToByteArray(wordArray, length) { | |
if (wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")) { | |
length = wordArray.sigBytes; | |
wordArray = wordArray.words; | |
} | |
var result = [], | |
bytes, | |
i = 0; | |
while (length > 0) { | |
bytes = wordToByteArray(wordArray[i], Math.min(4, length)); | |
length -= bytes.length; | |
result.push(bytes); | |
i++; | |
} | |
return [].concat.apply([], result); | |
} |
right shift left shift oprators not working
Done. Thanks @VicEcho
This is hugely helpful. Thanks so much. :-)
Just one thing more. Could you please include the ES6 import statement that resolves the symbol CryptoJS
? I am guessing it is:
import CryptoJS from "./locationOf/crypto-js.js";
But I can't be sure.
Just for anyone else who has the same question as mine, as indicated in the previous post in this thread, here is the answer.
It appears that if you do either of the following ES 6 imports, it fails with different errors:
import CryptoJS from "./locationOf/crypto-js.js"; // fails with import not found: default
import "./locationOf/crypto-js.js"; // fails with ReferenceError: root undefined.
I investigated and found that the issue was that symbol root
, which is also the first parameter of the iffy that you find at the beginning of the file crypto-js.js
was not being initialized to the window
object because the argument this
that was being passed to it did not resolve to the window
object.
So, as a kludge, which worked for me, I replaced the following line (lines 10 to 13):
else {
// Global (browser)
root.CryptoJS = factory();
}
with the following line and it worked.
else {
// Global (browser)
window.CryptoJS = factory();
}
thanks, great work
Did you find the solution to this range error problem ?
I found solution to my problem on stackoverflow.
Link: https://stackoverflow.com/questions/58937464/cryptojs-maximum-call-stack-size-exceeded-in-wordarray-to-bytearray-conversion/58937696#58937696
This is pretty bad and buggy code. See the multiple comments. I will look for something more scalable and less errors
I wrote an unit test for this. This implementation works only for converting Uint8Array to CryptoJS.lib.WordArray and back.
It fails for converting CryptoJS.lib.WordArray to Uint8Array and back, the reverse conversion returns different values. That's really bad.
code:
` // ORIGINAL IMPLEMENTATION
static ba2wa(ba) {
var wa = [],
i;
for (i = 0; i < ba.length; i++) {
wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i);
}
return CryptoJS.lib.WordArray.create(wa, ba.length);
}
private static w2ba(word, length) {
var ba = [],
i,
xFF = 0xFF;
if (length > 0)
ba.push(word >>> 24);
if (length > 1)
ba.push((word >>> 16) & xFF);
if (length > 2)
ba.push((word >>> 8) & xFF);
if (length > 3)
ba.push(word & xFF);
return ba;
}
static wa2ba(wordArray, length) {
if (wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")) {
length = wordArray.sigBytes;
wordArray = wordArray.words;
}
var result = [],
bytes,
i = 0;
while (length > 0) {
bytes = this.w2ba(wordArray[i], Math.min(4, length));
length -= bytes.length;
result.push(bytes);
i++;
}
return [].concat.apply([], result);
}
`
test:
`
it('should convert a large CryptoJS.lib.WordArray to a Uint8Array and back to the same CryptoJS.lib.WordArray',
() => {
// Arrange
const input = CryptoJS.lib.WordArray.random(10);
console.log(JSON.stringify(input.words));
// Act
const result1 = WordArrayExtensions.wa2ba(input, null);
const result2 = WordArrayExtensions.ba2wa(result1);
// Assert
expect(result1).toBeDefined();
expect(result2).toBeDefined();
expect(result2.words).toEqual(input.words);
});
`
thank a lot <3
Combined and rewrote the words-to-bytes-function to be a bit faster. Just in case someone needs it.
function cryptArrToByteArr(wordArray) {
var bytes = new Uint8Array(wordArray.sigBytes);
var fullwords = wordArray.sigBytes >>> 2; //equal div 4
var lastbytes = wordArray.sigBytes % 4;
var word, offs;
for (var i = 0; i < fullwords; i++) {
word = wordArray.words[i];
offs = i<<2;
bytes[offs] = word >>> 24;
bytes[offs+1] = (word >>> 16) & 0xFF;
bytes[offs+2] = (word >>> 8) & 0xFF;
bytes[offs+3] = word & 0xFF;
}
if (lastbytes > 0) {
word = wordArray.words[fullwords];
offs = fullwords<<2;
bytes[offs] = word >>> 24;
if (length > 1) bytes[offs+1] = (word >>> 16) & 0xFF;
if (length > 2) bytes[offs+2] = (word >>> 8) & 0xFF;
}
return bytes;
}
The above code has errors too, although I definitely prefer its intended efficiency:
if (lastbytes > 0) {
word = wordArray.words[fullwords];
offs = fullwords<<2;
bytes[offs] = word >>> 24;
if (lastbytes > 1) bytes[offs+1] = (word >>> 16) & 0xFF;
if (lastbytes > 2) bytes[offs+2] = (word >>> 8) & 0xFF;
}
In case anyone comes here looking for a solution, here is what I ended up using:
/** Returns a crypto-JS compatible Word Array, based on the byte array provided */
static toWordArray(bytes) {
var words = [];
for (var j = 0; j < bytes.length; j++) {
words[(j>>>2)] |= bytes[j] << (24 - (8 * (j%4)));
}
return CryptoJS.lib.WordArray.create(words, bytes.length);
}
/** Returns a byte array, based on the crypto-JS compatible word array provided */
static fromWordArray(wordArray) {
var bytes = new Uint8Array(wordArray.sigBytes);
for (var j=0; j<wordArray.sigBytes; j++) {
bytes[j] = (wordArray.words[(j>>>2)] >>> (24 - (8 * (j%4)))) & 0xFF
}
return bytes;
}
when convert a word array size of sigBytes of 1189455, i got error of Maximum call stack size exceeded
