lib: Add file name compression

Allows to compress short arbitrary strings and returns a string using base64 url encoding.

Generator for tables included and a few samples has been added. Add more to init.go

Tested with fuzzing for crash resistance and symmetry, see fuzz.go
This commit is contained in:
Klaus Post 2020-08-13 08:14:11 -07:00 committed by GitHub
parent 770a6f2cad
commit cb7534dcdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 363 additions and 4 deletions

View file

@ -0,0 +1,60 @@
package filename
import (
"encoding/base64"
"encoding/binary"
"github.com/klauspost/compress/huff0"
)
// Encode will encode the string and return a base64 (url) compatible version of it.
// Calling Decode with the returned string should always succeed.
// It is not a requirement that the input string is valid utf-8.
func Encode(s string) string {
initCoders()
bestSize := len(s)
bestTable := tableUncompressed
org := []byte(s)
bestOut := []byte(s)
// Try all tables and choose the best
for i, enc := range encTables[:] {
if len(org) <= 1 || len(org) > maxLength {
// Use the uncompressed
break
}
if enc == nil {
continue
}
// Try to encode using table.
err := func() error {
encTableLocks[i].Lock()
defer encTableLocks[i].Unlock()
out, _, err := huff0.Compress1X(org, enc)
if err != nil {
return err
}
if len(out) < bestSize {
bestOut = bestOut[:len(out)]
bestTable = i
bestSize = len(out)
copy(bestOut, out)
}
return nil
}()
// If input is a single byte repeated store as RLE or save uncompressed.
if err == huff0.ErrUseRLE {
if len(org) > 2 {
// Encode as one byte repeated since it will be smaller than uncompressed.
n := binary.PutUvarint(bestOut, uint64(len(org)))
bestOut = bestOut[:n+1]
bestOut[n] = org[0]
bestSize = n + 1
bestTable = tableRLE
}
break
}
}
return string(encodeURL[bestTable]) + base64.URLEncoding.EncodeToString(bestOut)
}