Расширение Chrome - получение типа файла на основе магического числа - PullRequest
0 голосов
/ 22 апреля 2019

Мне нужно написать расширение Chrome, которое получает загруженный тип файла.

Это существующий код, который получает его по файлу расширения.

chrome.downloads.onDeterminingFilename.addListener(function(item, __suggest) {

    function suggest(filename, conflictAction) {
        __suggest({
            filename: filename,
            conflictAction: conflictAction,
            conflict_action: conflictAction
        });
    }
    var fileType = item.fileName.substr(item.fileName.lastIndexOf('.') + 1);
    console.log(fileType);
});

Мне нужно изменить код, чтобы получить его на основе магического номера файла.

https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files

Как?

1 Ответ

1 голос
/ 22 апреля 2019

Используя информацию из этой страницы , это способ получения магических чисел из файлов. Пожалуйста, выберите для проверки несколько файлов с вашего компьютера с различными типами.

let filesRead = [];
let numFiles = 0;

function treatResult() {
	filesRead.map(e=>{
	        const uint = new Uint8Array(e.fileStart);
                let bytes = [];
                uint.forEach((byte)=>bytes.push(byte.toString(16)));
                e.magicNumber = bytes.join('').toUpperCase();
		e.typeFromMagicNumber = getTypeFromMagicNumber(e.magicNumber);
	});
	let list = filesRead.map(e=>
		'<li>Name: ' + e.name + ' ||| MimeType: ' + e.type + ' ||| Magic Number: ' + 
		    e.magicNumber + ' ||| Type from mn: ' + e.typeFromMagicNumber + '</li>').join('');
	document.getElementById('list').innerHTML = list;
}	

function getTypeFromMagicNumber(signature) {
	switch (signature) {
	    case '89504E47':
		return 'image/png'
	    case '47494638':
		return 'image/gif'
	    case '25504446':
		return 'application/pdf'
	    case 'FFD8FFDB':
	    case 'FFD8FFE0':
	    case 'FFD8FFE1':
		return 'image/jpeg'
	    case '504B0304':
		return 'application/zip'
	    default:
		return 'Unknown filetype'
	}
}

function treatFile(file) {
        const blob = file.slice(0, 4);
        var reader = new FileReader();
	reader.readAsArrayBuffer(blob);
	reader.onprogress = function(event) {
	    filesRead.push({name: file.name, type : file.type, fileStart: event.target.result});
	    reader.abort();
	    if (filesRead.length == numFiles) 
    		treatResult();
	};
}

function handleFileSelect(evt) {
	var files = evt.target.files;
	numFiles = files.length;
	for (var i = 0, f; f = files[i]; i++) 
    	treatFile(files[i]);
}

document.getElementById('files').addEventListener('change', handleFileSelect, false);
<html>
<body>
        <h1>List files with magic number types</h1>
        <input type="file" id="files" name="files[]" multiple />

        <ul id='list'></ul>

<script src="teste.js"></script>
</body>
</html>                     

Обратите внимание, что объект file, возвращаемый входными данными, уже сообщает тип файла в свойстве type.

На странице, которую я упомянул, для чтения файла использовался метод onloadend. Поскольку нам нужны только первые несколько байтов, я не думаю, что необходимо читать весь файл.

Также таблица магических чисел очень ограничена и должна быть улучшена для реального приложения.

РЕДАКТИРОВАТЬ на основе комментария

К вашему сведению, все эти операции выполняются на уровне клиента. ReadFile может только читать файлы клиентского компьютера. Так что здесь нет загрузки. Если вы пытаетесь прочитать файл на сервере, чтобы проверить его магическое число перед загрузкой, это невозможно, поскольку сервер не разрешил вам читать файлы в нем с помощью клиента.

Что возможно, так это чтобы сервер подготовил URL-адрес для приема входящих вызовов, а затем ответил файлом, страницей или информацией. Но сделать расширение, которое читает загружаемый файл, невозможно. Файл можно прочитать только после загрузки или, по крайней мере, после начала загрузки.

...