Stavo solo sperimentando con archive/tar e compress/gzip, per l'elaborazione automatizzata di alcuni backup che ho.Perché l'hash md5 della parte tar di un tar.gz tramite TeeReader è errato?
Il mio problema è: ho vari file .tar e file .tar.gz in giro, e quindi voglio estrarre l'hash (md5) del file .tar.gz e l'hash (md5) di anche il file .tar, idealmente in una corsa.
Il codice di esempio che ho finora funziona perfettamente per gli hash dei file in .tar.gz anche per .gz, ma l'hash per .tar è sbagliato e non riesco a scoprirlo qual è il problema
Ho guardato il file tar/reader.go e ho visto che ci sono alcuni salti, ma ho pensato che tutto dovrebbe essere eseguito sull'interfaccia io.Reader e quindi il TeeReader dovrebbe comunque catturare tutti i byte.
package main
import (
"archive/tar"
"compress/gzip"
"crypto/md5"
"fmt"
"io"
"os"
)
func main() {
tgz, _ := os.Open("tb.tar.gz")
gzMd5 := md5.New()
gz, _ := gzip.NewReader(io.TeeReader(tgz, gzMd5))
tarMd5 := md5.New()
tr := tar.NewReader(io.TeeReader(gz, tarMd5))
for {
fileMd5 := md5.New()
hdr, err := tr.Next()
if err == io.EOF {
break
}
io.Copy(fileMd5, tr)
fmt.Printf("%x %s\n", fileMd5.Sum(nil), hdr.Name)
}
fmt.Printf("%x tb.tar\n", tarMd5.Sum(nil))
fmt.Printf("%x tb.tar.gz\n", gzMd5.Sum(nil))
}
Ora per il seguente esempio:
$ echo "a" > a.txt
$ echo "b" > b.txt
$ tar cf tb.tar a.txt b.txt
$ gzip -c tb.tar > tb.tar.gz
$ md5sum a.txt b.txt tb.tar tb.tar.gz
60b725f10c9c85c70d97880dfe8191b3 a.txt
3b5d5c3712955042212316173ccf37be b.txt
501352dcd8fbd0b8e3e887f7dafd9392 tb.tar
90d6ba204493d8e54d3b3b155bb7f370 tb.tar.gz
Su Linux Mint 14 (basata su Ubuntu 12.04) con il passare 1.02 dal Ubuntu repository il risultato per il mio programma go è:
$ go run tarmd5.go
60b725f10c9c85c70d97880dfe8191b3 a.txt
3b5d5c3712955042212316173ccf37be b.txt
a26ddab1c324780ccb5199ef4dc38691 tb.tar
90d6ba204493d8e54d3b3b155bb7f370 tb.tar.gz
Quindi tutti gli hash tranne tb.tar sono come previsto. (Naturalmente se riprovi questo esempio, il tuo .tar e .tar.gz sarà diverso da questo, a causa di diversi timestamp)
Qualsiasi suggerimento su come farlo funzionare sarebbe molto apprezzato, io preferirei davvero averlo in 1 run però (con i TeeReader).