сумма sha256 не соответствует выводу команды gzip - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь вычислить сумму sha256 gzipped-файла в Go, но мой вывод не совпадает с выводом команды gzip.

У меня есть функция Compress, которая распаковывает содержимоеio.Reader, файл в моем случае.

func Compress(r io.Reader) (io.Reader, error) {
    var buf bytes.Buffer
    zw := gzip.NewWriter(&buf)
    if _, err := io.Copy(zw, r); err != nil {
        return nil, err
    }
    if err := zw.Close(); err != nil {
        return nil, err
    }
    return &buf, nil
}

Тогда у меня есть функция Sum256, которая вычисляет сумму читателя sha256.

func Sum256(r io.Reader) (sum []byte, err error) {
    h := sha256.New()
    if _, err := io.Copy(h, r); err != nil {
        return nil, err
    }
    return h.Sum(nil), nil
}

Моя основная функция открываетсяфайл, распаковывает его, затем вычисляет сумму архива sha256 из сжатого содержимого.Проблема в том, что выходные данные не совпадают с выходными данными команды gzip.Входной файл hello.txt содержит одну строку со словом hello без новой строки в конце.

func main() {
    uncompressed, err := os.Open("hello.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer uncompressed.Close()

    sum, err := Sum256(uncompressed)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%x  %s\n", sum, uncompressed.Name())

    uncompressed.Seek(0, 0)
    compressed, err := Compress(uncompressed)
    if err != nil {
        log.Fatal(err)
    }

    sum, err = Sum256(compressed)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%x  %s.gz\n", sum, uncompressed.Name())
}

gzip results:

$ sha256sum hello.txt
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  hello.txt

$ gzip -c hello.txt | sha256sum
809d7f11e97291d06189e82ca09a1a0a4a66a3c85a24ac7ff389ae6fbe02bcce  -

$ gzip -nc hello.txt | sha256sum
f901eda57fd86d4239806fd4b76f64036c1c20711267a7bc776ab2aa45069b2a  -

Результаты моей программы:

$ go run main.go
# match
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  hello.txt
# mismatch
3429ae8bc6346f1e4fb67b7d788f85f4637e726a725cf4b66c521903d0ab3b07  hello.txt.gz

Есть идеи, почему выходы не совпадают или как это исправить?Я попытался использовать файл io.Pipe, ioutil.TempFile и другие методы с той же проблемой.

1 Ответ

0 голосов
/ 15 декабря 2018

В частности, обратите внимание, что если вы запустите команду:

gzip -c hello.txt

Вывод будет содержать имя файла hello.txt.Это можно увидеть с помощью hexdump:

$ touch hello.txt; gzip -c hello.txt | hexdump -C
00000000  1f 8b 08 08 ad 1b 14 5c  00 03 68 65 6c 6c 6f 2e  |.......\..hello.|
00000010  74 78 74 00 03 00 00 00  00 00 00 00 00 00        |txt...........|
0000001e

Если вы просто скопируете данные в поток Gzip в вашей программе, имя файла там не будет.Таким образом, вы должны получить другие результаты, а сумма SHA-256 должна отличаться.

Однако, даже если вы исправите этот конкретный дефект ... вы по-прежнемуне гарантируется получение одинаковых результатов при запуске Gzip для одного и того же файла.

Если вы хотите, чтобы контрольная сумма была такой же, запустите контрольную сумму для распакованных данных.

...