LoginSignup
2
0

A Tour of GoでExercise: rot13Readerをやってみた

Posted at

Goの学習でA Tour of Goをさらっています。
Methods and interfacesの章でExercise: rot13Readerをやったのでメモです。

解答

やったこと

やったことは下記です

  1. 状況把握
  2. Readメソッドの返り値とReadメソッド中で変換するための文字列を取得する
  3. Readメソッド内でROT13の処理をする

1. 状況把握

"Lbh penpxrq gur pbqr!"をROT13という変換方法を利用して文字列変換したものを出力する。
初期状態として下記が与えられている。このまま実行するとrot13Readerにio.Reader(Readメソッド)がないと言われます。

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r) // ここで標準出力するためにrot13ReaderにReadメソッドを追加する
}

2. Readメソッドの返り値とReadメソッド中で変換するための文字列を取得する

返り値の文字数、errorは、rot13Readerの構造体中のio.ReaderのReadメソッドの返り値をそのまま利用すればいい。
また、rot13Readerの構造体中のio.ReaderのReadメソッドを呼び出した際に、byte配列bにLbh penpxrq gur pbqr!を入れてくれている。

func (r rot13Reader) Read(b []byte) (int, error) {
	n, err := r.r.Read(b) // ここで、rot13Readerの構造体中のio.Readerを利用し、返り値と文字列をゲットする
	if err != nil {
		return n, err // n, errをそのまま返せる
	}
     ...
	return n, nil // nをそのまま返せる
}

3. Readメソッド内でROT13の処理をする

やり方は色々あると思いますが、
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklmに変換できればok

大文字と小文字に分けて13個ローテーションさせました。

func (r rot13Reader) Read(b []byte) (int, error) {
	n, err := r.r.Read(b)
	if err != nil {
		return n, err
	}

    // bに入れていく
	for i := 0; i < len(b); i++ {
		if b[i] >= 'A' && b[i] <= 'Z' {
			b[i] = (b[i]-'A'+13)%26 + 'A' // 大文字の場合、13個ローテーションする
		} else if b[i] >= 'a' && b[i] <= 'z' {
			b[i] = (b[i]-'a'+13)%26 + 'a'  // 小文字の場合、13個ローテーションする
		}
	}

	return n, nil
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0