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:
parent
770a6f2cad
commit
cb7534dcdf
8 changed files with 363 additions and 4 deletions
60
lib/encoder/filename/encode.go
Normal file
60
lib/encoder/filename/encode.go
Normal 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)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue