Go には標準zipファイルを扱うパッケージ archive/zip がありますが、パスワード付きzipファイルを作成する機能はありません1。
そこで、パスワード付きの zip を作成する機能が追加されたフォークパッケージ yeka/zip を使います。
パスワード付き zip ファイルの作成
テキストファイル sample.txt
をパスワード long-long-password
を設定した zip ファイルを作成するサンプルコード。
package main
import (
"bytes"
"os"
"github.com/yeka/zip"
)
func createZipBuffer() (*bytes.Buffer, error) {
filename := "sample.txt"
content := "ファイル内容"
password := "long-long-password"
buf := new(bytes.Buffer)
w := zip.NewWriter(buf)
// Create の代わりに Encrypt を使う
f, err := w.Encrypt(filename, password, zip.AES256Encryption)
if err != nil {
return nil, err
}
_, err = f.Write([]byte(content))
if err != nil {
return nil, err
}
err = w.Close()
if err != nil {
return nil, err
}
return buf, nil
}
func main() {
filename := "password.zip"
f, err := os.Create(filename)
if err != nil {
panic(err)
}
defer f.Close()
buf, err := createZipBuffer()
if err != nil {
panic(err)
}
if _, err := f.Write(buf.Bytes()); err != nil {
panic(err)
}
}
パスワード付き zip ファイルの読み込み
上記サンプルで作成したパスワード付き zip ファイルを読み込むサンプルコード。
package main
import (
"bytes"
"io"
"io/ioutil"
"os"
"github.com/yeka/zip"
)
func readZipBuffer(buf *bytes.Reader) error {
password := "long-long-password"
zipr, err := zip.NewReader(buf, int64(buf.Len()))
if err != nil {
return err
}
for _, z := range zipr.File {
z.SetPassword(password) // 解凍するためのパスワードを設定する
rc, err := z.Open()
if err != nil {
return err
}
if _, err := io.Copy(os.Stdout, rc); err != nil {
return err
}
rc.Close()
}
return nil
}
func main() {
filename := "password.zip"
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
if err := readZipBuffer(bytes.NewReader(b)); err != nil {
panic(err)
}
}