La documentación de Node.js FS dice que readFileSync de readFileSync solo devuelve el contenido del archivo de destino. Ese enlace es a la documentación de readFile pero la sección sobre readFileSync dice que consulte los documentos de readFile . Supuestamente, NodeJS readFile "lee de forma asincrónica todo el contenido de un archivo".
Quiero generar un hash de un archivo. Uso la biblioteca crypto pero estoy dispuesto a usar otras bibliotecas o métodos. El hash no puede basarse solo en el contenido del archivo. Tiene que usar todos los bytes del propio archivo. Por ejemplo, suponga que la ruta apunta a un archivo que usa el formato PE de Microsoft. Los bytes en el encabezado del archivo que representan Machine , NumberOfSections , etc. deben usarse en el hash. Quiero hacer eso a un archivo de texto. Además, este es un enlace a un artículo de Microsoft sobre el formato PE: formato PE . El siguiente código imprime tan pocos bytes en la consola, lo que implica que solo se lee el contenido.
const crypto = require('crypto') function hash (path) { const hash_object = crypto.createHash('sha256'); const file_as_buffer = fs.readFileSync(path) hash_object.update(file_as_buffer); const hash_string = hash_object.digest('hex'); console.log("Has input", file_as_buffer); return hash_string; } hash('test.txt');Suponiendo que el archivo solo contiene un carácter de nueva línea, la salida en la consola para esto es un solo byte. ¿Cómo uso los bytes que representan el archivo de texto completo, incluidos los metadatos como el autor y la fecha de creación, como entrada para la función hash?
Confirmé que en copias idénticas del archivo, usar el código anterior devuelve el mismo hash para diferentes copias del mismo archivo. Esto sucede incluso si su nombre de archivo es diferente o si se crearon con unos minutos de diferencia. ¿Cómo evito eso?
Si necesita que el hash sea diferente para diferentes archivos con el mismo contenido, deberá considerar los metadatos del archivo que puede obtener de fs.stat .
function hash (path) { const hash_object = crypto.createHash('sha256'); const file_as_buffer = fs.readFileSync(path); const file_meta = fs.statSync(path); // Get file stats const allFile = Buffer.concat([file_as_buffer, Buffer.from(JSON.stringify(file_meta))]); //Add them to the input buffer for hashing hash_object.update(allFile); const hash_string = hash_object.digest('hex'); console.log("Has input", file_as_buffer); return hash_string; }Esta es la respuesta final que usé. Es casi lo mismo que la respuesta de Charlie. Acabo de aceptar las sugerencias en los comentarios para seleccionar elementos específicos de los resultados de fs.statSync . Tomé la suma de mtime (tiempo modificado, supongo), ctime (tiempo creado) y size . Las siguientes operaciones se realizan todas en una línea. Convertí explícitamente la suma en una cadena y creé un búfer a partir de la cadena. Por último, concatené los dos búferes.
function hash(path: string): string { const hash_object = crypto.createHash('sha256'); const file_as_buffer = fs.readFileSync(path) let blockfile_stat = fs.statSync(path); let blockfile_stat_num: number = blockfile_stat.mtimeMs + blockfile_stat.ctimeMs + blockfile_stat.size; hash_object.update(Buffer.concat( [file_as_buffer, Buffer.from(String(blockfile_stat_num))]) ); const hash_string = hash_object.digest('hex'); return hash_string; }