func (c *Cipher) encrypt(deadline uint64, b []byte) []byte {
	result := make([]byte, c.hdrLen+len(b))
	binary.BigEndian.PutUint64(result[c.sigLen:c.hdrLen], deadline)
	copy(result[c.hdrLen:], b)
	hash := hmac.New(c.hash, c.signKey)
	hash.Write(b)
	hash.Write(result[c.sigLen:c.hdrLen])
	copy(result, hash.Sum(nil)[:c.sigLen])
	return result
}
| signature | deadline | str
package token
import (
	"bytes"
	"crypto/hmac"
	"encoding/binary"
	"hash"
	"time"
	"github.com/cosiner/gohper/encoding"
	"github.com/cosiner/gohper/errors"
	"github.com/cosiner/gohper/time2"
)
const (
	ErrBadKey           = errors.Err("bad key")
	ErrExpiredKey       = errors.Err("expired key")
	ErrInvalidSignature = errors.Err("invalid signature")
)
type Cipher struct {
	signKey []byte
	ttl     time.Duration
	hash    func() hash.Hash
	sigLen  int
	hdrLen  int
}
func newCipher(signKey []byte, ttl time.Duration, hash func() hash.Hash) *Cipher {
	sigLen := hash().Size()
	return &Cipher{
		signKey: signKey,
		ttl:     ttl,
		hash:    hash,
		sigLen:  sigLen,
		hdrLen:  sigLen + 8,
	}
}
func NewCipher(signKey []byte, ttl time.Duration, hash func() hash.Hash, encs ...encoding.Encoding) encoding.Encoding {
	return encoding.Pipe(encs).Prepend(newCipher(signKey, ttl, hash))
}