とあるプロジェクトの技術支援に入っているのですが、API リクエスト/レスポンスの送受信内容(UTF-8)のログが、すべてバイト列を hex-encoded されたものになっているようなシステムになっております。 人類は長い歴史を無為に生きてきたため、hex-encoded されたバイト列を頭の中で UTF-8 にエンコードできるほど進化しておりません。なんとかしないといけない。
そういうわけなので、なんとかして UTF-8 のバイト列が hex-encoded された文字列をプレインテキストに戻してやるツールが必要になります。 それでいて、開発は Windows でなされているので、ツールは Windows で動かないといけない。
おやおや、これは Go で書けば良いんじゃねーかと思いまして、初めて Go でプログラムを書いてみました。
こんなかんじで、hex-encoded された文字列を標準入力に食わせると、標準出力に結果を出力する。
$ cat hello e38193e38293e381abe381a1e381af e38193e38293e381abe381a1e381af $ cat hello | ~/bin/hexstr こんにちは こんにちは
でも、自宅に Windows 環境ないし Windows で標準入力に投入するテストしにくかったのと、オプション解析を Go でどうやるのか試したかったので、オプション引数でファイル指定にも対応する実験をしてみた。
$ ~/bin/hexstr -i hello
こんにちは
こんにちは
Go の標準ライブラリが結構充実していたので、あんまし大した実装しなくて良い。 以下がだいたいの処理なんだけど、ファイル開いて hex-encoded の文字列を取り出して、それをデコードしてから utf-8 の文字列として出力するだけ。
func run(args []string) int { var scanner *bufio.Scanner var filename = flag.String("i", "", "file path which includes hex-encoded lines") flag.Parse() if *filename == "" { scanner = bufio.NewScanner(os.Stdin) } else { file, err := os.Open(*filename) if err != nil { fmt.Fprintf(os.Stderr, "file open error: %s\n", err) return ExitCodeOpenFileError } defer file.Close() scanner = bufio.NewScanner(file) } for scanner.Scan() { var hexString = scanner.Text() var decoded, err = hex.DecodeString(hexString) if err != nil { fmt.Fprintf(os.Stderr, "failed to decode \"%s\": %s\n", hexString, err) return ExitCodeInputError } fmt.Println(string(decoded)) } if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "scanner error: %s\n", err) return ExitCodeInputError } return ExitCodeOK }
むしろつらかったのはツールチェーン系で、クロスコンパイルを楽にするための gox とか、いろいろあるのだなぁという学習コストそれなりにあったし、今後もありそう。まぁこのあたりの学習コストはどの言語でも必要なので、慣れるしかない。
l