Shogo's Blog

Apr 23, 2023 - 4 minute read - go

RE: Akamai x UNIQLOコラボTシャツに書かれたプログラムを解読してみる

CDNサービスで有名なAkamaiがユニクロとコラボしてTシャツを作りました。

完全に二番煎じですが、Tシャツに描かれたコードを解読してみます。

解読してみる

Tシャツに描かれたこのコード、PEACE FOR ALLに参画するために作られたのではなく、企業ブランドの一部として作られたもののようです。 Akamaiのウェブページをよく見てみると、背景にも同じコードが使われています。

コードの文脈をまったく意識せず切り貼りしたため、Tシャツのデザインでは失われてしまった部分があります(内容を理解できる人間にとってはちょっと残念)。 しかし、営業資料っぽいPDFに同じコードが利用されており、ここからなら十分に復元可能です。

行ごとに分割して、同じ文字列が出現する箇所をつなぎ合わせると、以下のようなコードが浮かび上がります。

package main; import ( "fmt"; "html"; "log"; "net/http"; "strconv"; "strings"; "time" ); type ControlMessage struct { Target string; Count int64; }; func main() { controlChannel := make(chan ControlMessage);workerCompleteChan := make(chan bool); statusPollChannel := make(chan chan bool); workerActive := false;go admin(controlChannel, statusPollChannel); for { select { case respChan := <- statusPollChannel: respChan <- workerActive; case msg := <-controlChannel: workerActive = true; go doStuff(msg, workerCompleteChan); case status := <- workerCompleteChan: workerActive = status; }}}; func admin(cc chan ControlMessage, statusPollChannel chan chan bool) {http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) { hostTokens := strings.Split(r.Host, ":"); r.ParseForm(); count, err := strconv.ParseInt(r.FormValue("count"), 10, 64); if err != nil { fmt.Fprintf(w, err.Error()); return; }; msg := ControlMessage{Target: r.FormValue("target"), Count: count}; cc <- msg; fmt.Fprintf(w, "Control message issued for Target %s, count %d", html.EscapeString(r.FormValue("target")), count); }); http.HandleFunc("/status",func(w http.ResponseWriter, r *http.Request) { reqChan := make(chan bool); statusPollChannel <- reqChan;timeout := time.After(time.Second); select { case result := <- reqChan: if result { fmt.Fprint(w, "ACTIVE"); } else { fmt.Fprint(w, "INACTIVE"); }; return; case <- timeout: fmt.Fprint(w, "TIMEOUT");}}); log.Fatal(http.ListenAndServe(":1337", nil)); };

Goにしてはセミコロン(;)がたくさんあるのは、おそらくコードを一行にまとめるためでしょう。 本来各ステートメントはセミコロンで区切る必要がありますが、自動的にセミコロンを補完してくれる仕様があります。

普段見るGoのコードでセミコロンが少ないのは、この仕様のおかげでセミコロンを省略できているからです。 The code textureのようにセミコロンを省略せずに書くこともできます。

整形してみる

省略可能なセミコロンを明示的に書いているだけで、The code textureのコードは文法としては有効です。 実際 go fmt で整形できます。

package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type ControlMessage struct {
	Target string
	Count  int64
}

func main() {
	controlChannel := make(chan ControlMessage)
	workerCompleteChan := make(chan bool)
	statusPollChannel := make(chan chan bool)
	workerActive := false
	go admin(controlChannel, statusPollChannel)
	for {
		select {
		case respChan := <-statusPollChannel:
			respChan <- workerActive
		case msg := <-controlChannel:
			workerActive = true
			go doStuff(msg, workerCompleteChan)
		case status := <-workerCompleteChan:
			workerActive = status
		}
	}
}
func admin(cc chan ControlMessage, statusPollChannel chan chan bool) {
	http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
		hostTokens := strings.Split(r.Host, ":")
		r.ParseForm()
		count, err := strconv.ParseInt(r.FormValue("count"), 10, 64)
		if err != nil {
			fmt.Fprintf(w, err.Error())
			return
		}
		msg := ControlMessage{Target: r.FormValue("target"), Count: count}
		cc <- msg
		fmt.Fprintf(w, "Control message issued for Target %s, count %d", html.EscapeString(r.FormValue("target")), count)
	})
	http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
		reqChan := make(chan bool)
		statusPollChannel <- reqChan
		timeout := time.After(time.Second)
		select {
		case result := <-reqChan:
			if result {
				fmt.Fprint(w, "ACTIVE")
			} else {
				fmt.Fprint(w, "INACTIVE")
			}
			return
		case <-timeout:
			fmt.Fprint(w, "TIMEOUT")
		}
	})
	log.Fatal(http.ListenAndServe(":1337", nil))
}

コンパイルしてみる

しかし残念なことにコンパイルは通りません。 以下のようなエラーが出ます。

% go run main.go
# command-line-arguments
./main.go:30:7: undefined: doStuff
./main.go:38:3: hostTokens declared and not used

コンパイルが通るように最低限を変更を加えます。

@@ -36,6 +36,7 @@
 func admin(cc chan ControlMessage, statusPollChannel chan chan bool) {
 	http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
 		hostTokens := strings.Split(r.Host, ":")
+		_ = hostTokens // hostTokensは使われていないが、コンパイルエラーにならないようにするために代入している
 		r.ParseForm()
 		count, err := strconv.ParseInt(r.FormValue("count"), 10, 64)
 		if err != nil {
@@ -64,3 +65,8 @@
 	})
 	log.Fatal(http.ListenAndServe(":1337", nil))
 }
+
+// doStuffが未定義なので追加
+func doStuff(msg ControlMessage, workerCompleteChan chan bool) {
+	log.Println("Target:", msg.Target, "Count:", msg.Count)
+}

できあがったコードはこちら。

package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type ControlMessage struct {
	Target string
	Count  int64
}

func main() {
	controlChannel := make(chan ControlMessage)
	workerCompleteChan := make(chan bool)
	statusPollChannel := make(chan chan bool)
	workerActive := false
	go admin(controlChannel, statusPollChannel)
	for {
		select {
		case respChan := <-statusPollChannel:
			respChan <- workerActive
		case msg := <-controlChannel:
			workerActive = true
			go doStuff(msg, workerCompleteChan)
		case status := <-workerCompleteChan:
			workerActive = status
		}
	}
}
func admin(cc chan ControlMessage, statusPollChannel chan chan bool) {
	http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
		hostTokens := strings.Split(r.Host, ":")
		_ = hostTokens // hostTokensは使われていないが、コンパイルエラーにならないようにするために代入している
		r.ParseForm()
		count, err := strconv.ParseInt(r.FormValue("count"), 10, 64)
		if err != nil {
			fmt.Fprintf(w, err.Error())
			return
		}
		msg := ControlMessage{Target: r.FormValue("target"), Count: count}
		cc <- msg
		fmt.Fprintf(w, "Control message issued for Target %s, count %d", html.EscapeString(r.FormValue("target")), count)
	})
	http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
		reqChan := make(chan bool)
		statusPollChannel <- reqChan
		timeout := time.After(time.Second)
		select {
		case result := <-reqChan:
			if result {
				fmt.Fprint(w, "ACTIVE")
			} else {
				fmt.Fprint(w, "INACTIVE")
			}
			return
		case <-timeout:
			fmt.Fprint(w, "TIMEOUT")
		}
	})
	log.Fatal(http.ListenAndServe(":1337", nil))
}

// doStuffが未定義なので追加
func doStuff(msg ControlMessage, workerCompleteChan chan bool) {
	log.Println("Target:", msg.Target, "Count:", msg.Count)
}

ここまで来れば実行する事もできます。 /adminにリクエストを投げると、バックグランドで処理を実行。 /statusで処理の状況確認です。

% go run main.go
% curl -d count=10 -d target=hoge http://localhost:1337/admin
Control message issued for Target hoge, count 10
% curl http://localhost:1337/status
ACTIVE

The code texture

このコードについて調べてみたら、利用ガイドラインがありました。

リリース文だけ読んで「“texture"という名前のコード」かと思ってましたが、ガイドラインを読むと「“The code texture"という名前の画像」みたいですね。 「The code texture」=「Akamaiが指定したコードを、Akamaiが指定したフォントで、Akamaiが指定した色を使って、レンダリングした結果の画像」というわけです。

PEACE FOR ALL

コードの色の変わっている部分については、紹介動画でバッチリ言ってました。

And on the front, you see some code. And this is actual code that is taken from some of our solutions to defend against attackers. And you see we’ve highlighted some of the letters in the code that spell peace for all.

全面にはコードが描かれています。 攻撃者から守るために当社の製品で実際に使われているコードを引用しました。 peace for allを表すいくつかの文字をハイライトしました。

まとめ

  • Akamai x UNIQLOコラボTシャツに書かれたプログラムを解読してみました
  • このコラボのために作られたコードではなく、もともとAkamaiがブランドイメージに使っていた画像

Gopherのひとりとしては、Tシャツにデザインされる過程で、不完全なコードになってしまったのが残念ですね。 せっかくならコンパイルできてほしかった。

参考