Я попытался в цикле for повторно объявить/назначить декодер base64 и использовать функцию os.Seek, чтобы вернуться к началу файла в конце цикла до этого, чтобы вызываемая функция ( в этом тестовом примере PrintBytes), чтобы иметь возможность обрабатывать файл от начала до конца снова и снова в цикле for.
Вот мой (я уверен, ужасно неидиоматический) код, который не может прочитать 2-й байт в [] байт длины 2 и емкости 2 во время второй итерации основного цикла for в main():
package main
import (
"encoding/base64"
"io"
"log"
"net/http"
"os"
)
var (
remote_file string = "http://cryptopals.com/static/challenge-data/6.txt"
local_file string = "secrets_01_06.txt"
)
func main() {
f, err := os.Open(local_file)
if err != nil {
DownloadFile(local_file, remote_file)
f, err = os.Open(local_file)
if err != nil {
log.Fatal(err)
}
}
defer f.Close()
for blocksize := 1; blocksize <= 5; blocksize++ {
decoder := base64.NewDecoder(base64.StdEncoding, f)
PrintBytes(decoder, blocksize)
_, err := f.Seek(0, 0)
if err != nil {
log.Fatal(err)
}
}
}
func PrintBytes(reader io.Reader, blocksize int) {
block := make([]byte, blocksize)
for {
n, err := reader.Read(block)
if err != nil && err != io.EOF {
log.Fatal(err)
}
if n != blocksize {
log.Printf("n=%d\tblocksize=%d\tbreaking...", n, blocksize)
break
}
log.Printf("%x\tblocksize=%d", block, blocksize)
}
}
func DownloadFile(local string, url string) {
f, err := os.Create(local)
if err != nil {
log.Fatal(err)
}
defer f.Close()
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
_, err = io.Copy(f, resp.Body)
if err != nil {
log.Fatal(err)
}
}
Вывод этого кода можно посмотреть здесь https://gist.github.com/tomatopeel/b8e2f04179c7613e2a8c8973a72ec085 а>
Я не понимаю именно этого поведения: https://gist.github.com/tomatopeel/b8e2f04179c7613e2a8c8973a72ec085#file-bad_reader_log-L5758
Я ожидал, что он просто прочитает файл по 2 байта за раз в 2-байтовый срез, от начала до конца. По какой причине здесь читается только 1 байт?
Seek
ing базового считывателя между чтениями из считывателя base64 может иметь непредсказуемые результаты. - person Adrian   schedule 30.05.2017asBytes, err := ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, f))
и приступайте к работе с данными asBytes. (т.е.: расчет расстояния между длинами блоков и т. д.) - person Rob   schedule 30.05.2017