您无需将二进制数据转换为十六进制即可替换其中的任何内容。如果要替换二进制文件中的数据,则意味着您确切地知道要替换的内容,这意味着基于某些模式或数据结构或字节块的特定偏移量,您必须搜索。
如果您想为您的客户创建一个在线十六进制编辑器,那是完全不同的事情,它不仅涉及后端逻辑,还涉及允许用户上传/编辑和下载文件的 UI。
使用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);
// 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);
}
}
将输出如下内容:
对于网页 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,您可以使用它来存储二进制数据。将文件保存到文件系统并仅使用字段来保存其路径也是一种不错的方法,但您必须处理备份/恢复,包括将存储文件的目录。