2017-05-03 209 views

回答

4

的错误是:

panic: runtime error: index out of range 

goroutine 1 [running]: 
encoding/base64.(*Encoding).Encode(0xc420056000, 0x0, 0x0, 0x0, 0xc42003bf30, 0xe, 0x20) 
     /usr/lib/go/src/encoding/base64/base64.go:113 +0x27b 
main.main() 
     /home/martin/a.go:11 +0x9b 
exit status 2 

shell returned 1 

如果我们看一下/usr/lib/go/src/encoding/base64/base64.go线113,我们看到(略):

n := (len(src)/3) * 3 
for si < n { 
    // [..] 
    dst[di+0] = enc.encode[val>>18&0x3F] 
    dst[di+0] = enc.encode[val>>18&0x3F] 
    dst[di+1] = enc.encode[val>>12&0x3F] 
    // [..] 
} 

换句话说,这个功能直接将索引设置dstvar encodedData []byte的长度为零,因此您会收到index out of range错误。

一个解决它的方法是将行更改为:

encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(data))) 

这将使得大小的数组中的第二个参数。 Base64编码的数据比输入大,因此base64.StdEncoding.EncodedLen()

但是,这并不是解决问题的最佳方法。 The documentation提及:

编码不适用于大数据流的各个块。改用NewEncoder()。

重写代码以NewEncoder()看起来像:

func main() { 
    data := []byte("string of data") 

    encodedData := &bytes.Buffer{} 
    encoder := base64.NewEncoder(base64.StdEncoding, encodedData) 
    defer encoder.Close() 
    encoder.Write(data) 

    fmt.Println(encodedData) 
} 

还有一些其他有用的功能,诸如EncodeToString()这使得上述一点更短和更方便的:encodedData := base64.StdEncoding.EncodeToString(data)

+0

感谢您的深入解答!那么编码数据将如何被解码? – jsc

+1

我相信你可以找到这个问题的答案[在文档中](https://golang.org/pkg/encoding/base64/)@jscionti :-) – Carpetsmoker

4

分配空间为输出。例如,

package main 

import (
    "encoding/base64" 
    "fmt" 
) 

func main() { 
    data := []byte("string of data") 
    encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(data))) 
    base64.StdEncoding.Encode(encodedData, data) 
    fmt.Println(encodedData) 
} 

输出:

[99 51 82 121 97 87 53 110 73 71 57 109 73 71 82 104 100 71 69 61] 

var encodedData []byte是零个字节。因此,index out of range

1

因为Encode预计dst切片被分配到正确的长度。

编码使用编码enc编码src,将 EncodedLen(len(src))字节写入dst。

相关问题