blog.fetus.jp

Staaaay Fresh!

stat.ink: Modernizing the Codebase

English follows Japanese.

最近、AI を活用して stat.ink のシステムを更新しています。

stat.ink のソースコードには 10 年以上の歴史があり、古い書き方や、当時の事情に合わせて設計された構造が数多く残っています。

現在、こうしたコードを近代化するとともに、静的解析を活用してコードの品質を向上させる作業を進めています。目指しているのは、意図しないエラーや、潜在的な不具合が発生しにくいコードにすることです。

今回の作業では、非常に多くのソースコードを書き換えています。通常の利用で動作が変わらないよう注意して進めていますが、変更範囲が広いため、あらゆる利用状況で問題がないことまでは確認できていません。

また、作業を進める中で、何年も前から存在していた潜在的な問題が AI によって発見され、修正されたケースもあります。その結果、これまでエラーが発生していた機能が、正常に動作するようになっている場合もあります。

もし不自然な動作やエラーに気づいたら、ぜひお知らせください。

連絡には Discord をおすすめしますが、GitHub の Issue や、このブログのコメントでも構いません。どのページで、どのような操作をしたときに、何が起きたのかを具体的に書いていただけると、原因の調査がスムーズになります。

I’ve recently been using AI to help update the stat.ink system.
Oh wait, I’m supposed to call it “SI” now, aren’t I? Super Intelligence. Heh.

The stat.ink codebase has more than 10 years of history, and much of it still reflects old coding styles and the circumstances of its time.
I’m now modernizing it and using static analysis to improve code quality.
The goal is a structure where unintended errors and latent bugs are less likely to occur.

This work involves rewriting a very large amount of code.
I’m being careful not to change behavior in normal use, but because of the sheer volume of changes, I haven’t been able to confirm that everything works in every real-world use case.

Along the way, the AI has also found and fixed latent problems that had existed for years.
As a result, some features that used to fail with an error may now work correctly.

If you notice anything strange or run into an error, please let me know.
Discord is preferred, but GitHub issues or comments on this blog are fine too.
It helps a lot if you can include which page you were on, what you did, and what happened.

stat.ink: Sign Up Without a Password

English follows Japanese.

数日前より、stat.ink でパスキーのみで会員登録ができるようになりました。

4月にパスキーを導入した時点では、パスワードを設定せずに会員登録することはできませんでした。
先日のリリースでパスワードを無効にできるようになりましたが、その場合も、登録時には一度パスワードを設定する必要がありました。

今回の変更により、最初からパスワードを設定せず、パスキーだけで会員登録できるようになりました。

これまでどおり、パスワードでログインしたい方は、パスワードを設定して登録することもできます。
また、パスキーのみで登録したあとから、パスワードを追加することも可能です。
その場合は、プロフィールページからパスキーで本人確認を行い、設定してください。

なお、パスキーのみで登録したアカウントは、パスワードを無効にしたアカウントと同じ扱いになります。

パスワードが設定されていない間は、最後に残ったパスキーを削除することはできず、API キーを使ったパスワードの再設定もできません。

すべてのパスキーを失ってしまうと、リカバリキーがない限りログインできなくなります。
会員登録が完了したら、忘れずにリカバリキーを作成し、安全な場所に保管しておいてください。

As of a few days ago, you can sign up for stat.ink with only a passkey.

When I added passkey support in April, you couldn’t create an account without a password.
The recent release let you disable your password, but you still had to set one when you first signed up.
With this change, you can sign up without a password from the start.

If you prefer to log in with a password, you can still set one when you sign up, just as before.
You can also add a password later, even if you signed up with only a passkey.
Just open your profile page, verify with your passkey, and set your password.

Note that an account created with only a passkey is treated the same as an account with its password disabled.
While you have no password, you cannot delete your last remaining passkey, and you cannot reset your password with your API key.
If you lose all your passkeys, you will no longer be able to log in unless you have a recovery key.
Don’t forget to create recovery keys once you’ve signed up.

stat.ink: Disable Your Password

English follows Japanese.

パスワードを削除できるようになりました

パスキーを登録しているユーザーは、パスワードを削除してパスキーだけでログインする設定ができるようになりました。

プロフィールページから「パスワードを無効にする」を選び、パスキーで本人確認をすると、パスワードはサーバーから消去されます。それ以降のログインはパスキーだけになります。

セキュリティ上のメリット

パスワードがあると、パスキーを設定していても、パスワードを知っている人ならログインできてしまいます。他のサービスで漏れたパスワードを使い回していた場合や、フィッシングサイトにパスワードを入力してしまった場合が、その典型です。

パスワードを削除すると、ログインの手段がパスキーだけになります。パスキーはお使いの端末に保存され、正規の stat.ink 以外では使えません。そのため、パスワードの漏洩、使い回し、フィッシングによる不正ログインを根本から防げます。また、サーバーにパスワードの情報が残らないので、万一の情報漏洩でもパスワードが流出することはありません。

ご注意ください

  • パスワードを無効にしている間は、最後の 1 つのパスキーを削除できません。
  • すべてのパスキーを失うと、リカバリキーがなければ新しいパスワードを設定できません。パスワードを無効にする前に、リカバリキーを作成しておくことを強くおすすめします。
    • パスワードを無効にしている間は、API キーを使ったパスワードの再設定はできません。
  • パスキーで本人確認をすれば、プロフィールページからいつでもパスワードを設定し直せます。

翻訳の改善

各言語の翻訳を見直しました。ゲーム内の公式用語に合わせ、足りなかった訳文を追加しています。

その他

  • Google パスワードマネージャなど、一部のパスキー管理ツールでパスキーを登録しようとするとエラーになり、登録できなかった問題を修正しました。

Sign in with passkeys only

If you have registered a passkey, you can now delete your password and sign in with your passkey only.

Open your profile page, choose “Disable Password”, and verify with your passkey. Your password is then erased from the server, and from then on you can sign in only with your passkey.

Why this is more secure

As long as your account has a password, anyone who knows it can sign in, even if you have also set up a passkey. This typically happens when you reuse a password that leaked from another service, or when you type your password into a phishing site.

When you delete your password, a passkey becomes the only way to sign in. Passkeys are stored on your device and cannot be used anywhere except the real stat.ink. This stops sign-ins that rely on leaked or reused passwords or on phishing. Also, no password data is kept on our server, so a data breach on our side cannot expose your password.

Before you disable your password

  • While your password is disabled, you cannot delete your last remaining passkey.
  • If you lose all your passkeys, you can set a new password only with a recovery key. We strongly recommend creating recovery keys before you disable your password.
    • While your password is disabled, you cannot reset it with your API key.
  • You can set a password again from your profile page at any time after verifying with your passkey.

Translation improvements

We reviewed the translations in each language, matched them to the official in-game terms, and added missing translations.

Other changes

  • Fixed an issue where registering a passkey failed with an error for some passkey providers, such as Google Password Manager.

stat.ink: Upgraded to PHP 8.5

Thank you for using stat.ink.

At around 18:45 JST on October 8, 2026 (09:45 UTC / 5:45 AM EDT / 2:45 AM PDT), I updated the systems that stat.ink runs on:

  • Upgraded to PHP 8.5
  • Restarted the server

If you accessed the site during the upgrade or restart and saw a Cloudflare error page, I apologize for the inconvenience.

Development has already been running on PHP 8.5, so I’m confident there shouldn’t be any issues.
That said, if you run into any errors or notice behavior that differs from before, please let me know via Discord or another channel.

stat.ink: Passkeys

日本語は英語の後にあります。

A few days ago, I added passkey support to stat.ink.
You can now log in more securely than with password-based login.
This method is expected to become one of the standard login methods going forward (you could even say it already has).

With passkeys, not only your password, but also your face recognition data and fingerprint data are never transmitted.
When using a passkey, you’ll be asked for your OS password or fingerprint authentication, but this is only used to access the passkey on your PC or smartphone — none of this information is transmitted to stat.ink or any other site you’re using.

In a typical environment, you should be able to use the passkey storage provided by your OS or browser.
If you’re more advanced, you might be using 1Password or Bitwarden. Or perhaps a hardware key (such as a YubiKey).
Any of these can be used, and with cloud sync, you may be able to use the same passkey across various devices.

Please give passkeys a try!
If you encounter an issue where you can register a passkey but can’t actually use it, please let me know. (YubiKey was in this state until early morning of April 27, 2026, Japan Time…)

P.S. Account registration without setting a password, as well as removing your password after setting up a passkey, are not yet supported.
I’ll decide whether to implement these based on the stability of the implementation and user demand.

—

数日前、stat.ink にパスキーサポートを追加しました。
パスワードによるログインよりも安全にログインすることができるようになりました。
この方法は、この先のスタンダードなログイン方法のひとつになる(既になっていると言えるかも)ものと思われます。

パスキーでは、パスワードはもちろん、あなたの顔認証情報、指紋認証情報は一切送信されません。
パスキーの利用時には OS のパスワードや指紋認証が求められますが、これはあなたの PC やスマートフォンでパスキーを利用するためのもので、stat.ink をはじめとする利用サイト側には一切送信されません。

一般的な環境であれば、OS やブラウザによるパスキー保管所が利用できるはずです。
エキスパートであれば、1Password や Bitwarden を利用しているかもしれません。ハードウェアキー(例えば YubiKey)かもしれませんね。
どれも利用でき、クラウド同期されて様々な端末で同じパスキーを利用かもしれません。

是非パスキーをご利用ください!
もし、登録はできたのに利用はできないという問題を見つけたら教えてください。(2026/4/27 未明 (日本時間) まで YubiKey がこの状態でした…)

追記:まだパスワードを設定しない会員登録や、パスキーを設定した後にパスワードを削除する操作には非対応です。
実装の安定性と需要を見て実装するかを決めていきます。

小学校1年生までに習う漢字で書ける駅名

Twitter (X) を眺めていると、こんなのが流れてきていました。

リプライでかなりの駅名が挙げられていますが、まあプログラマで片足鉄っちゃんに突っ込みかけている私としては自動でなんかやりたくなりますよね。
ということで、公開されているデータを集めて抽出してみます。

まず、抽出条件が曖昧なので、整理する必要があります。これはもはや定義なので、人によって含める含めないなどの派閥があると思います。受け入れてください。
別に受け入れなくてもいいですが、決めないと始まらないので。
一番論争になりそうなアルファベットに関してはもう受け入れない人はその駅をなかったことにしてくれればそれでいいです。

  • 「小学校1年生までにならう漢字」は、文部科学省のリストに従います。 https://www.mext.go.jp/a_menu/shotou/new-cs/youryou/syo/koku/001.htm 閲覧時点で「一 右 雨 円 王 音 下 火 花 貝 学 気 九 休 玉 金 空 月 犬 見 五 口 校 左 三 山 子 四 糸 字 耳 七 車 手 十 出 女 小 上 森 人 水 正 生 青 夕 石 赤 千 川 先 早 草 足 村 大 男 竹 中 虫 町 天 田 土 二 日 入 年 白 八 百 文 木 本 名 目 立 力 林 六(80字)」だそうです。
  • 「ひらがな」「カタカナ」「数字」は使用して良いとします。
  • 「アルファベット(ローマ字)」も使用して良いとします。
  • 「ヶ」「ヵ」はカタカナであるとみなします(「ヶ」=「个」という立場を取りません)。
  • 会社名や路線名はこの判定に利用しないものとします。

また、実装上の都合(めんどくさい)やデータソースの都合上、次のような制約があります。

  • 同名かつほぼ同じ地点にある駅をまとめていません。会社が同じであっても路線が違うものなど実質完全に同一の駅でも複数回掲載されているものがあります。
  • 駅名のデータは https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v2_3.html から令和2年のデータを取得して利用しています。
  • 令和2年(のある時点)以降に開業・廃止・改名等された駅は反映されていません。例えば、スカイレールサービスが掲載されています。
  • 会社名や路線名は上述のデータに掲載のものをそのまま掲載しています。一般に知られている名称と違う場合があります(例えば、「つくばエクスプレス線」が「首都圏新都市鉄道・常磐新線」となっています)

ということで抽出したリストいきましょう。 続きを読む: 小学校1年生までに習う漢字で書ける駅名

PHP: 文字列リストを並び替える

この投稿中のコードはすべてCC0です

TL;DL

<?php

declare(strict_types=1);

// use Collator;

// この一覧を並び替える
$list = ['あい', 'うえ', 'アイ', 'ABC', 'abc', '亜', 'ぁぃ'];

$collator = Collator::create('ja'); // 実現には Collator を使う
assert($collator !== null);
$collator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); // ナチュラルソート
$collator->sort($list, Collator::SORT_STRING);

echo json_encode($list, JSON_UNESCAPED_UNICODE) . "\n";
// -> ["abc","ABC","ぁぃ","あい","アイ","うえ","亜"]

続きを読む: PHP: 文字列リストを並び替える

久々に東京へいった

仕事で用事があったので、2024/01/11 から 13 で東京へいった。
いや、13 は完全についでに遊んでただけだけど。

何年ぶりの東京だろうなあ。もしかしたら 2012 年以来とかなのかもしれない。
新宿の例の広告のビルを見て「ここがあれかー」とか、「ここがアルタかー」とか完全におのぼりさんしてた。
新宿人生 2 回目だからね、仕方ないね。

久々の東京なのでちょっとだけ乗り潰し。何も考えずに乗れるやつに雑に乗っていくスタイル。
関東はかなり郊外まで相互乗り入れで行くので本当はちゃんと計画立てて二度手間とかを避けるべきなのだけど、まあとりあえずいいでしょ。
(かなり外側で環状線(代表的なのが武蔵野線)を構成していたりするので、端っこ以外は意外とどうにかなりそうな気もする)

  • 東京地下鉄 銀座線 浅草-上野
  • 東京地下鉄 丸ノ内線 池袋-東京
  • 東京地下鉄 有楽町線 小竹向原-池袋
  • 東京地下鉄 半蔵門線 渋谷-押上
  • 東京地下鉄 副都心線 和光市-渋谷
  • 都営 浅草線 浅草-押上
  • 都営 日暮里・舎人ライナー 日暮里-見沼代親水公園

「都営地下鉄・東京メトロ共通一日乗車券」を使った割に東京メトロしか乗ってなくてちょっと勿体ないけど、どちらか意識して路線図見なくて良かったし、そもそも予定立ててないので特に後悔はしていない。
まあ900円で1364円分くらい乗ってるみたいなのでいいか。東京の地下鉄安いな。人口ボーナスを感じる。

途中で上野公園によって国立科学博物館入ったり、日暮里・舎人ライナー往復して荒川線に乗ろうかなとか思ってたら大雨(+雪予報)でやめたりしたので少なめ。
まあ、今後東京へ行く機会は増える見込みなので、ゆっくりやっていきましょう。


まーお話にならんですわ。

stat.ink: Twitter integration is back

Twitter integration is back. However, there are a few limitations.

First, I do not recommend new use of Twitter integration.
As you know, the environment surrounding Twitter has been deteriorating rapidly since the acquisition by Elon Musk, and the Twitter integration that is working now may stop working at any time.
Surely, no one can trust Eron Musk regarding his Twitter work?

  • The maximum number of logins executed is 25 per 24 hours, Twitter documentation says. (The current API docs have different things written on different pages, so I don’t know if this is true or not.)
  • The function for “copying profile icons from Twitter” has been removed.
  • Since it is now a different Twitter app internally, it will need to be re-authorized, at least initially.

Twitter連携機能が復旧しました。しかし、制限があります。

まず、新規のTwitter連携はおすすめしません。
ご存知の通り、Twitterを取り巻く環境はイーロン・マスクの買収以降急激に悪化しています。動作するようになったTwitter連携もいつ動かなくなるかわかりません。

  • ログインの試行は 24 時間あたり 25 回に制限されるとTwitterのドキュメントに記載されています。 (現在のTwitter APIは記載に一貫性がないので、本当にこの制限なのかはわかりません。少なくとも私はTwitterが信頼できないことを知っています)
  • プロフィール画像をTwitterからコピーする機能は削除しました。
  • 内部的には別のTwitterアプリになっているので、少なくとも一度は再認証が求められます。

stat.ink: Twitter integration is not working / Twitter連携が動作していません

Login and other operations are not working because the Twitter application is in status “SUSPENDED”, although it is unclear why.
Please use password authentication.

理由は不明ですが、Twitterアプリがステータス「SUSPENDED」になっているためログイン等が動作しません。
パスワード認証でご利用ください。