LoginSignup
5
3

More than 5 years have passed since last update.

Go でパスワードが設定された zip ファイルを作成する

Posted at

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)
    }
}

  1. github には対応要望の issue があるようです。 

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3