zip

package module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: BSD-3-Clause Imports: 38 Imported by: 0

README

Go Advanced ZIP Library

Go Reference

This project is a highly optimized and advanced drop-in replacement for the Go standard library archive/zip.

It combines the stability of the standard library with the best open-source ZIP processing features available in the Go ecosystem into one single, powerful package.

Features

  1. Drop-in Compatibility: 100% compatible with the archive/zip API. You can safely replace your archive/zip imports with github.com/unxed/zip.
  2. WinZip AES Encryption (AE-2): Full support for reading and writing AES-encrypted archives (128, 192, and 256-bit).
  3. Central Directory Encryption (CDE): The ability to encrypt the archive's metadata (filenames, sizes, etc.), making the list of files invisible without a password.
  4. Deflate64 Support: Built-in decoder for the Deflate64 (Method 9) format, commonly used by Windows' built-in archiver for large files.
  5. High Performance: Uses the blazing-fast klauspost/compress library for DEFLATE and adds native Zstandard (ZSTD) support.
  6. Multithreaded Archiving & Extraction: Concurrent archiver and extractor (adapted from fastzip) that processes multiple files in parallel.
  7. Cross-Platform Metadata:
    • Unix: Automatic preservation of UID/GID and extended timestamps.
    • Windows: Support for reading and writing NTFS Security Descriptors (ACLs).
  8. In-Place Archiving (Updater): Modify existing ZIP files (append/overwrite) without full re-compression.
  9. Legacy Codepage Auto-Detection: Advanced encoding detection from 7-zip / far2l to fix "mojibake" in filenames from legacy archives.

Usage

1. Standard Reader / Writer
import "github.com/unxed/zip"

// Use exactly like the standard library
r, err := zip.OpenReader("archive.zip")
// ...
2. High-Speed Multithreaded Archiving
w, _ := os.Create("archive.zip")
defer w.Close()

// Create archiver with concurrency
archiver, _ := zip.NewArchiver(w, "/path/to/source", zip.WithArchiverConcurrency(8))
defer archiver.Close()

// Map your files
files := make(map[string]os.FileInfo)
filepath.Walk("/path/to/source", func(p string, info os.FileInfo, err error) error {
	files[p] = info
	return nil
})

// Archive concurrently!
archiver.Archive(context.Background(), files)
3. In-Place Archive Update
f, _ := os.OpenFile("archive.zip", os.O_RDWR, 0)
defer f.Close()

updater, _ := zip.NewUpdater(f)
defer updater.Close()

// Overwrite an existing file natively
w, _ := updater.Append("config.json", zip.APPEND_MODE_OVERWRITE)
w.Write([]byte(`{"updated": true}`))

### 4. Create an Invisible (CDE) AES-256 Archive

```go
w, _ := os.Create("stealth.zip")
zw := zip.NewWriter(w)

// Encrypt the list of files itself!
zw.SetEncryptCentralDirectory(true, "master-password")

fh := &zip.FileHeader{Name: "secret.txt", Password: "master-password"}
f, _ := zw.CreateHeader(fh)
f.Write([]byte("top secret data"))
zw.Close()

License

This project is released under the BSD-3-Clause License. See also CREDITS.md.

Documentation

Index

Constants

View Source
const (
	Store     uint16 = 0 // no compression
	Deflate   uint16 = 8 // DEFLATE compressed
	Deflate64 uint16 = 9
	BZIP2     uint16 = 12
	LZMA      uint16 = 14
	ZSTD      uint16 = 93 // Zstandard compressed
)

Compression methods.

Variables

View Source
var (
	OEMDecoder    *encoding.Decoder = charmap.CodePage437.NewDecoder()
	ANSIDecoder   *encoding.Decoder = charmap.Windows1252.NewDecoder()
	SystemDecoder *encoding.Decoder = charmap.CodePage437.NewDecoder()
)

Legacy Decoders configuration. They are automatically initialized based on the system locale during init(). You can override them manually if you need strict enforcement.

View Source
var (
	ErrFormat       = errors.New("zip: not a valid zip file")
	ErrAlgorithm    = errors.New("zip: unsupported compression algorithm")
	ErrChecksum     = errors.New("zip: checksum error")
	ErrInsecurePath = errors.New("zip: insecure file path")
)
View Source
var ConfigIncludePlatformMetadata = false

ConfigIncludePlatformMetadata defines if FileInfoHeader should automatically include OS-specific metadata (like UID/GID on Unix). Disabled by default to ensure archive portability.

View Source
var ErrMinConcurrency = errors.New("concurrency must be at least 1")

Functions

func RegisterCompressor

func RegisterCompressor(method uint16, comp Compressor)

func RegisterDecompressor

func RegisterDecompressor(method uint16, dcomp Decompressor)

Types

type AppendMode

type AppendMode int

AppendMode specifies the way to append new file to existing zip archive.

const (
	// APPEND_MODE_OVERWRITE removes the existing file data and append the new
	// data to the end of the zip archive.
	APPEND_MODE_OVERWRITE AppendMode = iota

	// APPEND_MODE_KEEP_ORIGINAL will keep the original file data and only
	// write the new file data at the end of the existing zip archive file.
	// This mode will keep multiple file with same name into one archive file.
	APPEND_MODE_KEEP_ORIGINAL
)

type Archiver

type Archiver struct {
	// contains filtered or unexported fields
}

func NewArchiver

func NewArchiver(w io.Writer, chroot string, opts ...ArchiverOption) (*Archiver, error)

func (*Archiver) Archive

func (a *Archiver) Archive(ctx context.Context, files map[string]os.FileInfo) (err error)

func (*Archiver) Close

func (a *Archiver) Close() error

func (*Archiver) Written

func (a *Archiver) Written() (bytes, entries int64)

type ArchiverOption

type ArchiverOption func(*archiverOptions) error

func WithArchiverBufferSize

func WithArchiverBufferSize(n int) ArchiverOption

func WithArchiverConcurrency

func WithArchiverConcurrency(n int) ArchiverOption

func WithArchiverMethod

func WithArchiverMethod(method uint16) ArchiverOption

func WithArchiverOffset

func WithArchiverOffset(n int64) ArchiverOption

func WithArchiverPlatformMetadata

func WithArchiverPlatformMetadata(enable bool) ArchiverOption

WithArchiverPlatformMetadata enables inclusion of local OS metadata (UID/GID) for this archiver instance.

func WithStageDirectory

func WithStageDirectory(dir string) ArchiverOption

type Compressor

type Compressor func(w io.Writer) (io.WriteCloser, error)

type Decompressor

type Decompressor func(r io.Reader) io.ReadCloser

type Directory

type Directory struct {
	FileHeader
	// contains filtered or unexported fields
}

func (*Directory) HeaderOffset

func (d *Directory) HeaderOffset() int64

type Extractor

type Extractor struct {
	// contains filtered or unexported fields
}

func NewExtractor

func NewExtractor(filename, chroot string, opts ...ExtractorOption) (*Extractor, error)

func NewExtractorFromReader

func NewExtractorFromReader(r io.ReaderAt, size int64, chroot string, opts ...ExtractorOption) (*Extractor, error)

func (*Extractor) Close

func (e *Extractor) Close() error

func (*Extractor) Extract

func (e *Extractor) Extract(ctx context.Context) (err error)

func (*Extractor) Files

func (e *Extractor) Files() []*File

func (*Extractor) Written

func (e *Extractor) Written() (bytes, entries int64)

type ExtractorOption

type ExtractorOption func(*extractorOptions) error

func WithExtractorChownErrorHandler

func WithExtractorChownErrorHandler(fn func(name string, err error) error) ExtractorOption

func WithExtractorConcurrency

func WithExtractorConcurrency(n int) ExtractorOption

func WithExtractorMaxFileSize

func WithExtractorMaxFileSize(n int64) ExtractorOption

func WithExtractorMaxRatio

func WithExtractorMaxRatio(n int64) ExtractorOption

type File

type File struct {
	FileHeader
	// contains filtered or unexported fields
}

func (*File) DataOffset

func (f *File) DataOffset() (offset int64, err error)

func (*File) Open

func (f *File) Open() (io.ReadCloser, error)

func (*File) OpenRaw

func (f *File) OpenRaw() (io.Reader, error)

type FileHeader

type FileHeader struct {
	Name               string
	Comment            string
	NonUTF8            bool // If set, disables automatic UTF-8 flag encoding
	CreatorVersion     uint16
	ReaderVersion      uint16
	Flags              uint16
	Method             uint16
	Modified           time.Time
	Accessed           time.Time
	Created            time.Time
	ModifiedTime       uint16 // Deprecated
	ModifiedDate       uint16 // Deprecated
	CRC32              uint32
	CompressedSize     uint32 // Deprecated: Use CompressedSize64
	UncompressedSize   uint32 // Deprecated: Use UncompressedSize64
	CompressedSize64   uint64
	UncompressedSize64 uint64
	Extra              []byte
	ExternalAttrs      uint32
	// UNIX attributes
	Uid      int
	Gid      int
	OwnerSet bool
	// NTFS Attributes
	Acl []byte // Windows Security Descriptor (ACL)

	// WinZip AES encryption
	Password    string
	AESStrength byte // 1 = 128, 2 = 192, 3 = 256. Defaults to 3 (AES-256) if Password != ""
}

FileHeader describes a file within a ZIP file.

func FileInfoHeader

func FileInfoHeader(fi fs.FileInfo) (*FileHeader, error)

func (*FileHeader) FileInfo

func (h *FileHeader) FileInfo() fs.FileInfo

func (*FileHeader) IsEncrypted

func (h *FileHeader) IsEncrypted() bool

func (*FileHeader) ModTime

func (h *FileHeader) ModTime() time.Time

func (*FileHeader) Mode

func (h *FileHeader) Mode() (mode fs.FileMode)

func (*FileHeader) SetModTime

func (h *FileHeader) SetModTime(t time.Time)

func (*FileHeader) SetMode

func (h *FileHeader) SetMode(mode fs.FileMode)

type ReadCloser

type ReadCloser struct {
	Reader
	// contains filtered or unexported fields
}

func OpenReader

func OpenReader(name string) (*ReadCloser, error)

func (*ReadCloser) Close

func (rc *ReadCloser) Close() error

type Reader

type Reader struct {
	File    []*File
	Comment string
	// contains filtered or unexported fields
}

func NewReader

func NewReader(r io.ReaderAt, size int64) (*Reader, error)

func (*Reader) Open

func (r *Reader) Open(name string) (fs.File, error)

func (*Reader) RegisterDecompressor

func (r *Reader) RegisterDecompressor(method uint16, dcomp Decompressor)

func (*Reader) SetPassword

func (r *Reader) SetPassword(password string)

type Updater

type Updater struct {
	// contains filtered or unexported fields
}

Updater allows to modify & append files into an existing zip archive without decompress the whole file.

func NewUpdater

func NewUpdater(rws io.ReadWriteSeeker) (*Updater, error)

NewUpdater returns a new Updater from io.ReadWriteSeeker, which is assumed to have the given size in bytes.

func (*Updater) Append

func (u *Updater) Append(name string, mode AppendMode) (io.Writer, error)

func (*Updater) AppendHeader

func (u *Updater) AppendHeader(fh *FileHeader, mode AppendMode) (io.Writer, error)

func (*Updater) Close

func (u *Updater) Close() error

func (*Updater) Entries

func (u *Updater) Entries() []*FileHeader

func (*Updater) GetComment

func (u *Updater) GetComment() string

func (*Updater) RemoveFile

func (u *Updater) RemoveFile(dirIndex int) (int64, error)

func (*Updater) SetComment

func (u *Updater) SetComment(comment string) error

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

func NewWriter

func NewWriter(w io.Writer) *Writer

func (*Writer) AddFS

func (w *Writer) AddFS(fsys fs.FS) error

func (*Writer) Close

func (w *Writer) Close() error

func (*Writer) Copy

func (w *Writer) Copy(f *File) error

func (*Writer) Create

func (w *Writer) Create(name string) (io.Writer, error)

func (*Writer) CreateHeader

func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error)

func (*Writer) CreateRaw

func (w *Writer) CreateRaw(fh *FileHeader) (io.Writer, error)

func (*Writer) Flush

func (w *Writer) Flush() error

func (*Writer) RegisterCompressor

func (w *Writer) RegisterCompressor(method uint16, comp Compressor)

func (*Writer) SetComment

func (w *Writer) SetComment(comment string) error

func (*Writer) SetEncryptCentralDirectory

func (w *Writer) SetEncryptCentralDirectory(enable bool, password string)

SetEncryptCentralDirectory enables encryption of the central directory records. This hides file names and metadata from unauthorized users. Requires a password to be set.

func (*Writer) SetOffset

func (w *Writer) SetOffset(n int64)

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL