2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

golangでパスワード付きzipファイルを展開する

Last updated at Posted at 2019-01-31
  • "1234"のパスワードのかかったzipファイルを引数に与えると実行ファイルと同じディレクトリに1ファイルを展開する。
package main

import (
        "bufio"
        "flag"
        "fmt"
        "github.com/yeka/zip"
        "io/ioutil"
        "log"
        "os"
        "path/filepath"
)

const password = "1234"

func readline() {
        stdin := bufio.NewScanner(os.Stdin)
        for stdin.Scan() {
                break
        }
}

func main() {
        // 実行ファイルディレクトリ取得
        exe, err := os.Executable()
        dirname := filepath.Dir(exe)
        fmt.Println(dirname)

        // 引数取得
        flag.Parse()
        args := flag.Args()
        fmt.Println(args)

        // zipファイルを開く
        r, err := zip.OpenReader(flag.Arg(0))
        if err != nil {
                log.Fatal(err)
        }
        defer r.Close()

        // zipファイルのリストをループ
        for _, f := range r.File {
                if f.IsEncrypted() {
                        f.SetPassword(password)
                }
                r, err := f.Open()
                if err != nil {
                        log.Fatal(err)
                }
                // ファイルの中身を読み込み
                buf, err := ioutil.ReadAll(r)
                if err != nil {
                        log.Fatal(err)
                }
                defer r.Close()
                fmt.Printf("Size of %v: %v byte(s)\n", f.Name, len(buf))

                // ファイル書き出し
                err = ioutil.WriteFile(filepath.Join(dirname, f.Name), buf, 0644)
                if err != nil {
                        log.Fatal(err)
                }

                break
        }

        // 入力待ち
        readline()
}
// パスワード付きzipファイル作る
$ zip -e --password=1234 pool.zip pool.pl
  adding: pool.pl (deflated 67%)

// go runだとos.Executable()が/tmpになるので展開先が消える
$ go run main.go pool.zip
/tmp/go-build265026491/b001/exe
[pool.zip]
Size of pool.pl: 6140 byte(s)
$ $ ./main pool.zip
ls: cannot access pool.pl: No such file or directory

// Linuxバイナリ作って実行ならOK
$ go build main.go
$ ./main pool.zip
/home/k8uwall/gozip
[pool.zip]
Size of pool.pl: 6140 byte(s)
$ ls pool.pl
pool.pl

// Windowsバイナリ作る
$ GOOS=windows GOARCH=amd64 go build main.go
$ ls main.exe
main.exe

// Windowsでも使える。ファイルを実行ファイルにDropしても動く。
PS C:\Users\k8uwall\Desktop\gozip> .\main.exe pool.zip
C:\Users\k8uwall\Desktop\gozip
[pool.zip]
Size of pool.pl: 6140 byte(s)
  • 入力待ちはWindows向けのデバッグ用
  • log.Fatalとfmt.Printfどっちかにしないとorz
  • フォルダーを含んだファイルが駄目くさい気がする
  • for _, f := range r.File {の箇所は1ファイルだけ取り出したかったのだけれど、ループ以外の方法がよくわからなかったが時間切れ

参考リンク

go言語でクロスコンパイルしてみる - Qiita

Goでflagを使ってコマンドライン引数を扱う - Qiita
Goでflagを使ってコマンドライン引数を扱う - Qiita
Go言語で標準入力 - Qiita

Go で実行ファイルのパスを取得 - Qiita
これは1.8以降

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?