-
-
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); | |
} |
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;
}
Maximum call stack size exceeded error too when trying to decrypt a video file

Can someone help me with this please?