src/pkg/encoding/base32/base32.go - The Go Programming Language

Golang

Source file src/pkg/encoding/base32/base32.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package base32 implements base32 encoding as specified by RFC 4648.
     6	package base32
     7	
     8	import (
     9		"io"
    10		"strconv"
    11	)
    12	
    13	/*
    14	 * Encodings
    15	 */
    16	
    17	// An Encoding is a radix 32 encoding/decoding scheme, defined by a
    18	// 32-character alphabet.  The most common is the "base32" encoding
    19	// introduced for SASL GSSAPI and standardized in RFC 4648.
    20	// The alternate "base32hex" encoding is used in DNSSEC.
    21	type Encoding struct {
    22		encode    string
    23		decodeMap [256]byte
    24	}
    25	
    26	const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
    27	const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
    28	
    29	// NewEncoding returns a new Encoding defined by the given alphabet,
    30	// which must be a 32-byte string.
    31	func NewEncoding(encoder string) *Encoding {
    32		e := new(Encoding)
    33		e.encode = encoder
    34		for i := 0; i < len(e.decodeMap); i++ {
    35			e.decodeMap[i] = 0xFF
    36		}
    37		for i := 0; i < len(encoder); i++ {
    38			e.decodeMap[encoder[i]] = byte(i)
    39		}
    40		return e
    41	}
    42	
    43	// StdEncoding is the standard base32 encoding, as defined in
    44	// RFC 4648.
    45	var StdEncoding = NewEncoding(encodeStd)
    46	
    47	// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648.
    48	// It is typically used in DNS.
    49	var HexEncoding = NewEncoding(encodeHex)
    50	
    51	/*
    52	 * Encoder
    53	 */
    54	
    55	// Encode encodes src using the encoding enc, writing
    56	// EncodedLen(len(src)) bytes to dst.
    57	//
    58	// The encoding pads the output to a multiple of 8 bytes,
    59	// so Encode is not appropriate for use on individual blocks
    60	// of a large data stream.  Use NewEncoder() instead.
    61	func (enc *Encoding) Encode(dst, src []byte) {
    62		if len(src) == 0 {
    63			return
    64		}
    65	
    66		for len(src) > 0 {
    67			dst[0] = 0
    68			dst[1] = 0
    69			dst[2] = 0
    70			dst[3] = 0
    71			dst[4] = 0
    72			dst[5] = 0
    73			dst[6] = 0
    74			dst[7] = 0
    75	
    76			// Unpack 8x 5-bit source blocks into a 5 byte
    77			// destination quantum
    78			switch len(src) {
    79			default:
    80				dst[7] |= src[4] & 0x1F
    81				dst[6] |= src[4] >> 5
    82				fallthrough
    83			case 4:
    84				dst[6] |= (src[3] << 3) & 0x1F
    85				dst[5] |= (src[3] >> 2) & 0x1F
    86				dst[4] |= src[3] >> 7
    87				fallthrough
    88			case 3:
    89				dst[4] |= (src[2] << 1) & 0x1F
    90				dst[3] |= (src[2] >> 4) & 0x1F
    91				fallthrough
    92			case 2:
    93				dst[3] |= (src[1] << 4) & 0x1F
    94				dst[2] |= (src[1] >> 1) & 0x1F
    95				dst[1] |= (src[1] >> 6) & 0x1F
    96				fallthrough
    97			case 1:
    98				dst[1] |= (src[0] << 2) & 0x1F
    99				dst[0] |= src[0] >> 3
   100			}
   101	
   102			// Encode 5-bit blocks using the base32 alphabet
   103			for j := 0; j < 8; j++ {
   104				dst[j] = enc.encode[dst[j]]
   105			}
   106	
   107			// Pad the final quantum
   108			if len(src) < 5 {
   109				dst[7] = '='
   110				if len(src) < 4 {
   111					dst[6] = '='
   112					dst[5] = '='
   113					if len(src) < 3 {
   114						dst[4] = '='
   115						if len(src) < 2 {
   116							dst[3] = '='
   117							dst[2] = '='
   118						}
   119					}
   120				}
   121				break
   122			}
   123			src = src[5:]
   124			dst = dst[8:]
   125		}
   126	}
   127	
   128	// EncodeToString returns the base32 encoding of src.
   129	func (enc *Encoding) EncodeToString(src []byte) string {
   130		buf := make([]byte, enc.EncodedLen(len(src)))
   131		enc.Encode(buf, src)
   132		return string(buf)
   133	}
   134	
   135	type encoder struct {
   136		err  error
   137		enc  *Encoding
   138		w    io.Writer
   139		buf  [5]byte    // buffered data waiting to be encoded
   140		nbuf int        // number of bytes in buf
   141		out  [1024]byte // output buffer
   142	}
   143	
   144	func (e *encoder) Write(p []byte) (n int, err error) {
   145		if e.err != nil {
   146			return 0, e.err
   147		}
   148	
   149		// Leading fringe.
   150		if e.nbuf > 0 {
   151			var i int
   152			for i = 0; i < len(p) && e.nbuf < 5; i++ {
   153				e.buf[e.nbuf] = p[i]
   154				e.nbuf++
   155			}
   156			n += i
   157			p = p[i:]
   158			if e.nbuf < 5 {
   159				return
   160			}
   161			e.enc.Encode(e.out[0:], e.buf[0:])
   162			if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
   163				return n, e.err
   164			}
   165			e.nbuf = 0
   166		}
   167	
   168		// Large interior chunks.
   169		for len(p) >= 5 {
   170			nn := len(e.out) / 8 * 5
   171			if nn > len(p) {
   172				nn = len(p)
   173			}
   174			nn -= nn % 5
   175			if nn > 0 {
   176				e.enc.Encode(e.out[0:], p[0:nn])
   177				if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
   178					return n, e.err
   179				}
   180			}
   181			n += nn
   182			p = p[nn:]
   183		}
   184	
   185		// Trailing fringe.
   186		for i := 0; i < len(p); i++ {
   187			e.buf[i] = p[i]
   188		}
   189		e.nbuf = len(p)
   190		n += len(p)
   191		return
   192	}
   193	
   194	// Close flushes any pending output from the encoder.
   195	// It is an error to call Write after calling Close.
   196	func (e *encoder) Close() error {
   197		// If there's anything left in the buffer, flush it out
   198		if e.err == nil && e.nbuf > 0 {
   199			e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
   200			e.nbuf = 0
   201			_, e.err = e.w.Write(e.out[0:8])
   202		}
   203		return e.err
   204	}
   205	
   206	// NewEncoder returns a new base32 stream encoder.  Data written to
   207	// the returned writer will be encoded using enc and then written to w.
   208	// Base32 encodings operate in 5-byte blocks; when finished
   209	// writing, the caller must Close the returned encoder to flush any
   210	// partially written blocks.
   211	func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
   212		return &encoder{enc: enc, w: w}
   213	}
   214	
   215	// EncodedLen returns the length in bytes of the base32 encoding
   216	// of an input buffer of length n.
   217	func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 }
   218	
   219	/*
   220	 * Decoder
   221	 */
   222	
   223	type CorruptInputError int64
   224	
   225	func (e CorruptInputError) Error() string {
   226		return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
   227	}
   228	
   229	// decode is like Decode but returns an additional 'end' value, which
   230	// indicates if end-of-message padding was encountered and thus any
   231	// additional data is an error.
   232	func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
   233		osrc := src
   234		for len(src) > 0 && !end {
   235			// Decode quantum using the base32 alphabet
   236			var dbuf [8]byte
   237			dlen := 8
   238	
   239			// do the top bytes contain any data?
   240		dbufloop:
   241			for j := 0; j < 8; {
   242				if len(src) == 0 {
   243					return n, false, CorruptInputError(len(osrc) - len(src) - j)
   244				}
   245				in := src[0]
   246				src = src[1:]
   247				if in == '\r' || in == '\n' {
   248					// Ignore this character.
   249					continue
   250				}
   251				if in == '=' && j >= 2 && len(src) < 8 {
   252					// We've reached the end and there's
   253					// padding, the rest should be padded
   254					for k := 0; k < 8-j-1; k++ {
   255						if len(src) > k && src[k] != '=' {
   256							return n, false, CorruptInputError(len(osrc) - len(src) + k - 1)
   257						}
   258					}
   259					dlen = j
   260					end = true
   261					break dbufloop
   262				}
   263				dbuf[j] = enc.decodeMap[in]
   264				if dbuf[j] == 0xFF {
   265					return n, false, CorruptInputError(len(osrc) - len(src) - 1)
   266				}
   267				j++
   268			}
   269	
   270			// Pack 8x 5-bit source blocks into 5 byte destination
   271			// quantum
   272			switch dlen {
   273			case 7, 8:
   274				dst[4] = dbuf[6]<<5 | dbuf[7]
   275				fallthrough
   276			case 6, 5:
   277				dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
   278				fallthrough
   279			case 4:
   280				dst[2] = dbuf[3]<<4 | dbuf[4]>>1
   281				fallthrough
   282			case 3:
   283				dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
   284				fallthrough
   285			case 2:
   286				dst[0] = dbuf[0]<<3 | dbuf[1]>>2
   287			}
   288			dst = dst[5:]
   289			switch dlen {
   290			case 2:
   291				n += 1
   292			case 3, 4:
   293				n += 2
   294			case 5:
   295				n += 3
   296			case 6, 7:
   297				n += 4
   298			case 8:
   299				n += 5
   300			}
   301		}
   302		return n, end, nil
   303	}
   304	
   305	// Decode decodes src using the encoding enc.  It writes at most
   306	// DecodedLen(len(src)) bytes to dst and returns the number of bytes
   307	// written.  If src contains invalid base32 data, it will return the
   308	// number of bytes successfully written and CorruptInputError.
   309	// New line characters (\r and \n) are ignored.
   310	func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
   311		n, _, err = enc.decode(dst, src)
   312		return
   313	}
   314	
   315	// DecodeString returns the bytes represented by the base32 string s.
   316	func (enc *Encoding) DecodeString(s string) ([]byte, error) {
   317		dbuf := make([]byte, enc.DecodedLen(len(s)))
   318		n, err := enc.Decode(dbuf, []byte(s))
   319		return dbuf[:n], err
   320	}
   321	
   322	type decoder struct {
   323		err    error
   324		enc    *Encoding
   325		r      io.Reader
   326		end    bool       // saw end of message
   327		buf    [1024]byte // leftover input
   328		nbuf   int
   329		out    []byte // leftover decoded output
   330		outbuf [1024 / 8 * 5]byte
   331	}
   332	
   333	func (d *decoder) Read(p []byte) (n int, err error) {
   334		if d.err != nil {
   335			return 0, d.err
   336		}
   337	
   338		// Use leftover decoded output from last read.
   339		if len(d.out) > 0 {
   340			n = copy(p, d.out)
   341			d.out = d.out[n:]
   342			return n, nil
   343		}
   344	
   345		// Read a chunk.
   346		nn := len(p) / 5 * 8
   347		if nn < 8 {
   348			nn = 8
   349		}
   350		if nn > len(d.buf) {
   351			nn = len(d.buf)
   352		}
   353		nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
   354		d.nbuf += nn
   355		if d.nbuf < 8 {
   356			return 0, d.err
   357		}
   358	
   359		// Decode chunk into p, or d.out and then p if p is too small.
   360		nr := d.nbuf / 8 * 8
   361		nw := d.nbuf / 8 * 5
   362		if nw > len(p) {
   363			nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
   364			d.out = d.outbuf[0:nw]
   365			n = copy(p, d.out)
   366			d.out = d.out[n:]
   367		} else {
   368			n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
   369		}
   370		d.nbuf -= nr
   371		for i := 0; i < d.nbuf; i++ {
   372			d.buf[i] = d.buf[i+nr]
   373		}
   374	
   375		if d.err == nil {
   376			d.err = err
   377		}
   378		return n, d.err
   379	}
   380	
   381	// NewDecoder constructs a new base32 stream decoder.
   382	func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
   383		return &decoder{enc: enc, r: r}
   384	}
   385	
   386	// DecodedLen returns the maximum length in bytes of the decoded data
   387	// corresponding to n bytes of base32-encoded data.
   388	func (enc *Encoding) DecodedLen(n int) int { return n / 8 * 5 }