2 ポイント 投稿者 GN⁺ 5 시간 전 | 1件のコメント | WhatsAppで共有
  • Uniqlo店舗で販売されたAkamaiデザインのTシャツには、base64 --decodeの結果をevalで実行する難読化されたbashコードが印刷されていたが、実際にはPeace for Allキャンペーン向けのイースターエッグだった
  • Base64でエンコードされたHere stringを展開すると、ターミナルで♥PEACE♥FOR♥ALL♥の文言をサイン波アニメーションで繰り返し表示するスクリプトが現れる
  • Base64には誤り訂正がないため転記が難しく、文字列のパディングや引用符・波括弧が合っているかを確認したうえで、Android OCR、Tesseract、Claudeの結果を比較して整理した
  • デコードされたスクリプトはtputbc、256色ANSIエスケープを組み合わせ、ターミナルサイズごとの文字位置と色を計算し、CTRL+Cで終了するとカーソルを復元する
  • Akamaiは背面の実際のコードをLinuxへの参照として説明しており、フォントは当初推定されたConsolasではなくRoboto Monoに訂正された

Tシャツ背面の実行可能なコード

  • Uniqlo x AkamaiのPeace for AllTシャツの前面には波括弧の中のハートがあり、背面には大きな英数字ブロックが印刷されている
  • 近くで見ると、そのブロックはshebangで始まるbashコードで、Base64エンコードされたHere stringをbase64 --decodeで展開してevalに渡す構造になっている
  • 見た目には「ウイルス配布の手法」のように見えるかもしれないが、実際の目的はイースターエッグのメッセージを表示することだった
  • このTシャツは、AkamaiがUnqiloのPeace for All campaignを支援してデザインした製品である

OCRと転記の過程

  • Base64には誤り訂正機能がないため、印刷された文字列を実行可能な形へ移すには完全な転記が必要だった
  • 文字列は想定されるパディングで終わっており、引用符や波括弧も対応していたため、完全なコードである可能性が高かった
  • 転記には3つの方法を併用した
    • Androidのcircle-to-search内蔵OCR
    • Tesseractといくつかのオプションおよび調整
    • ClaudeによるOCRと位置表の作成
  • 3つの結果をdiffで比較して不一致箇所を見つけ、残りの部分は手作業で整理した
  • 同じUniqlo x Akamaiラインの別のTシャツデザインは、より広いコードブロックから切り取られたようで、importsが途中で切れ、returnretuで終わっていてコンパイル不能な状態だった

デコードされたbashスクリプトの動作

  • Base64をデコードすると、コメントが丁寧に付けられたbashイースターエッグが現れる
  • スクリプト冒頭には英語と日本語の祝福メッセージが含まれている
    • Congratulations! You found the easter egg! ❤️
    • おめでとうございます!隠されたサプライズを見つけました!❤️
  • アニメーション対象の文字列は♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL...という形で繰り返される
  • ターミナルサイズはtput colstput linesで取得し、文字列長はbashの${#text}で計算する
  • カーソルはtput civisで隠し、SIGINTを受けるとtput cnorm; exitで元に戻す

アニメーションの実装方法

  • ループはfor (( t=0; ; t+=1 ))形式の無限ループとして動き続ける
  • 各反復で、現在出力する文字をtextから1文字ずつ取り出す
  • 位置計算はbc -lでサイン値を求めて処理する
    • angle = t * 0.2
    • sine_value = s(angle)
    • x = (cols / 2) + (cols / 4) * sine_value
  • 計算されたxはターミナル範囲を外れないよう、0以上cols - 1以下に補正される
  • 色は256色パレットでcyanに相当する12とorangeに相当する208の間のグラデーションとして計算される
  • 出力はANSIエスケープとtput cupを使って指定位置に色付き文字を描き、改行で下へ進む方式になっている
  • その結果、Peace for Allキャンペーンのメッセージがターミナル上で連続するサイン波ループとして現れる

フォントとAkamaiのデザイン説明

  • フォントについての当初の推定はConsolasだったが、Hacker Newsユーザーralphinusの確認を受けてRoboto Monoに訂正された
  • 誤った推定の根拠としては、浅く斜線が入った0、セリフのない1BDygや数字2の丸い曲線などが挙げられていた
  • AkamaiはTシャツ発売時のプレスリリースを通じてデザインメッセージを説明している
  • 明るい黄褐色は初期インターネット時代のコンピューターの「beige box」プラスチック筐体を指し、前面のハートはインターネットが世界中で善い目的に使われてきたことを表している
  • 背面の実際のコードはLinuxへの参照であり、Akamaiはこれを「インターネットのオープンソース言語」であり、より安全でつながった世界へ向かう共通言語だと位置づけている
  • 同じTシャツに関心を持った別の事例としてWen Chuan Leeの記事があり、その記事はさらに別の関連投稿へとつながっている

1件のコメント

 
GN⁺ 5 시간 전
Hacker Newsのコメント
  • 「Uniqlo x Akamaiが同じラインで売っている別のシャツは、コードが明らかに未完成のデザインになっている」
    シャツが不具合を起こして返品しなければならないと想像すると笑える
    「なぜ返品されるのですか、サイズが合わなかったのですか、それともお気に召しませんでしたか?」
    「いえ、37行目に構文エラーがあって実行できないんです。それに、街の人たちに私が危険なBashスクリプトを書いていると宣伝していると思われそうで心配でして」

    • Uniqloのカスタマーサポート担当者向けに言うと、印刷されたコンピューターコードのエラーを理由にシャツを返品しようとする人がいたら断って、「本物のスクリプトキディなら、買う前にそのエラーに気づいていたはずです」と返せばいい
    • 品質保証がここまで足りないなんて、まさにshell-shocked状態だ。せめてパッチくらい当ててくれないか?
  • こういうものが好きなら、Martin Kleppeの作品も気に入るかもしれない。たとえばQuine Clockがある
    https://aem1k.com/qlock/
    数年前に、難読化されていない形にリバースエンジニアリングしたものもある
    https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
    そのほかにも素晴らしいASCIIビジュアライゼーションをたくさん作っている
    https://aem1k.com/

    • あれは本当にQuineなのか?
      とても印象的ではあるけれど、それでも
  • フォントはConsolasではなくRoboto Mono
    もっと奇妙なのは、フォント自体はちゃんとした等幅フォントなのに、シャツの組版はそうなっていないことだ。カーニングが入っていて、特に「Iy」の組み合わせで目立つし、「i」のような細い文字は横幅をあまり取っていないように見える。推測するに、InDesignの「optical kerning」のようなツールで組版したのだろう

    • 動的カーニング付きの等幅フォントを作った人はいるのだろうか? 上のコメントを読むまで考えたこともなかった、ちょっと突飛なアイデアだ。最初は筋が通らないように聞こえるが、少し聞いてほしい
      等幅フォントを使う理由は、グリッドにきれいに収まるからだ。でもそのグリッドの中でも文字を少し左や右に動かす余地はあるし、そうすればもっと読みやすい等幅フォントになるかもしれない。もちろん、文字が左に寄るたびに右側の空きが大きくなって、ひどい結果になる可能性も同じくらい高い
    • その通りだと思う。記事に訂正を追加し、このコメントも引用した
  • このシャツは本当に良い。実際のデザイナーが制作過程を説明している良い動画がある。意図的にOCRしにくくした工程も含まれている: https://youtu.be/jocGLiecpjU?t=526

    • OCRの方法を探すより、ただ自分で打ち込んだほうが速いかもしれない。45年前にCOMPUTE!誌でゲームコードを書き写していた感覚になりそうだ
      https://archive.org/details/1983-01-compute-magazine/page/96...
    • 筆者です。見たことのなかったリンクで、本当にありがとう。これを見られてうれしいし、OCRが難しかったのが自分だけの問題ではなく、意図された設計だったと分かったのもうれしい
    • リンクを見たが、OCRしにくくしたと言っている箇所が見つからなかった。具体的に何をしてOCRが難しくなったのだろう?
    • でもOCRは難しくない。なぜ記事がその部分にセクションひとつ丸ごと割いているのか分からない
      Samsung S24Uでホーム画面の「circle to search」ボタンを長押ししてAIツールのインターフェースを出し、テキストを長押しして一度に全部コピーした。正式名称は分からないが、2秒くらいだった
  • これをOCRするのは悪夢で、自分を優秀なOCR/ビジョンモデルだと主張するものにとって良いベンチマークになる
    ただ、最新のClaudeやGPTのような優れたビジョンモデルを組み込んだエージェント型ツールに画像を渡して、行ごとに分割し、各行を別々にOCRさせればかなり簡単にいけそうだ
    難読化前のこのスクリプト自体がLLMで書かれたのかも気になる。コメントがかなり多そうだし、この場合はそれでも別に構わない :)

    • LLMが書いたようには見えない。いくつか気になる点がある
      祝福メッセージが英語と日本語の両方で入っていて、ハートの絵文字も1つある。青緑からオレンジへ移るグラデーションにしたかった意図はあったようだが、その範囲はANSIブロックで始まり、256色ブロックの途中で終わっており、256色のターミナルカラーはそもそもグラデーション状に並んでいない。それにループの終わりにsleepがないが、LLMなら防御的に追加していそうだ
    • そこまで難しくない。うちの産業用OCRモデルはデフォルトパラメータで最初の試行から正確に読めた
      文字は簡単に分離できるし、読取器を混乱させるような構造的背景もない。たとえばヨーグルトのアルミ蓋に印字された賞味期限のようなものとは違う。結果を乱すような、ほとんど文字に見えるテクスチャもないし、フォントもきれいで標準的だ
    • インターネットの人たちが最後にbase64のOCRに執着していたのは数か月前だった。DoJがある故人のメールを大量公開したが、それがラスタライズされたPDFで出されたときだ
      今は名前を思い出せない。このところ気を散らすものが多すぎた
    • Safariの画像からテキストをコピーする機能は、文字列のbase64部分をほぼ丸ごと処理できる。最初の文字だけTではなくIと誤認した
      不思議なことに、hashbang部分まで含めて全文字列をコピーしようとすると、ずっと精度が悪くなる。内部で何をしていて、どうしてこんなにうまくいくのか気になる
    • 本当に悪夢なのか? シャツの最初のサムネイル画像をChatGPTに貼り付けたら、一発で解読して、Bashスクリプトが何をするのかまで教えてくれた
  • base64エンコードを難読化と呼ぶのか
    いけてるJS逆難読化テクニックを期待していたのに、よく言っても言葉にできないほどがっかりで、一日が台無しになった

  • うわ、店であのTシャツを見たとき、彼女に「このスクリプトが実際に動くはずない、ただの飾りだろう」と言っていた。もっと深掘りすべきだった

    • 見落としやすい。たいていの時間、私たちは落ち着いておらず、思考がオートパイロット状態になっている
  • いいね。スクリプトについて唯一惜しいと思ったのは、ループの中に
    sleep 0.1
    を入れておけばよかったかも、という点。そうすれば端末に出力されたときに実際に読める。最近の端末はスクロールが速すぎて、メッセージが流れていく様子を見られない
    10Hz更新 くらいまで遅くするとかなり見やすい

    • じゃあそこに パッチ を縫い込めるかもしれない?
  • 投稿者がいろいろなOCRツールを試して結果がばらついたあと、いちばん良かった出力を延々と手作業で直している様子が面白かった。最初から自分で打ち込めばいいのに、と思った

    • 自分も同じことを思った。でも自分は、雑誌や本に載っていた「ゲーム」を何時間もかけて ラバーキーボード で打ち写して育った世代なんだよね。そのあとでタイプミスを直すのにさらに何時間もかかったし
    • PaddlePaddle OCRにかけたら完璧に処理できた
      スマホのGoogle Lensで使うGoogle OCRもかなりうまく抽出できたけど、100%正確ではなかった。それでも手で打ち写すより、修正にかかる時間のほうがずっと少なかったはず。投稿者が何を使ったのかは分からないけど、OCRの試行結果を共有してくれたらよかったのにと思う。たぶんシンプルなOCRツールを試したんじゃないかな
    • 4行入力するのにほぼ2分かかって、そのうち1文字を見落としていた
      自分でも当然OCRを選ぶと思う。次に Bash Tシャツ に遭遇したときに備えないといけないから
    • 企業環境での作業自動化の現実を思い出す。初級者なら10分で手作業でできて、しかも週1回しか必要ない作業を自動化するために、エンジニアが40時間以上使うことがよくある。とにかく自動化 が未来なんだろうね
    • 「ただ打ち込むだけ」だと、平均的な人にとってはむしろミスが増える可能性が高い
  • 昔の同僚が Goプログラム の入ったシャツを持っていて、いつもかなりかっこいいと思っていた
    [0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code

    • Goのソルバープログラムのことを言っているのか、Go言語のことを言っているのか確信が持てなかった。誰かが GoでGoプログラム を作ったら面白そう
    • 今年、Goコード入りのものを1枚買った。まったく実際のコードだとは思わなくて、ただのランダムな内容だと思っていた