第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何在 Go 中解碼 zlib 流?

如何在 Go 中解碼 zlib 流?

Go
慕容森 2022-10-24 09:39:32
問題是什么?我無法使用 go 的zlib包從 zlib 流中解碼有效的壓縮塊。我準(zhǔn)備了一個(gè) github 存儲(chǔ)庫,其中包含說明我遇到的問題的代碼和數(shù)據(jù):https ://github.com/andreyst/zlib-issue 。那些塊是什么?它們是由文本游戲服務(wù)器 (MUD) 生成的消息。該游戲服務(wù)器以多個(gè)塊發(fā)送壓縮的消息流,其中第一個(gè)包含 zlib 標(biāo)頭,其他不包含。我使用名為“mcclient”的代理捕獲了兩個(gè)塊(第一個(gè)和第二個(gè)),它是一個(gè)邊車,為不支持壓縮的 MUD 客戶端提供壓縮。它是用 C 語言編寫的,并使用 Czlib庫來解碼壓縮塊。塊包含在“塊”目錄中,并以數(shù)字0和1. *.in文件包含壓縮數(shù)據(jù)。*.out包含從 mcclient 捕獲的未壓縮數(shù)據(jù)。*.log包含 zlib 解壓的狀態(tài)(inflate調(diào)用的返回碼)。一個(gè)特殊的all.in塊是與塊0連接的塊1。為什么我認(rèn)為它們是有效的?mcclient使用 C 成功解壓縮輸入塊,zlib沒有任何問題。*.logstatus 顯示0這意味著 Z_OK 這意味著 zlib 用語中沒有錯(cuò)誤。zlib-flate -uncompress < chunks/all.in在 Linux 下可以正常工作并解壓縮為相同的內(nèi)容。在 Mac OS 下,它也解壓縮到相同的內(nèi)容,但帶有警告zlib-flate: WARNING: zlib code -5, msg = input stream is complete but output may still be valid——這看起來與預(yù)期的一樣,因?yàn)閴K不包含“官方”流結(jié)束。中的 Python 代碼decompress.py可以正確解壓縮all.in和0/1塊,沒有任何問題。go的zlib有什么問題?看main.go——它嘗試解壓縮這些塊,從開始然后all.in嘗試逐步解壓縮塊。01嘗試 decode all.in( func all()) 有點(diǎn)成功,至少解壓后的數(shù)據(jù)是一樣的,但是 zlib reader 返回 error flate: corrupt input before offset 446。在嘗試逐塊解壓縮塊的實(shí)際場景(func stream())時(shí),zlib 讀取器使用預(yù)期數(shù)據(jù)解碼第一個(gè)塊,但返回錯(cuò)誤flate: corrupt input before offset 32,隨后嘗試解碼塊1完全失敗。問題zlib是否可以在適合這種場景的某種“流”模式下使用 go 的包?也許我使用不正確?如果沒有,解決方法是什么?同樣有趣的是,為什么會(huì)這樣——這是設(shè)計(jì)使然嗎?只是還沒有實(shí)施嗎?我錯(cuò)過了什么?
查看完整描述

2 回答

?
江戶川亂折騰

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超5個(gè)贊

請注意,錯(cuò)誤表示輸入后偏移處的數(shù)據(jù)已損壞。那是因?yàn)槟鷱奈募凶x取的方式:


    buf := make([]byte, 100000)

    n, readErr := f.Read(buf)

    if readErr != nil {

        log.Fatalf("readErr=%v\n", readErr)

    }

    fmt.Printf("Read bytes, n=%v\n", n)


    buffer := bytes.NewBuffer(buf)

    zlibReader, zlibErr := zlib.NewReader(buffer)

    if zlibErr != nil {

        log.Fatalf("zlibErr=%v\n", zlibErr)

    }

buf := make([]byte, 100000)將制作一個(gè) 100000 字節(jié)的切片,全部為 0。但在all.in. 由于您從不縮短切片,因此閱讀器將在有效數(shù)據(jù)之后遇到幾千個(gè)零并斷定它已損壞。這就是你得到輸出和錯(cuò)誤的原因。


至于流媒體。在 TCP/UDP 連接的情況下,您應(yīng)該能夠?qū)?a 連接傳遞io.Reader給zlib.NewReader. 為了模擬相同的內(nèi)容,我在修改后的代碼中使用了io.Pipe:


package main


import (

    "bytes"

    "compress/zlib"

    "fmt"

    "io"

    "log"

    "os"


    otherzlib "github.com/4kills/go-zlib"

)


func main() {

    all()

    stream()


    // Alas it hangs :(

    // otherZlib()

}


func all() {

    fmt.Println("==== RUNNING DECOMPRESSION OF all.in")

    fmt.Println("")


    buf, readErr := os.ReadFile("./chunks/all.in")

    if readErr != nil {

        log.Fatalf("readErr=%v\n", readErr)

    }

    fmt.Printf("Read bytes, n=%v\n", len(buf))


    buffer := bytes.NewBuffer(buf)

    zlibReader, zlibErr := zlib.NewReader(buffer)

    if zlibErr != nil {

        log.Fatalf("zlibErr=%v\n", zlibErr)

    }


    out := new(bytes.Buffer)

    written, copyErr := io.Copy(out, zlibReader)

    if copyErr != nil {

        log.Printf("copyErr=%v\n", copyErr)

    }

    fmt.Printf("Written bytes, n=%v, out:\n%v\n", written, out.String())

    fmt.Println("")

}


func stream() {

    fmt.Println("==== RUNNING DECOMPRESSION OF SEPARATE CHUNKS")

    fmt.Println("")


    pRead, pWrite := io.Pipe()

    go func() {

        buf, readErr := os.ReadFile("./chunks/0.in")

        if readErr != nil {

            log.Fatalf("readErr=%v\n", readErr)

        }

        fmt.Printf("Read 0 bytes, n=%v\n", len(buf))


        written0, copy0Err := io.Copy(pWrite, bytes.NewBuffer(buf))

        if copy0Err != nil {

            log.Printf("copy0Err=%v\n", copy0Err)

        }

        fmt.Printf("Written compressed bytes, n0=%v", written0)


        buf, readErr = os.ReadFile("./chunks/1.in")

        if readErr != nil {

            log.Fatalf("read1Err=%v\n", readErr)

        }

        fmt.Printf("Read 1 bytes, n=%v\n", len(buf))


        written1, copy1Err := io.Copy(pWrite, bytes.NewBuffer(buf))

        if copy1Err != nil {

            log.Printf("copy1Err=%v\n", copy1Err)

        }

        fmt.Printf("Written compressed bytes, n1=%v", written1)


        pWrite.Close()

    }()


    zlibReader, zlibErr := zlib.NewReader(pRead)

    if zlibErr != nil {

        log.Fatalf("zlibErr=%v\n", zlibErr)

    }


    out := new(bytes.Buffer)

    written2, copy2Err := io.Copy(out, zlibReader)

    if copy2Err != nil {

        log.Printf("copy2Err=%v\n", copy2Err)

    }

    fmt.Printf("Written decompressed bytes, n0=%v, out:\n%v\n", written2, out.String())


    fmt.Println("")

}

使用此代碼,我沒有收到任何錯(cuò)誤,stream()但我仍然收到copyErr=unexpected EOF錯(cuò)誤all(),看起來最后all.in缺少校驗(yàn)和數(shù)據(jù),但我認(rèn)為這只是一個(gè)意外。


查看完整回答
反對 回復(fù) 2022-10-24
?
白豬掌柜的

TA貢獻(xiàn)1893條經(jīng)驗(yàn) 獲得超10個(gè)贊

通過仔細(xì)調(diào)試,我能夠看到我錯(cuò)誤地傳遞了太大的緩沖區(qū)切片,這導(dǎo)致不正確的輸入緩沖區(qū)被饋送到解壓縮。

此外,重要的是不要使用io.Copy,這會(huì)導(dǎo)致緩沖區(qū)上的 EOF 停止一切,而是只使用 zlibReader.Read(),這將解壓縮當(dāng)前在緩沖區(qū)中的所有內(nèi)容。

我已經(jīng)更新了代碼,所以它現(xiàn)在可以按預(yù)期工作。


查看完整回答
反對 回復(fù) 2022-10-24
  • 2 回答
  • 0 關(guān)注
  • 285 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號