Плагин криптопро работает с base64 данными.
Поэтому подписи и шифр отгружаются клиенту в текстовом формате (enc).
А хочется в двоичном (p7e). Можно конечно шифр отправлять на сервер и оттуда загружать преобразованный.
Но может спецы знают как преобразовать данные в браузере?
Здравствуйте, vaa, Вы писали:
vaa>Плагин криптопро работает с base64 данными. vaa>Поэтому подписи и шифр отгружаются клиенту в текстовом формате (enc). vaa>А хочется в двоичном (p7e). Можно конечно шифр отправлять на сервер и оттуда загружать преобразованный. vaa>Но может спецы знают как преобразовать данные в браузере?
let create_blob_from_base64String = function (base64String, contentType) {
const byteCharacters = atob(base64String);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: contentType || 'text/json' });
return (blob);
}
Здравствуйте, Igorxz, Вы писали:
I>Здравствуйте, vaa, Вы писали:
vaa>>Плагин криптопро работает с base64 данными. vaa>>Поэтому подписи и шифр отгружаются клиенту в текстовом формате (enc). vaa>>А хочется в двоичном (p7e). Можно конечно шифр отправлять на сервер и оттуда загружать преобразованный. vaa>>Но может спецы знают как преобразовать данные в браузере?
I>
I>let create_blob_from_base64String = function (base64String, contentType) {
I> const byteCharacters = atob(base64String);
I> const byteNumbers = new Array(byteCharacters.length);
I> for (let i = 0; i < byteCharacters.length; i++) {
I> byteNumbers[i] = byteCharacters.charCodeAt(i);
I> }
I> const byteArray = new Uint8Array(byteNumbers);
I> const blob = new Blob([byteArray], { type: contentType || 'text/json' });
I> return (blob);
I>}
I>
Спасибо! Я правда немного не так сделал, у меня кусками данные. Так отработало.
function _base64ToArrayBuffer(base64String) {
console.log(base64String);
const byteCharacters = atob(base64String);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
return byteNumbers;
}
arr = arr.concat(_base64ToArrayBuffer(chunk));
new Blob([arr], { type: "octet/stream" });
Но все равно облом. Похоже ограничение размера массива где-то в районе 64Мб, исходный файл 81Мб, чанк 1МБ, на 77% такая шляпа:
Uncaught (in promise) RangeError: Invalid array length
at Array.concat (<anonymous>)
I>странно. ну, у меня, вот такой код отрабатывает без ошибок. прям в консоли. I>
I>const byteNumbers = new Array(Math.pow(2, 30))
I>
I>тему надо исследовать глубжее.
непонятно, размер логирую, не отличается от предыдущих порций
взял другой файл чуть большего размера, примерно в том же месте упало.
Переписал
var add = _base64ToArrayBuffer(data);
for (let i = 0; i < add.length; i++) {
arr.push(add[i]);
}
arr.push(...add); // <= вот так не работает при даже при data = 0.5МБ
Здравствуйте, vaa, Вы писали: I>>странно. ну, у меня, вот такой код отрабатывает без ошибок. прям в консоли. I>>
I>>const byteNumbers = new Array(Math.pow(2, 30))
I>>
I>>тему надо исследовать глубжее. vaa>непонятно, размер логирую, не отличается от предыдущих порций vaa>взял другой файл чуть большего размера, примерно в том же месте упало. vaa>Переписал vaa>
vaa> var add = _base64ToArrayBuffer(data);
vaa> for (let i = 0; i < add.length; i++) {
vaa> arr.push(add[i]);
vaa> }
vaa>arr.push(...add); // <= вот так не работает при даже при data = 0.5МБ
vaa>
ну, собсно, сам ресурс оперативной памяти ограничен. это понятно. теперь нужно понять: а есть какое-то ограничение именно со стороны браузеров.
судя по докам — его явного нет.
теперь дальше: выделяя память вот так:
const byteNumbers = new Array(Math.pow(2, 30))
мы на самом деле ничего не выделяем. пока не начинаем лезть уже непосредственно к это памяти.
не забываем, что джаваскрипт в браузере — это хрен знает какой уровень абстракции. чем выше по абстракции — тем больше сюрпризов/зависимостей.
(в т.ч. поэтому на всяких а-ля сях всегда можно будет сделать то, что нельзя на джаваскриптах) вощем, долго писать))
вот так работает:
let finita_arrays = new Array(250*1024);
for (let i = 0; i < finita_arrays.length; i++) {
let arr = new Array(1024);
for (let j = 0; j < arr.length; j++) {
arr[ j ] = j;
}
finita_arrays[i] = arr;
}
const blob = new Blob(finita_arrays, { type: 'x/z' });
console.log(blob.size/(1024*1024));
=>
978.759765625 (мб)
в пике вкладка хрома сжирает > 4GB. ну и ясно, что все это машино-индивидуально.
Здравствуйте, Igorxz, Вы писали:
I>вот так работает: I>
I>let finita_arrays = new Array(250*1024);
I>for (let i = 0; i < finita_arrays.length; i++) {
I> let arr = new Array(1024);
I> for (let j = 0; j < arr.length; j++) {
I> arr[ j ] = j;
I> }
I> finita_arrays[i] = arr;
I>}
I>const blob = new Blob(finita_arrays, { type: 'x/z' });
I>console.log(blob.size/(1024*1024));
I>
I>=> I>
I>978.759765625 (мб)
I>
Я кажется понял в чем дело. На СО чел указал на ограничения браузера по памяти console.memory
и в случае если создать массив через var arr = [], видимо потом добавляемые через arr = arr.concat байты преобразуются во float, обертка который занимает 50+ байт.
тогда и получаются искомые ~ 60Мб, парадокс в том, что поштучное добавление элементов работает.
Здравствуйте, vaa, Вы писали:
vaa>Я кажется понял в чем дело. На СО чел указал на ограничения браузера по памяти console.memory vaa>и в случае если создать массив через var arr = [], видимо потом добавляемые через arr = arr.concat байты преобразуются во float, обертка который занимает 50+ байт. vaa>тогда и получаются искомые ~ 60Мб, парадокс в том, что поштучное добавление элементов работает.
тут дело в том, что, что такое:
arr = arr.concat(arr_2)
— это уже есть занятая память под два массива, нужно выделить память под третий, суммарно равный двум этим, туда скопировать данные. и это все существует вместе одновременно.
(не берем случаи, когда память резервируется (в менеджере памяти/аллокаторе) и там можно не перевыделять а занять резервируемую — т.к. это из джаваскрипта все равно неуправляемо — как повезет и т.д.)
в отличие от выделенного заранее одного и заполненного по байтно.
I>- это уже есть занятая память под два массива, нужно выделить память под третий, суммарно равный двум этим, туда скопировать данные. и это все существует вместе одновременно. I>(не берем случаи, когда память резервируется (в менеджере памяти/аллокаторе) и там можно не перевыделять а занять резервируемую — т.к. это из джаваскрипта все равно неуправляемо — как повезет и т.д.) I>в отличие от выделенного заранее одного и заполненного по байтно.
вообщем, решил проблему.
var arrayOne = new Uint8Array([2,4,8]);
var arrayTwo = new Uint8Array([16,32,64]);
var mergedArray = new Uint8Array(arrayOne.length + arrayTwo.length);
mergedArray.set(arrayOne);
mergedArray.set(arrayTwo, arrayOne.length);
файл в 200МБ успешно зашифрован поточным методом и выгружен на диск.