Cálculo del hash de archivos en intercambios seguros
En Secure Exchanges, utilizamos un método robusto y eficiente para calcular el hash SHA-512 de archivos de todos los tamaños. Nuestro enfoque garantiza la seguridad e integridad de los datos, a la vez que optimiza el rendimiento para archivos de gran tamaño.
Método de cálculo de hash
Archivos de 1 GB o menos :
- Para archivos de tamaño igual o menor a 1 GB, utilizamos un método estándar de cálculo del hash SHA-512 en una sola pasada en todo el archivo.
Archivos de más de 1 GB :
- Para archivos de más de 1 GB, dividimos el archivo en bloques de 100 MB.
- Calculamos el hash SHA-512 de cada bloque individualmente.
- Combinamos los hashes de cada bloque en una sola cadena.
- Calculamos el hash final de esta cadena combinada.
Consulta en línea
Para ofrecer a nuestros usuarios la máxima flexibilidad, cualquier persona con un archivo también puede consultar nuestra página dedicada a calcular su hash: Calculadora de Hash . Este servicio está diseñado para proporcionar un cálculo de hash rápido y fiable, independientemente del tamaño del archivo.
A partir del 24 de junio de 2024, implementamos este nuevo método de cálculo de hash para mejorar el rendimiento y la gestión de archivos grandes. Antes de esta fecha, el hash se calculaba mediante el método tradicional. Esta actualización refleja nuestro compromiso continuo con la optimización de nuestros servicios para satisfacer las necesidades de nuestros usuarios.
En Secure Exchanges, nos comprometemos a brindar soluciones seguras y eficientes para todas sus necesidades de gestión de archivos.
Código de ejemplo
Aquí hay algunos ejemplos de código en C#, JavaScript para calcular el hash SHA-512 de un archivo utilizando nuestro enfoque.
do#
utilizando el sistema;
utilizando System.Collections.Generic;
utilizando System.IO;
utilizando System.Security.Cryptography;
utilizando System.Text;
- Hashing de clase estática pública
- {
- cadena estática pública GetSHA512OfFile(cadena filePath)
- {
- si (Archivo.Existe(rutaArchivo))
- {
- constante int tamaño del fragmento = 100 * 1024 * 1024; // 100 MB
- constante larga largeFileTrigger = 1000 * 1024 * 1024; // 1 GB
- FileInfo fileInfo = new FileInfo(rutaArchivo);
- tamaño de archivo largo = fileInfo.Length;
- si (tamaño del archivo <= largeFileTrigger)
- {
- // Para archivos menores o iguales a 1 GB, calcule el hash directamente
- usando (var stream = new BufferedStream(Archivo.OpenRead(filePath), chunkSize))
- {
- devolver GetSHA512OfStream(flujo);
- }
- }
- demás
- {
- // Para archivos de más de 1 GB, utilice el método fragmentado
- Lista<string> blockHashes = nueva Lista<string>();
- usando (var stream = new BufferedStream(Archivo.OpenRead(filePath), chunkSize))
- {
- byte[] buffer = nuevo byte[chunkSize];
- int bytesLeído;
- mientras ((bytesRead = stream.Read(buffer, 0, chunkSize)) > 0)
- {
- usando (SHA512 sha512 = SHA512.Create())
- {
- byte[] chunkHash = sha512.ComputeHash(búfer, 0, bytesRead);
- blockHashes.Add(BitConverter.ToString(chunkHash).Replace("-", "").ToLower());
- }
- }
- }
- // Combinar hashes de bloque y calcular el hash final
- cadena combinedHashString = cadena.Join("", blockHashes);
- usando (SHA512 sha512 = SHA512.Create())
- {
- byte[] finalHash = sha512.ComputeHash(Encoding.UTF8.GetBytes(combinedHashString));
- devuelve BitConverter.ToString(finalHash).Replace("-", "").ToUpper();
- }
- }
- }
- demás
- {
- devuelve nulo;
- }
- }
- cadena estática pública GetSHA512OfStream(Stream stream)
- {
- usando (var sha = SHA512.Create())
- {
- devuelve GetHexaString(sha.ComputeHash(stream));
- }
- }
- cadena estática privada GetHexaString(byte[] hash)
- {
- si (hash != nulo)
- {
- StringBuilder sb = nuevo StringBuilder();
- para (int i = 0; i < hash.Length; i++)
- {
- sb.Append(hash[i].ToString("X2"));
- }
- devolver sb.ToString();
- }
- devolver cadena.Vacío;
}
}
Javascript

- var ventana = self;
- var documento = {};
- onmessage = función asíncrona (argumentos) {
- var obj = args.data;
- deje que el lector = nuevo FileReader();
- var hash = {};
- var chunkSize = 100 * 1024 * 1024; // Tamaño de fragmento de 100 MB para archivos grandes
- var largeFileTrigger = 1000 * 1024 * 1024; // El archivo de 1 GB utilizará el enfoque de bloque
- var isLargeFile = obj.File.size > largeFileTrigger;
- constante chunksQuantity = Math.ceil(obj.File.size / chunkSize);
- const chunksQueue = nueva Array(chunksQuantity).fill().map((_, índice) => índice).reverse();
- deje que blockHashes = [];
- reader.onload = función asíncrona (evt) {
- si (esArchivoGrande) {
- deje que blockHash = espere digestMessage(evt.currentTarget.result);
- blockHashes.push(blockHash);
- } demás {
- blockHashes.push(evt.currentTarget.result);
- }
- leerSiguiente();
- }
- deje que readNext = función asíncrona () {
- si (chunksQueue.length > 0) {
- constante chunkId = chunksQueue.pop();
- constante tamañoEnviado = chunkId * tamañoDeChunk;
- const chunk = obj.File.slice(enviadoTamaño, enviadoTamaño + chunkSize);
- lector.readAsArrayBuffer(fragmento);
- } demás {
- lector.abort();
- var hexHash = nulo;
- si (esArchivoGrande) {
- deje que combinedHashBuffer = nuevo TextEncoder().encode(blockHashes.join(''));
- hexHash = esperar digestMessage(combinedHashBuffer);
- } demás {
- hexHash = esperar mensaje de digestión (blockHashes[0]);
- }
- hash.SHA512 = hexHash.toUpperCase();
- postMessage({ Hash: hash, Archivo: obj.File, ID: obj.ID, ReturnObject: obj.ReturnObject });
- }
- }
- leerSiguiente();
- }
- // Función para digerir el mensaje y devolver una cadena hexadecimal
- función asíncrona digestMessage(buffer) {
- constante hashBuffer = await crypto.subtle.digest('SHA-512', buffer);
- constante hashArray = Array.from(new Uint8Array(hashBuffer));
- constante hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
- devuelve hashHex;
- }