Português (Brasil)

Ferramentas para desenvolvedores · SHA calculadora de hash

Mesmo texto, diferente SHA-256: novas linhas, codificações e bytes ocultos

· Como funciona

sha-256 codificação processamento de texto depuração

Duas entradas de texto de aparência idêntica produzindo resumos SHA-256 diferentes, com nova linha oculta e bytes de codificação destacados
Ilustração vetorial original ToolAcre

A linha de comando diz uma coisa e o navegador diz outra para o que parece ser o mesmo texto. No final das novas linhas, UTF-16 e CRLF explicam quase todos os casos; esta postagem mostra como encontrar os bytes ocultos.

echo diz um hash, a ferramenta diz outro - a incompatibilidade cotidiana e por que nenhum deles está errado

Um terminal reporta um resumo SHA-256 e um navegador reporta outro para o que parece ser um texto idêntico. A ferramenta de linha de comando não quebrou e o navegador também não. Os bytes que estão sendo hash não são os mesmos, embora os caracteres visíveis pareçam idênticos. Esta postagem rastreia as fontes mais comuns desses bytes ocultos e mostra como encontrá-los com um campo de texto e um visualizador hexadecimal.

O problema quase nunca é o próprio algoritmo SHA-256. SHA-256 é determinístico: os mesmos bytes sempre produzem o mesmo resumo e o resumo está correto. Quando as saídas diferem, os bytes são diferentes. A confusão surge porque “o mesmo texto” é ambíguo: uma pessoa vê caracteres, mas uma função hash vê bytes, e a tradução entre eles é onde as diferenças ocultas se escondem.

A nova linha final - como echo anexa um byte e printf não, e o que isso faz com um resumo

O comando echo em um shell acrescenta um caractere de nova linha (U+000A, byte 0x0A) à sua saída. Isso ocorre por design: a convenção no Unix de que os arquivos de texto terminam com uma nova linha dá ao echo uma tarefa simples. Quando você digita echo abc em um terminal e canaliza-o para sha256sum, os bytes digeridos são 61 62 63 0A (o ASCII códigos para a, b, c e o byte para nova linha), não 61 62 63. A ferramenta ToolAcre usa para calcular hashes hashes os bytes 61 62 63 e produz um resultado diferente.

O comando printf não adiciona uma nova linha, a menos que você escreva uma na string de formato. imprimirf abc | sha256sum calcula o resumo de bytes 61 62 63 sozinho, que corresponde à ferramenta do navegador. É por isso que comparar hashes geralmente significa executar printf em vez de echo, ou canalizar para sha256sum com o sinalizador -z, ou especificar entrada bruta em qualquer formato que sua ferramenta forneça. A nova linha oculta é o motivo mais comum pelo qual uma ferramenta de navegador e uma ferramenta de linha de comando discordam.

UTF-8 versus UTF-16 — por que os mesmos caracteres são bytes diferentes em alguns shells e editores

UTF-8 e UTF-16 codificam os mesmos caracteres como sequências de bytes diferentes. O caractere é (U+00E9, um e com acento agudo) é codificado como dois bytes UTF-8: 0xC3 0xA9. Em UTF-16, que é como JavaScript representa strings internamente, o mesmo caractere ocupa dois bytes em uma ordem diferente (dependendo do endianness) ou em uma forma totalmente diferente se composto de um caractere base e uma marca de combinação. Quando você copia o café de um aplicativo do Windows e o cola em uma ferramenta de hash do navegador, os bytes que a ferramenta faz o hash podem não corresponder ao hash de um terminal Mac, porque os sistemas padronizam codificações ou formas de normalização diferentes.

A ferramenta de hash ToolAcre converte explicitamente o texto em UTF-8 antes do hash via TextEncoder. Esta é a mesma codificação que a linha de comando do Unix usa por padrão. O código fonte em apps/dev/src/lib/base64.js mostra a função textToBytes chamando new TextEncoder().encode(), o que garante UTF-8. Se outro sistema estiver usando UTF-16 ou Latin-1 ou qualquer outra codificação, os bytes produzidos serão diferentes. A ferramenta exibe a contagem de bytes junto com o resumo, e é por isso que colar café e comparar com um hash de linha de comando mostrará contagens de bytes diferentes se as codificações divergirem.

CRLF, BOM e normalização — finais de linha, marcas de ordem de bytes e acentos compostos versus decompostos como diferenças de entrada invisíveis

CRLF (retorno de carro + avanço de linha, bytes 0x0D 0x0A) é a convenção de final de linha no Windows; LF (line feed sozinho, byte 0x0A) é a convenção Unix. Um arquivo de texto que parece idêntico quando aberto em um editor de texto pode conter diferentes finais de linha, e esses bytes fazem parte da entrada do hash. Um arquivo editado no Windows e verificado em relação a um SHA-256 calculado em um sistema Unix não corresponderá se um sistema tiver convertido os finais de linha e o outro não.

A marca de ordem de bytes (BOM, bytes 0xEF 0xBB 0xBF para UTF-8) é uma sequência opcional no início de um arquivo que sinaliza a codificação. Alguns editores adicionam; algumas ferramentas o removem; alguns ignoram isso. Se um arquivo contém um BOM e você faz o hash byte por byte, os bytes BOM fazem parte do resumo. Se você copiar o texto visível (do qual um visualizador oculta o BOM) em uma ferramenta que não adiciona um BOM, os resumos não corresponderão. Os formulários de normalização de texto (NFD versus NFC para acentos compostos e decompostos) adicionam outra camada: a mesma letra acentuada pode ser representada como um único caractere pré-composto ou como um caractere base seguido por um acento combinado, e as sequências de bytes são diferentes.

Exemplo resolvido - uma string com hash com e sem nova linha, depois em duas codificações, com cada diferença de byte mostrada

Método de diagnóstico um: use uma ferramenta hexadecimal ou um conversor online para ver exatamente em quais bytes suas ferramentas estão operando. Cole o texto em um codificador base64, codifique-o e você terá um registro textual dos bytes. Em seguida, decodifique o base64 na linha de comando com base64 -d e canalize-o para od -A x -t x1z para ver a sequência de bytes hexadecimais. Se os bytes corresponderem, o algoritmo está correto; caso contrário, a diferença será visível.

Método de diagnóstico dois: use a calculadora de hash ToolAcre SHA para fazer hash de entradas progressivamente mais longas, começando com um único caractere. Adicione uma nova linha (o que significa digitar Enter dentro da caixa de texto), adicione espaços, adicione o mesmo texto com sequências de escape UTF-16 se a entrada vier de uma fonte não ASCII. Observe a mudança do resumo a cada adição. A contagem de bytes exibida ao lado do resumo informa quantos bytes a ferramenta está fazendo hash, o que restringe drasticamente a pesquisa.

Caixa hexadecimal e espaço em branco na saída – as diferenças que são puramente cosméticas

A representação hexadecimal de um resumo não diferencia maiúsculas de minúsculas. Letras maiúsculas e minúsculas representam os mesmos bytes: A = 10, a = 10. Algumas ferramentas emitem letras maiúsculas, outras minúsculas, outras permitem isso. Se um resumo estiver em letras minúsculas e outro em maiúsculas, eles serão o mesmo resumo. Os espaços em branco na exibição do resumo são puramente cosméticos. Um resumo exibido como ba78 16bf versus ba7816bf é o mesmo; o espaço é apenas uma escolha de formatação. As incompatibilidades causadas por maiúsculas e minúsculas ou espaços em branco não são incompatibilidades reais.

As diferenças de formatação de largura fixa também são invisíveis no nível de byte. Um resumo mostrado com hífens, espaços ou dois pontos (como ba-78-16-bf) é uma convenção de formatação que facilita a leitura humana, e não uma alteração nos bytes reais. A ferramenta ToolAcre sempre emite letras minúsculas sem separadores, que é o formato que a maioria das ferramentas de linha de comando imprime. Se você estiver comparando com uma ferramenta que emite de forma diferente, converta primeiro para a mesma representação.

O que isso não cobre - arquivos hash, onde os mesmos princípios se aplicam, mas os bytes vêm do disco e não de um campo de texto

A calculadora de hash ToolAcre SHA executa a conversão UTF-8 antes do hash, exibe a contagem de bytes de entrada e oferece formatos de saída base64 e hexadecimal. O arquivo de origem apps/dev/src/lib/hash.js mostra a função hashText chamando digestBytes, que passa bytes.slice().buffer para crypto.subtle.digest. Os comentários nesse arquivo documentam explicitamente que a etapa UTF-8 é intencional e observam a diferença entre as diferentes codificações. Testar sua entrada em relação ao vetor conhecido (hashes abc para ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad em hexadecimal) estabelece que a ferramenta do navegador está funcionando corretamente; qualquer desvio aponta para uma diferença de bytes na entrada.

O hash de arquivo segue o mesmo princípio. O que importa são os bytes no arquivo: uma diferença no final da linha quando você exporta de um sistema e importa para outro pode alterar cada resumo. Algumas ferramentas oferecem opções para lidar com finais de linha durante a comparação; outros fazem hash do arquivo como está. Saber se sua ferramenta faz o hash do arquivo como binário ou executa a normalização do texto primeiro é essencial para a reprodutibilidade.

Conclusão: hash bytes, não texto — a calculadora de hash ToolAcre SHA faz hash dos bytes que você cola, então verifique o que você colou primeiro

A comparação e a verificação funcionam apenas quando você faz hash dos mesmos bytes. Comece confirmando que você está fazendo hash exatamente da mesma entrada: execute echo -n (ou printf) em vez de echo para evitar a nova linha, especifique a codificação UTF-8 explicitamente se sua ferramenta permitir, verifique se CRLF não foi inserido por um editor ou utilitário do sistema. Em seguida, faça hash com a calculadora ToolAcre e a ferramenta de linha de comando lado a lado. Se os resumos corresponderem, os bytes eram idênticos. Caso contrário, use a exibição de contagem de bytes e o método hexadecimal para encontrar a diferença oculta.

Depois de entender onde os bytes divergiram, você poderá escolher se deseja normalizá-los para comparação. Algumas somas de verificação destinam-se a verificar a integridade do arquivo exatamente como ele existe no disco; nesse caso, o objetivo é o hashing byte por byte. Outros destinam-se a verificar se o conteúdo visível é o mesmo; nesse caso, a normalização dos finais de linha e da codificação está correta. Nenhum dos dois está errado; eles respondem a perguntas diferentes. O algoritmo SHA-256 está sempre certo; a questão é apenas se você está solicitando o hash da mesma entrada em ambos os casos.