...
Run Format

Source file src/encoding/base64/base64.go

     1	// Copyright 2009 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 base64 implements base64 encoding as specified by RFC 4648.
     6	package base64
     7	
     8	import (
     9		"io"
    10		"strconv"
    11	)
    12	
    13	/*
    14	 * Encodings
    15	 */
    16	
    17	// An Encoding is a radix 64 encoding/decoding scheme, defined by a
    18	// 64-character alphabet. The most common encoding is the "base64"
    19	// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
    20	// (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
    21	// the standard encoding with - and _ substituted for + and /.
    22	type Encoding struct {
    23		encode    [64]byte
    24		decodeMap [256]byte
    25		padChar   rune
    26		strict    bool
    27	}
    28	
    29	const (
    30		StdPadding rune = '=' // Standard padding character
    31		NoPadding  rune = -1  // No padding
    32	)
    33	
    34	const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    35	const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
    36	
    37	// NewEncoding returns a new padded Encoding defined by the given alphabet,
    38	// which must be a 64-byte string.
    39	// The resulting Encoding uses the default padding character ('='),
    40	// which may be changed or disabled via WithPadding.
    41	func NewEncoding(encoder string) *Encoding {
    42		if len(encoder) != 64 {
    43			panic("encoding alphabet is not 64-bytes long")
    44		}
    45	
    46		e := new(Encoding)
    47		e.padChar = StdPadding
    48		copy(e.encode[:], encoder)
    49	
    50		for i := 0; i < len(e.decodeMap); i++ {
    51			e.decodeMap[i] = 0xFF
    52		}
    53		for i := 0; i < len(encoder); i++ {
    54			e.decodeMap[encoder[i]] = byte(i)
    55		}
    56		return e
    57	}
    58	
    59	// WithPadding creates a new encoding identical to enc except
    60	// with a specified padding character, or NoPadding to disable padding.
    61	func (enc Encoding) WithPadding(padding rune) *Encoding {
    62		enc.padChar = padding
    63		return &enc
    64	}
    65	
    66	// Strict creates a new encoding identical to enc except with
    67	// strict decoding enabled. In this mode, the decoder requires that
    68	// trailing padding bits are zero, as described in RFC 4648 section 3.5.
    69	func (enc Encoding) Strict() *Encoding {
    70		enc.strict = true
    71		return &enc
    72	}
    73	
    74	// StdEncoding is the standard base64 encoding, as defined in
    75	// RFC 4648.
    76	var StdEncoding = NewEncoding(encodeStd)
    77	
    78	// URLEncoding is the alternate base64 encoding defined in RFC 4648.
    79	// It is typically used in URLs and file names.
    80	var URLEncoding = NewEncoding(encodeURL)
    81	
    82	// RawStdEncoding is the standard raw, unpadded base64 encoding,
    83	// as defined in RFC 4648 section 3.2.
    84	// This is the same as StdEncoding but omits padding characters.
    85	var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
    86	
    87	// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
    88	// It is typically used in URLs and file names.
    89	// This is the same as URLEncoding but omits padding characters.
    90	var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
    91	
    92	/*
    93	 * Encoder
    94	 */
    95	
    96	// Encode encodes src using the encoding enc, writing
    97	// EncodedLen(len(src)) bytes to dst.
    98	//
    99	// The encoding pads the output to a multiple of 4 bytes,
   100	// so Encode is not appropriate for use on individual blocks
   101	// of a large data stream. Use NewEncoder() instead.
   102	func (enc *Encoding) Encode(dst, src []byte) {
   103		if len(src) == 0 {
   104			return
   105		}
   106	
   107		di, si := 0, 0
   108		n := (len(src) / 3) * 3
   109		for si < n {
   110			// Convert 3x 8bit source bytes into 4 bytes
   111			val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
   112	
   113			dst[di+0] = enc.encode[val>>18&0x3F]
   114			dst[di+1] = enc.encode[val>>12&0x3F]
   115			dst[di+2] = enc.encode[val>>6&0x3F]
   116			dst[di+3] = enc.encode[val&0x3F]
   117	
   118			si += 3
   119			di += 4
   120		}
   121	
   122		remain := len(src) - si
   123		if remain == 0 {
   124			return
   125		}
   126		// Add the remaining small block
   127		val := uint(src[si+0]) << 16
   128		if remain == 2 {
   129			val |= uint(src[si+1]) << 8
   130		}
   131	
   132		dst[di+0] = enc.encode[val>>18&0x3F]
   133		dst[di+1] = enc.encode[val>>12&0x3F]
   134	
   135		switch remain {
   136		case 2:
   137			dst[di+2] = enc.encode[val>>6&0x3F]
   138			if enc.padChar != NoPadding {
   139				dst[di+3] = byte(enc.padChar)
   140			}
   141		case 1:
   142			if enc.padChar != NoPadding {
   143				dst[di+2] = byte(enc.padChar)
   144				dst[di+3] = byte(enc.padChar)
   145			}
   146		}
   147	}
   148	
   149	// EncodeToString returns the base64 encoding of src.
   150	func (enc *Encoding) EncodeToString(src []byte) string {
   151		buf := make([]byte, enc.EncodedLen(len(src)))
   152		enc.Encode(buf, src)
   153		return string(buf)
   154	}
   155	
   156	type encoder struct {
   157		err  error
   158		enc  *Encoding
   159		w    io.Writer
   160		buf  [3]byte    // buffered data waiting to be encoded
   161		nbuf int        // number of bytes in buf
   162		out  [1024]byte // output buffer
   163	}
   164	
   165	func (e *encoder) Write(p []byte) (n int, err error) {
   166		if e.err != nil {
   167			return 0, e.err
   168		}
   169	
   170		// Leading fringe.
   171		if e.nbuf > 0 {
   172			var i int
   173			for i = 0; i < len(p) && e.nbuf < 3; i++ {
   174				e.buf[e.nbuf] = p[i]
   175				e.nbuf++
   176			}
   177			n += i
   178			p = p[i:]
   179			if e.nbuf < 3 {
   180				return
   181			}
   182			e.enc.Encode(e.out[:], e.buf[:])
   183			if _, e.err = e.w.Write(e.out[:4]); e.err != nil {
   184				return n, e.err
   185			}
   186			e.nbuf = 0
   187		}
   188	
   189		// Large interior chunks.
   190		for len(p) >= 3 {
   191			nn := len(e.out) / 4 * 3
   192			if nn > len(p) {
   193				nn = len(p)
   194				nn -= nn % 3
   195			}
   196			e.enc.Encode(e.out[:], p[:nn])
   197			if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
   198				return n, e.err
   199			}
   200			n += nn
   201			p = p[nn:]
   202		}
   203	
   204		// Trailing fringe.
   205		for i := 0; i < len(p); i++ {
   206			e.buf[i] = p[i]
   207		}
   208		e.nbuf = len(p)
   209		n += len(p)
   210		return
   211	}
   212	
   213	// Close flushes any pending output from the encoder.
   214	// It is an error to call Write after calling Close.
   215	func (e *encoder) Close() error {
   216		// If there's anything left in the buffer, flush it out
   217		if e.err == nil && e.nbuf > 0 {
   218			e.enc.Encode(e.out[:], e.buf[:e.nbuf])
   219			_, e.err = e.w.Write(e.out[:e.enc.EncodedLen(e.nbuf)])
   220			e.nbuf = 0
   221		}
   222		return e.err
   223	}
   224	
   225	// NewEncoder returns a new base64 stream encoder. Data written to
   226	// the returned writer will be encoded using enc and then written to w.
   227	// Base64 encodings operate in 4-byte blocks; when finished
   228	// writing, the caller must Close the returned encoder to flush any
   229	// partially written blocks.
   230	func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
   231		return &encoder{enc: enc, w: w}
   232	}
   233	
   234	// EncodedLen returns the length in bytes of the base64 encoding
   235	// of an input buffer of length n.
   236	func (enc *Encoding) EncodedLen(n int) int {
   237		if enc.padChar == NoPadding {
   238			return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
   239		}
   240		return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
   241	}
   242	
   243	/*
   244	 * Decoder
   245	 */
   246	
   247	type CorruptInputError int64
   248	
   249	func (e CorruptInputError) Error() string {
   250		return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
   251	}
   252	
   253	// decode is like Decode but returns an additional 'end' value, which
   254	// indicates if end-of-message padding or a partial quantum was encountered
   255	// and thus any additional data is an error.
   256	func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
   257		si := 0
   258	
   259		// skip over newlines
   260		for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   261			si++
   262		}
   263	
   264		for si < len(src) && !end {
   265			// Decode quantum using the base64 alphabet
   266			var dbuf [4]byte
   267			dinc, dlen := 3, 4
   268	
   269			for j := range dbuf {
   270				if len(src) == si {
   271					if enc.padChar != NoPadding || j < 2 {
   272						return n, false, CorruptInputError(si - j)
   273					}
   274					dinc, dlen, end = j-1, j, true
   275					break
   276				}
   277				in := src[si]
   278	
   279				si++
   280				// skip over newlines
   281				for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   282					si++
   283				}
   284	
   285				if rune(in) == enc.padChar {
   286					// We've reached the end and there's padding
   287					switch j {
   288					case 0, 1:
   289						// incorrect padding
   290						return n, false, CorruptInputError(si - 1)
   291					case 2:
   292						// "==" is expected, the first "=" is already consumed.
   293						if si == len(src) {
   294							// not enough padding
   295							return n, false, CorruptInputError(len(src))
   296						}
   297						if rune(src[si]) != enc.padChar {
   298							// incorrect padding
   299							return n, false, CorruptInputError(si - 1)
   300						}
   301	
   302						si++
   303						// skip over newlines
   304						for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   305							si++
   306						}
   307					}
   308					if si < len(src) {
   309						// trailing garbage
   310						err = CorruptInputError(si)
   311					}
   312					dinc, dlen, end = 3, j, true
   313					break
   314				}
   315				dbuf[j] = enc.decodeMap[in]
   316				if dbuf[j] == 0xFF {
   317					return n, false, CorruptInputError(si - 1)
   318				}
   319			}
   320	
   321			// Convert 4x 6bit source bytes into 3 bytes
   322			val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
   323			dbuf[2], dbuf[1], dbuf[0] = byte(val>>0), byte(val>>8), byte(val>>16)
   324			switch dlen {
   325			case 4:
   326				dst[2] = dbuf[2]
   327				dbuf[2] = 0
   328				fallthrough
   329			case 3:
   330				dst[1] = dbuf[1]
   331				if enc.strict && dbuf[2] != 0 {
   332					return n, end, CorruptInputError(si - 1)
   333				}
   334				dbuf[1] = 0
   335				fallthrough
   336			case 2:
   337				dst[0] = dbuf[0]
   338				if enc.strict && (dbuf[1] != 0 || dbuf[2] != 0) {
   339					return n, end, CorruptInputError(si - 2)
   340				}
   341			}
   342			dst = dst[dinc:]
   343			n += dlen - 1
   344		}
   345	
   346		return n, end, err
   347	}
   348	
   349	// Decode decodes src using the encoding enc. It writes at most
   350	// DecodedLen(len(src)) bytes to dst and returns the number of bytes
   351	// written. If src contains invalid base64 data, it will return the
   352	// number of bytes successfully written and CorruptInputError.
   353	// New line characters (\r and \n) are ignored.
   354	func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
   355		n, _, err = enc.decode(dst, src)
   356		return
   357	}
   358	
   359	// DecodeString returns the bytes represented by the base64 string s.
   360	func (enc *Encoding) DecodeString(s string) ([]byte, error) {
   361		dbuf := make([]byte, enc.DecodedLen(len(s)))
   362		n, _, err := enc.decode(dbuf, []byte(s))
   363		return dbuf[:n], err
   364	}
   365	
   366	type decoder struct {
   367		err     error
   368		readErr error // error from r.Read
   369		enc     *Encoding
   370		r       io.Reader
   371		end     bool       // saw end of message
   372		buf     [1024]byte // leftover input
   373		nbuf    int
   374		out     []byte // leftover decoded output
   375		outbuf  [1024 / 4 * 3]byte
   376	}
   377	
   378	func (d *decoder) Read(p []byte) (n int, err error) {
   379		// Use leftover decoded output from last read.
   380		if len(d.out) > 0 {
   381			n = copy(p, d.out)
   382			d.out = d.out[n:]
   383			return n, nil
   384		}
   385	
   386		if d.err != nil {
   387			return 0, d.err
   388		}
   389	
   390		// This code assumes that d.r strips supported whitespace ('\r' and '\n').
   391	
   392		// Refill buffer.
   393		for d.nbuf < 4 && d.readErr == nil {
   394			nn := len(p) / 3 * 4
   395			if nn < 4 {
   396				nn = 4
   397			}
   398			if nn > len(d.buf) {
   399				nn = len(d.buf)
   400			}
   401			nn, d.readErr = d.r.Read(d.buf[d.nbuf:nn])
   402			d.nbuf += nn
   403		}
   404	
   405		if d.nbuf < 4 {
   406			if d.enc.padChar == NoPadding && d.nbuf > 0 {
   407				// Decode final fragment, without padding.
   408				var nw int
   409				nw, _, d.err = d.enc.decode(d.outbuf[:], d.buf[:d.nbuf])
   410				d.nbuf = 0
   411				d.end = true
   412				d.out = d.outbuf[:nw]
   413				n = copy(p, d.out)
   414				d.out = d.out[n:]
   415				if n > 0 || len(p) == 0 && len(d.out) > 0 {
   416					return n, nil
   417				}
   418				if d.err != nil {
   419					return 0, d.err
   420				}
   421			}
   422			d.err = d.readErr
   423			if d.err == io.EOF && d.nbuf > 0 {
   424				d.err = io.ErrUnexpectedEOF
   425			}
   426			return 0, d.err
   427		}
   428	
   429		// Decode chunk into p, or d.out and then p if p is too small.
   430		nr := d.nbuf / 4 * 4
   431		nw := d.nbuf / 4 * 3
   432		if nw > len(p) {
   433			nw, d.end, d.err = d.enc.decode(d.outbuf[:], d.buf[:nr])
   434			d.out = d.outbuf[:nw]
   435			n = copy(p, d.out)
   436			d.out = d.out[n:]
   437		} else {
   438			n, d.end, d.err = d.enc.decode(p, d.buf[:nr])
   439		}
   440		d.nbuf -= nr
   441		copy(d.buf[:d.nbuf], d.buf[nr:])
   442		return n, d.err
   443	}
   444	
   445	type newlineFilteringReader struct {
   446		wrapped io.Reader
   447	}
   448	
   449	func (r *newlineFilteringReader) Read(p []byte) (int, error) {
   450		n, err := r.wrapped.Read(p)
   451		for n > 0 {
   452			offset := 0
   453			for i, b := range p[:n] {
   454				if b != '\r' && b != '\n' {
   455					if i != offset {
   456						p[offset] = b
   457					}
   458					offset++
   459				}
   460			}
   461			if offset > 0 {
   462				return offset, err
   463			}
   464			// Previous buffer entirely whitespace, read again
   465			n, err = r.wrapped.Read(p)
   466		}
   467		return n, err
   468	}
   469	
   470	// NewDecoder constructs a new base64 stream decoder.
   471	func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
   472		return &decoder{enc: enc, r: &newlineFilteringReader{r}}
   473	}
   474	
   475	// DecodedLen returns the maximum length in bytes of the decoded data
   476	// corresponding to n bytes of base64-encoded data.
   477	func (enc *Encoding) DecodedLen(n int) int {
   478		if enc.padChar == NoPadding {
   479			// Unpadded data may end with partial block of 2-3 characters.
   480			return n * 6 / 8
   481		}
   482		// Padded base64 should always be a multiple of 4 characters in length.
   483		return n / 4 * 3
   484	}
   485	

View as plain text