Herramientas de desarrollo · Calculadora de hash SHA
Mismo texto, diferente SHA-256: nuevas líneas, codificaciones y bytes ocultos
· Cómo funciona
sha-256 codificación procesamiento de textos depuración
La línea de comando dice una cosa y el navegador dice otra para lo que parece el mismo texto. Las nuevas líneas finales, UTF-16 y CRLF explican casi todos los casos; Esta publicación muestra cómo encontrar los bytes ocultos.
echo dice un hash, la herramienta dice otro: la falta de coincidencia cotidiana y por qué ninguno de los dos está mal
Una terminal informa un resumen SHA-256 y un navegador informa otro para lo que parece ser texto idéntico. La herramienta de línea de comandos no se ha roto y el navegador tampoco. Los bytes que se procesan no son los mismos, aunque los caracteres visibles parezcan idénticos. Esta publicación rastrea las fuentes más comunes de esos bytes ocultos y muestra cómo encontrarlos con un campo de texto y un visor hexadecimal.
El problema casi nunca es el algoritmo SHA-256 en sí. SHA-256 es determinista: los mismos bytes siempre producen el mismo resumen y el resumen es correcto. Cuando las salidas difieren, los bytes difieren. La confusión surge porque "el mismo texto" es ambiguo: una persona ve caracteres, pero una función hash ve bytes, y la traducción entre ellos es donde se esconden las diferencias ocultas.
La nueva línea final: cómo echo agrega un byte y printf no, y qué efecto tiene eso en un resumen
El comando echo en un shell agrega un carácter de nueva línea (U+000A, byte 0x0A) a su salida. Esto es por diseño: la convención en Unix de que los archivos de texto terminan con una nueva línea le da a echo un trabajo simple. Cuando escribe echo abc en una terminal y lo canaliza a sha256sum, los bytes digeridos son 61 62 63 0A (los códigos ASCII para a, b, cy el byte para nueva línea), no 61 62 63. La herramienta que ToolAcre utiliza para calcular hash procesa los bytes 61 62 63 y produce un resultado diferente.
El comando printf no agrega una nueva línea a menos que escriba una en la cadena de formato. imprimirf abc | sha256sum calcula el resumen de bytes 61 62 63 solo, que coincide con la herramienta del navegador. Es por eso que comparar hashes a menudo significa ejecutar printf en lugar de echo, o conectar a sha256sum con el indicador -z, o especificar una entrada sin formato en cualquier forma que proporcione su herramienta. La nueva línea oculta es la razón más común por la que una herramienta de navegador y una herramienta de línea de comandos no están de acuerdo.
UTF-8 versus UTF-16: por qué los mismos caracteres son bytes diferentes en algunos shells y editores
UTF-8 y UTF-16 codifican los mismos caracteres como secuencias de bytes diferentes. El carácter é (U+00E9, una e con acento agudo) se codifica como dos UTF-8 bytes: 0xC3 0xA9. En UTF-16, que es como JavaScript representa internamente cadenas, el mismo carácter ocupa dos bytes en un orden diferente (dependiendo del endianidad) o una forma completamente diferente si se compone de un carácter base y una marca de combinación. Cuando copia café desde una aplicación de Windows y lo pega en una herramienta hash del navegador, es posible que los bytes que la herramienta hash no coincidan con los que tiene un terminal Mac, porque los sistemas utilizan de forma predeterminada diferentes codificaciones o formas de normalización.
La herramienta hash ToolAcre convierte explícitamente texto a UTF-8 antes del hash a través de TextEncoder. Esta es la misma codificación que utiliza la línea de comandos de Unix de forma predeterminada. El código fuente en apps/dev/src/lib/base64.js muestra la función textToBytes que llama al nuevo TextEncoder().encode(), lo que garantiza UTF-8. Si otro sistema utiliza UTF-16 o Latin-1 o cualquier otra codificación, los bytes producidos serán diferentes. La herramienta muestra el recuento de bytes junto con el resumen, por lo que al pegar café y compararlo con un hash de línea de comandos se mostrarán diferentes recuentos de bytes si las codificaciones divergen.
CRLF, BOM y normalización: finales de línea, marcas de orden de bytes y acentos compuestos versus descompuestos como diferencias de entrada invisibles
CRLF (retorno de carro + avance de línea, bytes 0x0D 0x0A) es la convención de final de línea en Windows; LF (solo avance de línea, byte 0x0A) es la convención de Unix. Un archivo de texto que parece idéntico cuando se abre en un editor de texto puede tener diferentes finales de línea, y esos bytes son parte de la entrada al hash. Un archivo editado en Windows y comparado con un SHA-256 calculado en un sistema Unix no coincidirá si un sistema ha convertido los finales de línea y el otro no.
La marca de orden de bytes (BOM, bytes 0xEF 0xBB 0xBF para UTF-8) es una secuencia opcional al comienzo de un archivo que indica la codificación. Algunos editores lo añaden; algunas herramientas lo quitan; algunos lo ignoran. Si un archivo contiene una lista de materiales y la aplica un hash byte por byte, los bytes de la lista de materiales forman parte del resumen. Si luego copia el texto visible (del cual el espectador oculta la lista de materiales) en una herramienta que no agrega una lista de materiales, los resúmenes no coincidirán. Las formas de normalización de texto (NFD frente a NFC para acentos compuestos y descompuestos) añaden otra capa: la misma letra acentuada se puede representar como un único carácter precompuesto o como un carácter base seguido de un acento combinado, y las secuencias de bytes son diferentes.
Ejemplo resuelto: una cadena codificada con y sin nueva línea, luego en dos codificaciones, y se muestra cada diferencia de byte
Método de diagnóstico uno: use una herramienta de volcado hexadecimal o un convertidor en línea para ver exactamente en qué bytes están operando sus herramientas. Pegue el texto en un codificador base64, codifíquelo y tendrá un registro textual de los bytes. Luego decodifique base64 en la línea de comando con base64 -d y canalícelo a od -A x -t x1z para ver la secuencia de bytes hexadecimales. Si los bytes coinciden, el algoritmo es correcto; si no lo hacen, la diferencia será visible.
Método de diagnóstico dos: utilice la calculadora de hash SHA ToolAcre para realizar hash de entradas progresivamente más largas, comenzando con un solo carácter. Agregue una nueva línea (lo que significa escribir Enter dentro del cuadro de texto), agregue espacios, agregue el mismo texto con secuencias de escape UTF-16 si la entrada proviene de una fuente que no es ASCII. Observe cómo cambia el resumen con cada adición. El recuento de bytes que se muestra junto al resumen le indica cuántos bytes está procesando la herramienta, lo que reduce drásticamente la búsqueda.
Caja hexadecimal y espacios en blanco en la salida: las diferencias son puramente cosméticas
La representación hexadecimal de un resumen no distingue entre mayúsculas y minúsculas. Tanto las letras mayúsculas como las minúsculas representan los mismos bytes: A = 10, a = 10. Algunas herramientas emiten mayúsculas, otras minúsculas y otras permiten ambas. Si un resumen está en minúsculas y otro en mayúsculas, son el mismo resumen. Los espacios en blanco en la visualización del resumen son puramente cosméticos. Un resumen mostrado como ba78 16bf versus ba7816bf es el mismo; el espacio es sólo una elección de formato. Las discrepancias causadas por mayúsculas y minúsculas o espacios en blanco no son discrepancias reales.
Las diferencias de formato de ancho fijo también son invisibles a nivel de bytes. Un resumen que se muestra con guiones, espacios o dos puntos (como ba-78-16-bf) es una convención de formato que facilita la lectura para los humanos, no un cambio en los bytes reales. La herramienta ToolAcre siempre emite minúsculas sin separadores, que es el formato que imprimen la mayoría de las herramientas de línea de comandos. Si está comparando con una herramienta que emite de manera diferente, primero conviértala a la misma representación.
Lo que esto no cubre: archivos hash, donde se aplican los mismos principios pero los bytes provienen del disco en lugar de un campo de texto.
La calculadora de hash SHA ToolAcre realiza la conversión UTF-8 antes del hash, muestra el recuento de bytes de entrada y ofrece formatos de salida base64 y hexadecimal. El archivo fuente apps/dev/src/lib/hash.js muestra la función hashText que llama a digestBytes, que pasa bytes.slice().buffer a crypto.subtle.digest. Los comentarios en ese archivo documentan explícitamente que el paso UTF-8 es intencional y señalan la diferencia entre diferentes codificaciones. Al probar su entrada con el vector conocido (hashes abc a ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad en hexadecimal) se establece que la herramienta del navegador está funcionando correctamente; cualquier desviación apunta a una diferencia de bytes en la entrada.
El hash de archivos sigue el mismo principio. Los bytes del archivo son lo que importan: una diferencia en el final de línea cuando exporta desde un sistema e importa a otro puede cambiar cada resumen. Algunas herramientas ofrecen opciones para manejar los finales de línea durante la comparación; otros codifican el archivo tal cual. Saber si su herramienta codifica el archivo como binario o realiza primero la normalización del texto es esencial para la reproducibilidad.
Conclusión: bytes hash, no texto: la calculadora hash SHA de ToolAcre procesa los bytes que pega, así que verifique lo que pegó primero
La comparación y verificación funcionan solo cuando aplicas hash a los mismos bytes. Comience confirmando que está aplicando hash exactamente la misma entrada: ejecute echo -n (o printf) en lugar de echo para evitar la nueva línea, especifique la codificación UTF-8 explícitamente si su herramienta lo permite, verifique que CRLF no haya sido insertado por un editor o utilidad del sistema. Luego, haga un hash con la calculadora ToolAcre y la herramienta de línea de comandos, uno al lado del otro. Si los resúmenes coinciden, los bytes eran idénticos. Si no es así, utilice la visualización del recuento de bytes y el método de volcado hexadecimal para encontrar la diferencia oculta.
Una vez que comprenda dónde divergieron los bytes, puede elegir si desea normalizarlos para compararlos. Algunas sumas de verificación están destinadas a verificar la integridad del archivo exactamente como existe en el disco, en cuyo caso el objetivo es el hash byte por byte. Otros están destinados a verificar que el contenido visible sea el mismo, en cuyo caso la normalización de los finales de línea y la codificación es correcta. Ninguno de los dos está mal; Responden diferentes preguntas. El algoritmo SHA-256 siempre tiene razón; la única pregunta es si le está pidiendo que haga un hash de la misma entrada en ambos casos.