Вам не нужно преобразовывать двоичные данные в шестнадцатеричные, чтобы заменить что-либо в них. Если вы хотите заменить данные внутри двоичного файла, это означает, что вы точно знаете, что хотите заменить, а это означает определенные смещения, основанные на некоторых шаблонах, структуре данных или фрагментах байтов, которые вам придется ищи.
Если вы хотите создать шестнадцатеричный онлайн-редактор для своих клиентов, то это совершенно другое дело, и оно включает в себя не только внутреннюю логику, но и пользовательский интерфейс, который позволит пользователям загружать/редактировать и скачивать файлы.
Замена двоичных данных двоичными данными с фиксированным смещением с использованием Buffer.copy
:
// The first three bytes of data Buffer will be replaced with 0x02 0x03 0x04 bytes
Buffer.alloc(3, new Uint8Array([0x02, 0x03, 0x04])).copy(data, 0, 0, 3);
Использование Buffer.indexOf
для поиска шаблонов двоичных данных:
// Loading a PNG image
const data = fs.readFileSync('js-logo-16x16.png');
// Search for the PNG signature using Buffer.indexOf
const sigpos = data.indexOf(Buffer.from('PNG'));
if (sigpos >= 0) {
// If signature pos found (!= -1), replace it with JPG using Buffer.write
data.write('JPG', sigpos, 3);
}
Вы можете использовать простую логику обработки циклов и строк для печати шестнадцатеричных данных:
// For Node.js using a Buffer
function displayHexData(data) {
for (let addr = 0; addr <= data.length; addr += 16) {
const displayAddr = addr.toString(16).toUpperCase().padStart(8, '0');
const block = data.slice(addr, Math.min(addr + 16, data.length));
let hexblock = block.toString('hex');
if (addr + 16 > data.length) {
hexblock += ' '.repeat(16 - (data.length - addr));
}
const charsblock = Array.from(block)
.map(b => b >= 32 && b <= 126 ? String.fromCharCode(b) : '.')
.join('');
console.log(displayAddr, hexblock.split(/(.{2})/).join(' '), charsblock);
}
}
выведет что-то вроде этого:
![Отображение двоичных данных Node.js в шестнадцатеричном формате](https://i.stack.imgur.com/kIoBU.png)
И для веб-JavaScript:
// 16 x 16 PNG 8-bit
const base64Data = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAA3NCSVQICAjb4U/gAAAAMFBMVEUAAADQvhqQghFBOgj/7iAjIAT84x+6qxdqYA3u1x2nlxT//CIxLAZKQwnOuhnZyBvQr3QtAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAFNJREFUCJljSIMCBlIZKW4ubmBGhkrtdTDD1Yz5rBuI4XOTyQUs4mPdEA4SSfGx3n7gCZDxKfV+24fVQEYBQyED6zQgI39d2qyVIMUpW9Kyt6UBAGorNUfBuVldAAAAAElFTkSuQmCC';
const data = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));
displayHexData(data);
function displayHexData(data) {
let result = '';
for (let addr = 0; addr <= data.length; addr += 16) {
const displayAddr = addr.toString(16).toUpperCase().padStart(8, '0');
const block = data.slice(addr, Math.min(addr + 16, data.length));
let hexblock = Array.from (block)
.map (b => b.toString(16).toUpperCase().padStart(2, "0"))
.join('');
if (addr + 16 > data.length) {
hexblock += ' '.repeat(16 - (data.length - addr));
}
const charsblock = Array.from(block)
.map(b => b >= 32 && b <= 126 ? String.fromCharCode(b) : '.')
.join('');
result += `${displayAddr} ${hexblock.split(/(.{2})/).join(' ')} ${charsblock}\n`;
}
document.getElementById('hex').appendChild(document.createTextNode(result));
}
#hex {
font-size: small;
}
<pre id="hex"></pre>
Что касается сохранения двоичных данных в базу данных, то это, конечно, зависит от типа базы данных. Большинство баз данных поддерживают тип данных Binary Large OBject (BLOB), например MySQL, и вы используете его для хранения двоичных данных. Сохранение файла в файловой системе и простое использование поля для сохранения его пути также является довольно хорошим способом, но вам придется выполнять резервное копирование/восстановление, включая те каталоги, в которых будут храниться файлы.
person
Christos Lytras
schedule
18.02.2020