Sto cercando un algoritmo di checksum in cui per un grande blocco di dati il checksum è uguale alla somma dei checksum di tutti i blocchi di componenti più piccoli. La maggior parte di ciò che ho trovato proviene da RFC 1624/1141 che forniscono questa funzionalità. Qualcuno ha qualche esperienza con queste tecniche di checksum o simili?Checksum incrementali
risposta
Ho utilizzato solo i checksum Adler/Fletcher che funzionano come descritto.
C'è un bel confronto di implementazioni di hash/checksum di crypto ++ here.
Ho provato a giocare con Adler e non riesco a ottenere il risultato atteso, intendi: 'adler ('wiki') + adler ('pedia')' dovrebbe produrre lo stesso digest di 'adler ('wikipedia')', o mi manca qualcosa? –
Per rispondere alla domanda di generosità di Amigable Clark Kent, per scopi di identificazione dei file probabilmente si desidera una funzione di hash crittografica, che cerca di garantire che qualsiasi due file dati abbia una probabilità estremamente bassa di produrre lo stesso valore, al contrario di un checksum che viene generalmente utilizzato solo per il rilevamento degli errori e può fornire lo stesso valore per due file molto diversi.
Molte funzioni hash crittografiche, quali MD5 e SHA-1, utilizzare il Merkle–Damgård construction, in cui v'è un calcolo per comprimere un blocco di dati in una dimensione fissa, e quindi combinare che con un valore di dimensione fissa dal blocco precedente (o un vettore di inizializzazione per il primo blocco). Pertanto, sono in grado di lavorare in una modalità di streaming, calcolando in modo incrementale mentre procedono.
Se si tratta solo di combinare rapidamente i checksum dei blocchi più piccoli per ottenere i checksum del messaggio più grande (non necessariamente con una semplice sommatoria), è possibile farlo con un algoritmo di tipo CRC (o simile).
L'algoritmo CRC-32 è semplice come questo:
uint32_t update(uint32_t state, unsigned bit)
{
if (((state >> 31)^bit) & 1) state = (state << 1)^0x04C11DB7;
else state = (state << 1);
return state;
}
Matematicamente, lo stato rappresenta un polinomio di sopra del GF2 campo che viene sempre ridotta modulo il polinomio generatore. Dato un nuovo bit b
lo stato precedente viene trasformato nel nuovo stato simili
state --> (state * x^1 + b * x^32) mod G
dove G è il polinomio generatore e l'aggiunta viene effettuata in GF2 (XOR). Questo checksum è lineare, nel senso che si può scrivere il messaggio M
come una somma (XOR) di messaggi di A, B, C, ... come questo
10110010 00000000 00000000 = A = a 00000000 00000000
00000000 10010001 00000000 = B = 00000000 b 00000000
00000000 00000000 11000101 = C = 00000000 00000000 c
-------------------------------------------------------------
= 10110010 10010001 11000101 = M = a b c
con le seguenti proprietà
M = A + B + C
checksum(M) = checksum(A) + checksum(B) + checksum(C)
Anche in questo caso, intendo lo +
in GF2 che è possibile implementare con uno XOR binario.
Infine, è possibile calcolare checksum(B)
basato su checksum(b)
e la posizione del sottoblocco b
rispetto al B
. La parte semplice sta conducendo zeri. Gli zeri iniziali non influenzano affatto il checksum. Quindi checksum(0000xxxx)
è lo stesso di checksum(xxxx)
. Se vuoi calcolare il checksum di un messaggio con zero zeri (a destra -> ultimi zero) dato il checksum del messaggio non inserito, è un po 'più complicato.Ma non è così complicato:
zero_pad(old_check_sum, number_of_zeros)
:= (old_check_sum * x^{number_of_zeros} ) mod G
= (old_check_sum * (x^{number_of_zeros} mod G)) mod G
Quindi, ottenere il checksum di un messaggio zeri è solo una questione di moltiplicare il "checksum polinomiale" del messaggio non imbottita con qualche altro polinomio (x^{number_of_zeros} mod G
) che dipende solo sul numero di zeri che si desidera aggiungere. Puoi precomputerlo in una tabella o usare l'algoritmo square-and-multiply per calcolare rapidamente questo potere.
Lettura consigliata: Painless Guide to CRC Error Detection Algorithms
- 1. Algoritmi di grafi incrementali
- 2. Elenchi annidati incrementali in rmarkdown
- 3. checksum ReactJS non valido
- 4. Calcolo del checksum NMEA
- 5. Rails inizializzazione checksum error
- 6. Maven checksum failed
- 7. Generazione di checksum Luhn
- 8. Liquibase - disabilita il checksum?
- 9. Come calcolare il checksum
- 10. Checksum sulla stringa
- 11. Come specificare ID incrementali legacy con Java
- 12. Script per eseguire backup incrementali con rsync
- 13. Coda di priorità rapida con aggiornamenti incrementali
- 14. scritture incrementali in hdf5 con h5py
- 15. EC2 Istantanee EBS come backup incrementali
- 16. checksum in rotazione nell'algoritmo rsync
- 17. Checksum e XOR in Swift
- 18. Socket Java: checksum TCP errato
- 19. checksum errata per oggetto liberato
- 20. Subversion: mismatch checksum di base
- 21. Git svn rebase: checksum mismatch
- 22. Come calcolare il checksum TCP
- 23. Come trovare un checksum con lo stesso checksum? (domanda di colloquio di lavoro)
- 24. Come convalido il checksum ICMPv6? (Perché continuo a ricevere un checksum di 0x3fff?)
- 25. maven: "Convalida checksum non riuscita, nessun checksum disponibile dal repository", perché?
- 26. Come calcolare manualmente CheckSum in Fix?
- 27. Come calcolare sha256 checksum file in Go
- 28. Bash: parallelizzare md5sum checksum su molti file
- 29. Calcola un checksum su iPhone da NSData
- 30. checksum CRC utilizzando long (64 bit)
Ha bisogno di essere specifico pari alla somma aritmetica dei checksum dei blocchi più piccoli, o avete semplicemente più in generale vuole essere in grado di calcolare il checksum del grande blocco dalla checksum dei blocchi più piccoli? –
A mio parere, il problema del checksum è oggi considerato "per lo più risolto" e spesso liquidato come "vincolato all'IO" e quindi non interessante dal punto di vista delle prestazioni algoritmiche. Ma OK, "IO legato" è, cosa possiamo fare per IO? Bene, se potessimo calcolare gli hash mentre IO è ancora caldo nelle cache, sarebbe bello. –
@Amigable Clark Kent Forse sarebbe stato meglio aprire una nuova domanda, con i tuoi esatti requisiti, invece di fare da spalla a spalla di una risposta esistente. Stai solo cercando un checksum per rilevare gli errori? Stai cercando una funzione hash crittografica? È necessario che il checksum sia composto da una combinazione dei checksum di ciascun blocco, come richiesto dalla domanda originale, oppure è solo necessario che si possa calcolare il checksum in modo incrementale su un flusso di dati e fornire una somma di controllo per l'intero flusso una volta hai finito? –