質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

311閲覧

[golang] flate.NewWriterDict で辞書を使った圧縮の挙動が予期しないものになる

smith_30

総合スコア26

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2018/01/24 02:52

編集2018/01/24 02:53

タイトルの通りなのですが
下記コードを実行したときの挙動が予想しているものと違うので
何が間違っているかの切り分けを助言していただけると助かります。

問題

1回目のflate処理は

compressed_1 : []byte{0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x7, 0x0}

であっているのに対して、二回目が

compressed_2 : []byte{0x2, 0x13, 0x0, 0x0}

となってしまい、辞書を使った圧縮後の予想としては

compressed_2 : []byte{0xf2, 0x0, 0x11, 0x0, 0x0}

です。

予想の根拠は下記からしています
https://tools.ietf.org/html/rfc7692#section-7.2.3.2

pythonの他の実装では上記の正しい結果で圧縮されることは確認しています
https://github.com/aaugustin/websockets

実行コード

go

1package flate_dict 2 3import ( 4 "bytes" 5 "compress/flate" 6 "fmt" 7) 8 9func compressWithDict(level int) { 10 11 // compress 12 src := []byte("Hello") 13 14 // fmt.Printf("src : %#v\n", src) 15 compressed := &bytes.Buffer{} 16 compressor, _ := flate.NewWriter(compressed, level) 17 compressor.Write(src) 18 compressor.Flush() 19 compressor.Close() 20 21 dict := compressed.Bytes() 22 // fmt.Printf("compressed : %#v\n", dict) 23 dict = dict[:len(dict)-9] 24 // compress([]byte("Hello"), compressed, flate.BestCompression) 25 fmt.Printf("compressed_1 : %#v\n", dict) 26 27 // compress 28 dct := []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f} 29 src_2 := []byte("Hello") 30 31 compressed_2 := &bytes.Buffer{} 32 compressor_2, _ := flate.NewWriterDict(compressed_2, level, dct) 33 compressor_2.Write(src_2) 34 compressor_2.Flush() 35 compressor_2.Close() 36 37 dict_2 := compressed_2.Bytes() 38 dict_2 = dict_2[:len(dict_2)-9] 39 40 fmt.Printf("compressed_2 : %#v\n\n", dict_2) 41}

debug用テストコード

go

1package flate_dict 2 3import "testing" 4 5func Test_compressWithDict(t *testing.T) { 6 tests := []struct { 7 name string 8 level int 9 }{ 10 { 11 name: "01", 12 level: -2, 13 }, 14 { 15 name: "02", 16 level: -1, 17 }, 18 { 19 name: "03", 20 level: 0, 21 }, 22 { 23 name: "04", 24 level: 1, 25 }, 26 { 27 name: "05", 28 level: 2, 29 }, 30 { 31 name: "06", 32 level: 3, 33 }, 34 { 35 name: "07", 36 level: 4, 37 }, 38 { 39 name: "08", 40 level: 5, 41 }, 42 { 43 name: "09", 44 level: 6, 45 }, 46 { 47 name: "10", 48 level: 7, 49 }, 50 { 51 name: "11", 52 level: 8, 53 }, 54 { 55 name: "12", 56 level: 9, 57 }, 58 } 59 for _, tt := range tests { 60 t.Run(tt.name, func(t *testing.T) { 61 compressWithDict(tt.level) 62 }) 63 } 64} 65

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

私の仕様理解不足だったようで
一般に圧縮実装は同一出力を保証しているわけではないそうです。

要は、今回は可逆圧縮ができればよいということ。

それは@mattnさんが補足してくださったようにstack over flowで回答いただきました。
https://stackoverflow.com/questions/48414288/the-compression-using-flate-newwriterdict-is-strange

投稿2018/01/25 03:23

smith_30

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問