Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package base32 implements base32 encoding as specified by RFC 4648.
package base32

import (
	
	
)
* Encodings
An Encoding is a radix 32 encoding/decoding scheme, defined by a 32-character alphabet. The most common is the "base32" encoding introduced for SASL GSSAPI and standardized in RFC 4648. The alternate "base32hex" encoding is used in DNSSEC.
type Encoding struct {
	encode    [32]byte
	decodeMap [256]byte
	padChar   rune
}

const (
	StdPadding rune = '=' // Standard padding character
	NoPadding  rune = -1  // No padding
)

const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
NewEncoding returns a new Encoding defined by the given alphabet, which must be a 32-byte string.
func ( string) *Encoding {
	if len() != 32 {
		panic("encoding alphabet is not 32-bytes long")
	}

	 := new(Encoding)
	copy(.encode[:], )
	.padChar = StdPadding

	for  := 0;  < len(.decodeMap); ++ {
		.decodeMap[] = 0xFF
	}
	for  := 0;  < len(); ++ {
		.decodeMap[[]] = byte()
	}
	return 
}
StdEncoding is the standard base32 encoding, as defined in RFC 4648.
HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648. It is typically used in DNS.
WithPadding creates a new encoding identical to enc except with a specified padding character, or NoPadding to disable padding. The padding character must not be '\r' or '\n', must not be contained in the encoding's alphabet and must be a rune equal or below '\xff'.
func ( Encoding) ( rune) *Encoding {
	if  == '\r' ||  == '\n' ||  > 0xff {
		panic("invalid padding")
	}

	for  := 0;  < len(.encode); ++ {
		if rune(.encode[]) ==  {
			panic("padding contained in alphabet")
		}
	}

	.padChar = 
	return &
}
* Encoder
Encode encodes src using the encoding enc, writing EncodedLen(len(src)) bytes to dst. The encoding pads the output to a multiple of 8 bytes, so Encode is not appropriate for use on individual blocks of a large data stream. Use NewEncoder() instead.
func ( *Encoding) (,  []byte) {
	for len() > 0 {
		var  [8]byte
Unpack 8x 5-bit source blocks into a 5 byte destination quantum
		switch len() {
		default:
			[7] = [4] & 0x1F
			[6] = [4] >> 5
			fallthrough
		case 4:
			[6] |= ([3] << 3) & 0x1F
			[5] = ([3] >> 2) & 0x1F
			[4] = [3] >> 7
			fallthrough
		case 3:
			[4] |= ([2] << 1) & 0x1F
			[3] = ([2] >> 4) & 0x1F
			fallthrough
		case 2:
			[3] |= ([1] << 4) & 0x1F
			[2] = ([1] >> 1) & 0x1F
			[1] = ([1] >> 6) & 0x1F
			fallthrough
		case 1:
			[1] |= ([0] << 2) & 0x1F
			[0] = [0] >> 3
		}
Encode 5-bit blocks using the base32 alphabet
		 := len()
Common case, unrolled for extra performance
			[0] = .encode[[0]&31]
			[1] = .encode[[1]&31]
			[2] = .encode[[2]&31]
			[3] = .encode[[3]&31]
			[4] = .encode[[4]&31]
			[5] = .encode[[5]&31]
			[6] = .encode[[6]&31]
			[7] = .encode[[7]&31]
		} else {
			for  := 0;  < ; ++ {
				[] = .encode[[]&31]
			}
		}
Pad the final quantum
		if len() < 5 {
			if .padChar == NoPadding {
				break
			}

			[7] = byte(.padChar)
			if len() < 4 {
				[6] = byte(.padChar)
				[5] = byte(.padChar)
				if len() < 3 {
					[4] = byte(.padChar)
					if len() < 2 {
						[3] = byte(.padChar)
						[2] = byte(.padChar)
					}
				}
			}

			break
		}

		 = [5:]
		 = [8:]
	}
}
EncodeToString returns the base32 encoding of src.
func ( *Encoding) ( []byte) string {
	 := make([]byte, .EncodedLen(len()))
	.Encode(, )
	return string()
}

type encoder struct {
	err  error
	enc  *Encoding
	w    io.Writer
	buf  [5]byte    // buffered data waiting to be encoded
	nbuf int        // number of bytes in buf
	out  [1024]byte // output buffer
}

func ( *encoder) ( []byte) ( int,  error) {
	if .err != nil {
		return 0, .err
	}
Leading fringe.
	if .nbuf > 0 {
		var  int
		for  = 0;  < len() && .nbuf < 5; ++ {
			.buf[.nbuf] = []
			.nbuf++
		}
		 += 
		 = [:]
		if .nbuf < 5 {
			return
		}
		.enc.Encode(.out[0:], .buf[0:])
		if _, .err = .w.Write(.out[0:8]); .err != nil {
			return , .err
		}
		.nbuf = 0
	}
Large interior chunks.
	for len() >= 5 {
		 := len(.out) / 8 * 5
		if  > len() {
			 = len()
			 -=  % 5
		}
		.enc.Encode(.out[0:], [0:])
		if _, .err = .w.Write(.out[0 : /5*8]); .err != nil {
			return , .err
		}
		 += 
		 = [:]
	}
Trailing fringe.
	for  := 0;  < len(); ++ {
		.buf[] = []
	}
	.nbuf = len()
	 += len()
	return
}
Close flushes any pending output from the encoder. It is an error to call Write after calling Close.
If there's anything left in the buffer, flush it out
	if .err == nil && .nbuf > 0 {
		.enc.Encode(.out[0:], .buf[0:.nbuf])
		 := .enc.EncodedLen(.nbuf)
		.nbuf = 0
		_, .err = .w.Write(.out[0:])
	}
	return .err
}
NewEncoder returns a new base32 stream encoder. Data written to the returned writer will be encoded using enc and then written to w. Base32 encodings operate in 5-byte blocks; when finished writing, the caller must Close the returned encoder to flush any partially written blocks.
func ( *Encoding,  io.Writer) io.WriteCloser {
	return &encoder{enc: , w: }
}
EncodedLen returns the length in bytes of the base32 encoding of an input buffer of length n.
func ( *Encoding) ( int) int {
	if .padChar == NoPadding {
		return (*8 + 4) / 5
	}
	return ( + 4) / 5 * 8
}
* Decoder

type CorruptInputError int64

func ( CorruptInputError) () string {
	return "illegal base32 data at input byte " + strconv.FormatInt(int64(), 10)
}
decode is like Decode but returns an additional 'end' value, which indicates if end-of-message padding was encountered and thus any additional data is an error. This method assumes that src has been stripped of all supported whitespace ('\r' and '\n').
Lift the nil check outside of the loop.
	_ = .decodeMap

	 := 0
	 := len()

Decode quantum using the base32 alphabet
		var  [8]byte
		 := 8

		for  := 0;  < 8; {

			if len() == 0 {
We have reached the end and are missing padding
					return , false, CorruptInputError( - len() - )
We have reached the end and are not expecting any padding
				,  = , true
				break
			}
			 := [0]
			 = [1:]
We've reached the end and there's padding
not enough padding
					return , false, CorruptInputError()
				}
				for  := 0;  < 8-1-; ++ {
incorrect padding
						return , false, CorruptInputError( - len() +  - 1)
					}
				}
7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing the five valid padding lengths, and Section 9 "Illustrations and Examples" for an illustration for how the 1st, 3rd and 6th base32 src bytes do not yield enough information to decode a dst byte.
				if  == 1 ||  == 3 ||  == 6 {
					return , false, CorruptInputError( - len() - 1)
				}
				break
			}
			[] = .decodeMap[]
			if [] == 0xFF {
				return , false, CorruptInputError( - len() - 1)
			}
			++
		}
Pack 8x 5-bit source blocks into 5 byte destination quantum
		switch  {
		case 8:
			[+4] = [6]<<5 | [7]
			++
			fallthrough
		case 7:
			[+3] = [4]<<7 | [5]<<2 | [6]>>3
			++
			fallthrough
		case 5:
			[+2] = [3]<<4 | [4]>>1
			++
			fallthrough
		case 4:
			[+1] = [1]<<6 | [2]<<1 | [3]>>4
			++
			fallthrough
		case 2:
			[+0] = [0]<<3 | [1]>>2
			++
		}
		 += 5
	}
	return , , nil
}
Decode decodes src using the encoding enc. It writes at most DecodedLen(len(src)) bytes to dst and returns the number of bytes written. If src contains invalid base32 data, it will return the number of bytes successfully written and CorruptInputError. New line characters (\r and \n) are ignored.
func ( *Encoding) (,  []byte) ( int,  error) {
	 := make([]byte, len())
	 := stripNewlines(, )
	, _,  = .decode(, [:])
	return
}
DecodeString returns the bytes represented by the base32 string s.
func ( *Encoding) ( string) ([]byte, error) {
	 := []byte()
	 := stripNewlines(, )
	, ,  := .decode(, [:])
	return [:], 
}

type decoder struct {
	err    error
	enc    *Encoding
	r      io.Reader
	end    bool       // saw end of message
	buf    [1024]byte // leftover input
	nbuf   int
	out    []byte // leftover decoded output
	outbuf [1024 / 8 * 5]byte
}

func ( io.Reader,  []byte,  int,  bool) ( int,  error) {
	for  <  &&  == nil {
		var  int
		,  = .Read([:])
		 += 
data was read, less than min bytes could be read
	if  <  &&  > 0 &&  == io.EOF {
		 = io.ErrUnexpectedEOF
no data was read, the buffer already contains some data when padding is disabled this is not an error, as the message can be of any length
	if  &&  < 8 &&  == 0 &&  == io.EOF {
		 = io.ErrUnexpectedEOF
	}
	return
}

Use leftover decoded output from last read.
	if len(.out) > 0 {
		 = copy(, .out)
		.out = .out[:]
		if len(.out) == 0 {
			return , .err
		}
		return , nil
	}

	if .err != nil {
		return 0, .err
	}
Read a chunk.
	 := len() / 5 * 8
	if  < 8 {
		 = 8
	}
	if  > len(.buf) {
		 = len(.buf)
	}
Minimum amount of bytes that needs to be read each cycle
	var  int
	var  bool
	if .enc.padChar == NoPadding {
		 = 1
		 = false
	} else {
		 = 8 - .nbuf
		 = true
	}

	, .err = readEncodedData(.r, .buf[.nbuf:], , )
	.nbuf += 
	if .nbuf <  {
		return 0, .err
	}
Decode chunk into p, or d.out and then p if p is too small.
	var  int
	if .enc.padChar == NoPadding {
		 = .nbuf
	} else {
		 = .nbuf / 8 * 8
	}
	 := .enc.DecodedLen(.nbuf)

	if  > len() {
		, .end,  = .enc.decode(.outbuf[0:], .buf[0:])
		.out = .outbuf[0:]
		 = copy(, .out)
		.out = .out[:]
	} else {
		, .end,  = .enc.decode(, .buf[0:])
	}
	.nbuf -= 
	for  := 0;  < .nbuf; ++ {
		.buf[] = .buf[+]
	}

	if  != nil && (.err == nil || .err == io.EOF) {
		.err = 
	}

We cannot return all the decoded bytes to the caller in this invocation of Read, so we return a nil error to ensure that Read will be called again. The error stored in d.err, if any, will be returned with the last set of decoded bytes.
		return , nil
	}

	return , .err
}

type newlineFilteringReader struct {
	wrapped io.Reader
}
stripNewlines removes newline characters and returns the number of non-newline characters copied to dst.
func (,  []byte) int {
	 := 0
	for ,  := range  {
		if  == '\r' ||  == '\n' {
			continue
		}
		[] = 
		++
	}
	return 
}

func ( *newlineFilteringReader) ( []byte) (int, error) {
	,  := .wrapped.Read()
	for  > 0 {
		 := [0:]
		 := stripNewlines(, )
		if  != nil ||  > 0 {
			return , 
Previous buffer entirely whitespace, read again
		,  = .wrapped.Read()
	}
	return , 
}
NewDecoder constructs a new base32 stream decoder.
func ( *Encoding,  io.Reader) io.Reader {
	return &decoder{enc: , r: &newlineFilteringReader{}}
}
DecodedLen returns the maximum length in bytes of the decoded data corresponding to n bytes of base32-encoded data.
func ( *Encoding) ( int) int {
	if .padChar == NoPadding {
		return  * 5 / 8
	}

	return  / 8 * 5