UNPKG

mcard-js

Version:

MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers

84 lines 3.36 kB
export class BinarySignatureDetector { // Dictionary of binary signatures mapped to MIME types // Note: In TS, we use numbers or number arrays for bytes static SIGNATURES = { // Images '89504e470d0a1a0a': 'image/png', // \x89PNG\r\n\x1a\n 'ffd8ff': 'image/jpeg', '474946383761': 'image/gif', // GIF87a '474946383961': 'image/gif', // GIF89a '424d': 'image/bmp', // BM '00000100': 'image/x-icon', '00000200': 'image/x-icon', // MP4 '00000018667479706d703432': 'video/mp4', // ...ftypmp42 '000000186674797069736f6d': 'video/mp4', // ...ftypisom // ... (simplified for key common ones) // Documents '25504446': 'application/pdf', // %PDF // Archives '504b0304': 'application/zip', // PK\x03\x04 '1f8b08': 'application/gzip', '526172211a0700': 'application/x-rar-compressed', // Rar! '377abcaf271c': 'application/x-7z-compressed', // 7z... // Database '53514c69746520666f726d6174203300': 'application/x-sqlite3', // SQLite format 3\0 }; static OLE_SIGNATURE = 'd0cf11e0a1b11ae1'; /** * Helper to convert hex string to Uint8Array for easy comparison if needed, * but we will convert input bytes to hex for lookup. */ detect(content) { return this.detectFromBytes(content); } detectFromBytes(content) { // Handle RIFF (WAV, WebP) if (this.startsWithAscii(content, 'RIFF')) { return this.detectRiffFormat(content); } // Convert start of content to hex string for signature matching // Max signature length is roughly 16 bytes for what we have const hexHeader = this.toHex(content.slice(0, 32)); for (const [signature, mimeType] of Object.entries(BinarySignatureDetector.SIGNATURES)) { if (hexHeader.startsWith(signature)) { if (signature === BinarySignatureDetector.OLE_SIGNATURE) { return 'application/oleobject'; } if (signature === '504b0304') { // PK\x03\x04 // Check logic for OpenXML could go here, but omitted for parity with basic Python logic shown return 'application/zip'; } return mimeType; } } return 'application/octet-stream'; } detectRiffFormat(content) { if (content.length < 12) return 'application/octet-stream'; // Check format type at offset 8 const formatType = this.toAscii(content.slice(8, 12)); if (formatType === 'WAVE') return 'audio/wav'; if (formatType === 'WEBP') return 'image/webp'; return 'application/octet-stream'; } startsWithAscii(content, str) { if (content.length < str.length) return false; for (let i = 0; i < str.length; i++) { if (content[i] !== str.charCodeAt(i)) return false; } return true; } toAscii(content) { return Array.from(content).map(b => String.fromCharCode(b)).join(''); } toHex(content) { return Array.from(content).map(b => b.toString(16).padStart(2, '0')).join(''); } } //# sourceMappingURL=BinarySignatureDetector.js.map