Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.01.2023, 12:47
Аватар для webgraph
Профессор
Отправить личное сообщение для webgraph Посмотреть профиль Найти все сообщения от webgraph
 
Регистрация: 14.11.2014
Сообщений: 186

Как сохранить двоичный код в файл?
Как сохранить число или иную информацию в файл в виде двоичного кода?

//1673357377000 — весит целых 13 байтов

console.log((1673357377000 >>> 0).toString(2));

//10011011110111110011110111101000 — весит всего 4 байта




//340282366920938463463374607431768211455 — весит целых 39 байт

console.log((340282366920938463463374607431768211455n).toString(2))

//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 — весит всего 16 байт


В данном примере 1673357377000 — это дата в секундах от 1 янв 1970. Допустим, надо сохранить много дат в файл — каждая дата с новой строки. Как же это сделать?


Попробовали такой код, но нули и единицы всё равно сохраняются как байты:

var sampleBits = (1673357377000 >>> 0).toString(2);

    var saveBitArray = (function () {
        var a = document.createElement("a");
        document.body.appendChild(a);
        a.style = "display: none";
        return function (data, name) {
            var blob = new Blob(data, {type: "octet/stream"}),
                url = window.URL.createObjectURL(blob);
            a.href = url;
            a.download = name;
            a.click();
            window.URL.revokeObjectURL(url);
        };
    }());

    saveBitArray([sampleBits], 'example');

Последний раз редактировалось webgraph, 15.01.2023 в 12:50.
Ответить с цитированием
  #2 (permalink)  
Старый 15.01.2023, 13:51
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Двоичные данные надо сохранять через типизированные массивы

<body>
<script>
const sampleBits = 1673357377000;
 
   const saveBitArray = function (data, filename) {
		const buffer = new ArrayBuffer(8);
		const bindata = new Float64Array(buffer);
		bindata[0] = data;
		
        const a = document.createElement("a");
        a.download = filename;
        document.body.append(a);
        
        a.style = "display: none";
        
        const blob = new Blob([buffer], {type: "octet/stream"});
        const url = window.URL.createObjectURL(blob);
        a.href = url;
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
    };
 
    saveBitArray(sampleBits, 'examplebin');
</script>
</body>
Ответить с цитированием
  #3 (permalink)  
Старый 15.01.2023, 14:02
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Сообщение от webgraph
надо сохранить много дат в файл — каждая дата с новой строки. Как же это сделать?
Бинарные данные не хранятся по строкам. Будет непонятно, как искать разделитель строк.
Ответить с цитированием
  #4 (permalink)  
Старый 15.01.2023, 14:20
Аватар для webgraph
Профессор
Отправить личное сообщение для webgraph Посмотреть профиль Найти все сообщения от webgraph
 
Регистрация: 14.11.2014
Сообщений: 186

Сообщение от voraa
const buffer = new ArrayBuffer(8);
А почему вы создали массив из 8 байтов если требуется 4?
Ответить с цитированием
  #5 (permalink)  
Старый 15.01.2023, 14:31
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Сообщение от webgraph
//10011011110111110011110111101000 — весит всего 4 байта
1673357377000
В 2 это 00000001 10000101 10011011 11011111 00111101 11101000
В 16 это 01 85 9B DF 3D E8
Ну никак не 4 байта, а 6

Такие числа представляются как double64
В js целые числа меньшие 2**53 - 1 хранятся как денормализованные double64

В windows есть калькулятор. Проверьте в режиме "программист"

Последний раз редактировалось voraa, 15.01.2023 в 14:33.
Ответить с цитированием
  #6 (permalink)  
Старый 15.01.2023, 14:47
Аватар для webgraph
Профессор
Отправить личное сообщение для webgraph Посмотреть профиль Найти все сообщения от webgraph
 
Регистрация: 14.11.2014
Сообщений: 186

Сообщение от voraa Посмотреть сообщение
1673357377000
В 2 это 00000001 10000101 10011011 11011111 00111101 11101000
В 16 это 01 85 9B DF 3D E8
Ну никак не 4 байта, а 6

Такие числа представляются как double64
В js целые числа меньшие 2**53 - 1 хранятся как денормализованные double64

В windows есть калькулятор. Проверьте в режиме "программист"
Да, видимо из-за сдвига >>> 0 уменьшилось итоговое количество битов (Зачем его там тогда вообще применяли??). Число 1673357377000 (в миллисекундах) в двоичной системе имеет значение 11000010110011011110111110011110111101000 (41 бит).

Получается, если хранить в секундах — 1673357377, то это поместится в 4 байта 1100011101111010110100001000001 (31 бит).


А как тогда сохранить в файл большое беззнаковое целое число?

const bigInt = 340282366920938463463374607431768211455n;

console.log(bigInt.toString(2))
Ответить с цитированием
  #7 (permalink)  
Старый 15.01.2023, 14:50
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Сообщение от webgraph
Да, видимо из-за сдвига >>> 0 уменьшилось итоговое количество битов
Конечно. При всех побитовых операциях в js числа переводятся в формат int32 с отбрасыванием старших бит.
Ответить с цитированием
  #8 (permalink)  
Старый 15.01.2023, 14:51
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Сообщение от webgraph
А как тогда сохранить в файл большое беззнаковое целое число?
Только в виде строки.
Ну или самим писать функции преобразования их в двоичные и обратно.
Ответить с цитированием
  #9 (permalink)  
Старый 15.01.2023, 15:15
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Что то вроде такого
<body>
<script>
const sampleBits = 340282366920938463463374607431768211455n;
const toBinArr = (data) => {
	const binstr = data.toString(2);
	const len = binstr.length;
	const arr = [];
	let bb = 0;
	let shift = 0;
	for (let i=0; i<len; i++) {
		const bit = binstr.at(-i-1);
		if (bit === '1') 
			bb |= 1<<shift;
		shift ++;
		if (i%8 == 7) {
			arr.unshift(bb);
			bb=0;
			shift = 0;
		}
	}
	if (bb) arr.unshift(bb);
	return arr;
}
 
const saveBitArray = function (data, filename) {
	const binar = toBinArr(data);
	const buffer = new ArrayBuffer(binar.length);
	let bindata = new Uint8Array(buffer);
	for (let i=0; i<binar.length; i++) 
		bindata[i] = binar[i];
		
    const a = document.createElement("a");
    a.download = filename;
    document.body.append(a);
        
    a.style = "display: none";
        
    const blob = new Blob([buffer], {type: "octet/stream"});
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
};
 
saveBitArray(sampleBits, 'examplebin');
</script>
</body>
Ответить с цитированием
  #10 (permalink)  
Старый 15.01.2023, 15:16
Аватар для webgraph
Профессор
Отправить личное сообщение для webgraph Посмотреть профиль Найти все сообщения от webgraph
 
Регистрация: 14.11.2014
Сообщений: 186

Сообщение от voraa Посмотреть сообщение
Только в виде строки.
Ну или самим писать функции преобразования их в двоичные и обратно.
Ну, преобразование-то и так работает же.

// Псевдопример 

const bigInt = 340282366920938463463374607431768211455n;

const binaryBigInt = bigInt.toString(2);

console.log(binaryBigInt)
// выведет 11111111....11111111 (128 единиц, т.е. 128 бит = 16 байт)

const arrayBuffer = new ArrayBuffer(16);

const binaryData = new Uint128Array(arrayBuffer); // Uint128Array не существует — типа надо эту функцию создать?

binaryData[0] = binaryBigInt;
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно сохранить загруженный файл? 2chan Node.JS 10 03.04.2016 23:11
Как сохранить данные в файл? Возможно такое на JavaScript? Forgott Общие вопросы Javascript 35 26.06.2015 19:11
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 13:29
Как запустить на выполнение код файла kgn Общие вопросы Javascript 4 06.01.2012 22:08
Как можно достать файл из <input type="file"/> преобразовать файл в base 64 maxcab Events/DOM/Window 2 28.06.2011 22:52