Strumenti per sviluppatori · SHA calcolatore hash
Byte esadecimali, Base64 e grezzi: tre modi per scrivere lo stesso SHA Digest
· Come funziona
sha-256 base64 codifica formati di file
sha256sum stampa esadecimale, package-lock.json memorizza base64 e Docker utilizza un prefisso sha256:. Possono essere tutti uguali 32 bytes. Questo post spiega ciascuna rappresentazione e come convertirla tra di loro.
Gli hash che sembrano diversi ma concordano: una stringa del file di blocco e un checksum del terminale per lo stesso file
Un digest SHA-256 è fondamentalmente 32 bytes. Il modo in cui scrivi quei byte determina l'aspetto del digest. Un digest, 32 byte identici, viene visualizzato come caratteri esadecimali 64 (due per byte) o caratteri 44 base64 (circa quattro per tre byte) o lunghezze e formati diversi a seconda della codifica. La confusione nasce perché un file di lock potrebbe mostrare una rappresentazione e un terminale ne mostra un'altra, entrambi per lo stesso 32 bytes sottostante.
Comprendere la codifica è il passo che trasforma "perché questi sembrano diversi?" in "Posso confermare che sono la stessa cosa". Tutte e tre le rappresentazioni sono equivalenti una volta decodificate in byte.
Un digest è composto da byte: 20, 32, 48 o 64 a seconda dell'algoritmo, prima di qualsiasi codifica del testo
Prima che esista qualsiasi rappresentazione testuale, il risultato è un ArrayBuffer di byte digest. ToolAcre avvolge il buffer con Uint8Array, quindi scrive ogni byte come due cifre esadecimali o converte ogni byte in un carattere binario prima di chiamare btoa. Nessuno dei due formattatori riesegue l'hash e nessuno dei due modifica un singolo bit digest.
La larghezza del byte segue l'algoritmo selezionato in questo strumento: SHA-1 restituisce venti byte, SHA-256 trentadue, SHA-384 quarantotto e SHA-512 sessantaquattro. Questi sono gli output supportati verificati dai metadati e dai test dell'algoritmo. I byte non elaborati sono appropriati per il confronto a livello di codice; hex e base64 sono notazioni di trasporto per i canali che prevedono testo.
Hex: due caratteri per byte, perché domina gli strumenti da riga di comando e la questione del caso
La rappresentazione esadecimale utilizza le cifre 0-9 e le lettere A-F (o a-f) per rappresentare i possibili valori 16 di un bocconcino 4 bit. Due cifre esadecimali rappresentano un byte. Il digest SHA-256 dell'abc di input è 32 bytes, quindi viene visualizzato come caratteri esadecimali 64: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad. Questo è il formato stampato dalla maggior parte degli strumenti da riga di comando. L'esadecimale è leggibile dall'uomo e non ambiguo; ogni byte è rappresentato ogni volta esattamente dagli stessi due caratteri.
L'esadecimale è il formato predefinito per checksum e hash nella documentazione e nella riga di comando. È facile da leggere e copiare e non c'è riempimento, nessuna distinzione tra maiuscole e minuscole nell'interpretazione (sebbene la convenzione imponga sempre minuscole o maiuscole) e nessun carattere speciale che richieda l'escape negli URL o JSON. Lo svantaggio è che richiede il doppio dei caratteri rispetto ai byte grezzi, motivo per cui esistono altri formati.
Base64 e base64url: circa quattro caratteri per tre byte, riempimento e dove appare ciascuno (SRI, npm, SSH impronte digitali)
Base64 codifica tre byte come quattro caratteri estratti da un alfabeto di caratteri 64: A-Z, a-z, 0-9, +, /. I tre byte 61 62 63 (il I codici ASCII per abc) codificano come YWJj in base64. Un digest 32-byte completo SHA-256 codifica come circa 44 caratteri base64. Il riempimento con = caratteri porta la lunghezza dell'output a un multiplo di 4, quindi 44 caratteri più 0 riempimento (poiché 32 è un multiplo di 3, non è necessario alcun riempimento). La decodifica inverte il processo: quattro caratteri base64 vengono decodificati in tre byte.
Base64 viene visualizzato nei file package-lock.json, nel wrapper npm, negli attributi SRI (integrità della risorsa secondaria) in HTML e nelle impronte digitali delle chiavi SSH. È compatto: circa il 33% più lungo dei byte grezzi, rispetto al 100% più lungo del formato esadecimale. Il compromesso è che non tutte le rappresentazioni testuali sono ugualmente facili da leggere; base64 sembra più criptato ad un occhio umano che esadecimale.
Forme con prefisso: sha256: nei digest del contenitore, sha384- negli attributi di integrità, SHA256: in SSH
Base64url è una variante definita in RFC 4648 che sostituisce - e _ per + e /. L'alfabeto diventa A-Z, a-z, 0-9, -, _. I JWT utilizzano base64url perché + e / hanno significati speciali negli URL (+ può essere letto come uno spazio nelle stringhe di query, / è un separatore di percorso). Un segmento JWT è sempre codificato in base64url e un decodificatore che insiste sullo standard base64 lo rifiuterà. Al contrario, un decodificatore base64url che non accetta l'alfabeto standard fallirà su base64 standard.
L'imbottitura è facoltativa in base64url. Pad base64 standard con = per garantire che la lunghezza dell'output sia un multiplo di 4. Base64url omette comunemente il riempimento perché = è esso stesso URL-imbarazzante. Un decodificatore dovrebbe accettare base64url con o senza riempimento e il codificatore dovrebbe essere esplicito su ciò che produce. Lo strumento ToolAcre base64 accetta entrambi gli alfabeti e tollera il riempimento mancante nell'input e consente di scegliere il formato nell'output.
Esempio funzionante: un digest convertito da esadecimale a base64 e viceversa, con i limiti dei byte contrassegnati
I moduli con prefisso aggiungono un identificatore di schema al digest. I digest di immagini Docker utilizzano sha256:ba7816bf..., dove sha256: è il prefisso. Le impronte digitali SSH utilizzano SHA256:, con i due punti. Alcuni strumenti utilizzano sha256= o SHA256= (con un segno di uguale). Il prefisso è puramente informativo; ti dice quale algoritmo ha prodotto il digest. La rimozione del prefisso lascia gli stessi byte nella stessa codifica.
Quando si confrontano i digest, il prefisso è rumore. Se uno strumento stampa SHA256:ba78... e un altro stampa ba78..., sono lo stesso digest; il prefisso è solo metadati sul formato. Allo stesso modo, prefissi come sha256:- (utilizzato in alcuni contesti contenitori) o sha384- (utilizzato negli attributi di integrità) sono convenzioni di formattazione che non modificano i byte. Spogliateli per fare un confronto.
Cosa non copre: quale codifica emette un determinato strumento; controllare il formato di output prima del confronto
Un digest, SHA-256 dell'input abc, viene visualizzato in più forme: esadecimale (64 caratteri), base64 con riempimento (44 caratteri), base64url con riempimento (44 caratteri, con - e _ invece di + e /), o con vari prefissi. Per confermare che sono uguali, decodifica ciascuno in byte e confronta i byte. La rappresentazione esadecimale ba7816bf... decodifica in byte 0xba 0x78 0x16 0xbf 0x8f 0x01 0xcf 0xea ... La rappresentazione base64 si converte nella stessa sequenza di byte quando decodificata.
Per impostazione predefinita, il calcolatore hash ToolAcre SHA restituisce in formato esadecimale. Se hai bisogno di base64, puoi utilizzare uno strumento separato per convertire l'esadecimale in base64 oppure utilizzare l'utilità base64 sullo stesso sito per codificare direttamente il testo. Strumenti progettati per contesti specifici (npm per package-lock.json, Docker per digest di immagini) restituiscono l'output nel formato previsto dal contesto. Comprendere che questi sono tutti uguali 32 bytes in abiti diversi elimina la confusione quando gli strumenti non sono d'accordo sul formato.
Conclusione: confronta byte, non stringhe: calcola il digest con il calcolatore hash ToolAcre SHA, quindi convertilo nella rappresentazione con cui stai confrontando
Per convertire manualmente un digest esadecimale in base64, raggruppa le cifre esadecimali in byte, converti ciascun byte in decimale, quindi codifica utilizzando l'alfabeto base64. Il byte 0xba (hex ba) è decimale 186; 0x78 è 120; 0x16 è 22; 0xbf è 191. Raggruppando questi quattro byte e codificandoli come base64 si ottengono i caratteri w (0 + 22 nell'alfabeto), as (codifica 186), AA (codifica 120), vw (codifica 191). Il digest completo richiede di eseguire questa operazione 10 volte e di riempire se necessario. Questo processo manuale è istruttivo ma noioso; uno strumento di conversione base64 lo rende istantaneo.
L'intuizione chiave è che un digest è composto innanzitutto da byte e la rappresentazione del testo è secondaria. Ogni codifica degli stessi byte viene decodificata negli stessi byte e quindi è intercambiabile ai fini della verifica dell'integrità. Le differenze tra maiuscole e minuscole in esadecimale, le differenze di riempimento in base64, i prefissi e la spaziatura sono tutte scelte di formattazione che non influiscono sul valore effettivo. Quando padroneggi la capacità di convertire tra rappresentazioni, le discrepanze del formato digest diventano problemi di debug che puoi risolvere invece che misteri.