「功」という文字の中のバックスラッシュ:台湾のエンジニアが毎日支払っている二層のデフォルト税

語系zh-TW版Windows 11において、翻訳ステータススクリプトが検出した4000件以上のパスをすべてrootに投入しTechnologyがゼロになる。同じ週のLinux CIは緑色である。この問題は、スクリプトが正斜線で分類名を区切る一方で、ドライブではバックスラッシュを使用していることに起因する。さらに古い層として、Big5における「功」の第二バイトがASCIIのバックスラッシュであるという事象がある。

大きな文字「功」の横にそのBig5コードA5と5Cの2マスがあり、5Cのマスが矢印でASCII 0x5Cバックスラッシュを指している。下部にはPythonの実際の出力が表示されており、「許功蓋」という3文字目の第二バイトはすべてバックスラッシュである。
画像クレジット: Taiwan.md Contributors(自製圖解)· CC BY-SA 4.0

30秒概要: 私が翻訳ステータススクリプトを実行したところ、画面に4546と表示され、すべてrootに入っていました。GitHub上のLinux CIは緑色でした。後になって二つの事柄を明確に理解しました。Windowsのパスにおけるバックスラッシュは、スクリプトではスラッシュで区切れない。「功」のBig5コードの後半部分は、それ自体がASCIIの\です。これら二つのメカニズムは異なりますが、同じ繁体中国語版Windows上で同時に発生することがあります。

私は語系zh-TW版Windows 11上でTaiwan.mdの翻訳ステータススクリプトを維持しています。その夜、いつものようにi18n-status.pyを実行し、ターミナルに数字が出力されるのを待っていました。メインコンソールはcp950です。出力には赤文字はありませんでした。

画面は4546で停止しました。すべて「root」という分類に入っていました。Technologyは0でした。

同じ週にGitHubへプッシュしたところ、Linux上のCIは緑のランプを灯していました。

スクリプト変数はzh_articlesと呼ばれ、knowledgeディレクトリ配下から英語、about、およびアンダーラインディレクトリ以外のパスをスキャンします。日本語や韓国語、アラビア語もカウントされていました。その夜、それは分類名さえ区切ることができず、4000件以上のパスが同じセルに詰め込まれてしまいました。例外もなく、警告もありませんでした。統計上はサイト全体が壊れたように見えましたが、ファイルは一つも減っていませんでした1。

ドライブ上のパスはknowledge\Technology\某篇文章.mdであり、ディレクトリ間はバックスラッシュで区切られています。スクリプトはsplit('/')を使って分類名を取得します。Linux上ではこの行は機能しますが、なぜならパス自体がスラッシュだからです。Windows上ではバックスラッシュを区切れないため、パス全体がそのまま戻ってきてしまい、記事はデフォルトのrootに投入されてしまいました2。

pathlibを使ってディレクトリ処理するように変更した後、Technologyの下には59件があり、これはフォルダ内の内容と一致しました。中間にあるのは一つの仮定だけです。それは「あなたのマシンがどの線でディレクトリを区切っているか」という点です。

Pythonターミナルの実際の出力:同じWindowsパスをsplit('/')で区切り、要素一つのみのリストを返却する様子;PureWindowsPath(p).partsに渡すことでknowledge, Technology, ファイル名の3つの部分が区切られる

同じパスに対して、二通りの分割方法。split('/')はスラッシュを見つけられず全体をそのまま返し、PureWindowsPathはバックスラッシュを認識しTechnologyを返します。Taiwan.mdの貢献者によって作成され、CC BY-SA 4.0です。

📝 キュレーターノート: スクリプトの構文に誤りはありませんし、CIも確かにテストを実行しました。亀裂が入ったのは、「作者が実際に座っているマシン」と「ツールがあなたが座っていると想定しているマシン」の間です。この隙間はどのプロセスにも属していないため、誰も監視していません。

「功」の中の線

パスは第一層です。第二層は遥か昔のもので、文字の中に埋め込まれています。

Big5は1984年に確定し、一つの漢字が二バイトを占めます。第二バイトが0x40から0x7Eの範囲にある場合、ASCIIの一般的な記号と重複します。具体的には[、]、{、}、\、|です。当時の朝陽科技大学情報管理学科の副教授であった洪朝貴(2023年8月退職)は、自身の講義ページに「40-7Eは一般的な常用文字のASCIIコード範囲であるため、時としてプログラマーにいくらかの困惑をもたらすことがあります」と記述しています3。

「功」のコードはA5 5Cです。後者の0x5Cは、ASCIIではバックスラッシュ\そのものです。バイト列を一つずつスキャンし、\をエスケープ文字または区切り文字として扱うプログラムは、「功」の後半部分をスキャンした際に、パスに遭遇したと誤認することがあります。ファイル名に「功」が含まれていたり、パスに「功」が含まれていたりする場合、ここでつまずく可能性があります。

台湾と香港の開発コミュニティではこれを「許功蓋(hsiu-kong-gai)」と呼んでいます。「許」はB3 5C、「功」はA5 5C、「蓋」はBB 5Cという三つの常用漢字を連続して書いたものが人名として使われる例です4。洪朝貴氏はさらに「加也程陣功」を列挙し、第二バイトがそれぞれ[、]、{、}と衝突するケースを示し、スキャンツールb5tmを作成しました3。あるバグが人の名前に冠されたのは、それが十分に頻繁に発生し、世代間で指さして話せる必要があったためです。

2015年、ブログ「黑暗執行緒(Dark Thread)」の著者がVisual Studio 2015に切り替えた際、古い.csファイルはまだBIG5で保存されていました。コンパイラがRoslynに移行した後、ファイル内の許功蓋はコンパイルエラーを引き起こしました。

数日後、同僚から「彼らも切り替えましたが、長く詰まっており、最終的に彼の記事を遡って修正した」と聞きました。あるネットユーザーは何千ものファイルを抱えていましたが、変換してもまだ残っているため、「VS2015にさよならするしかなかった」とのことです5。

これは先ほどのsplit('/')とは別の問題です。前者は現代のツールがパスをどのように想定しているかという話であり、後者は40年前に二バイト文字を選択した結果、文字の内部に記号が住み着いてしまったという話です。メカニズムは異なりますが、請求書(この場合はエラー)は同じcp950マシン上で同時に届くことがよくあります。入力側ではどのように文字をコンピュータに送り込むかについては、東亞文字輸入法を参照してください。ここでは、ファイルがすでにディスク上にある後で、ツールチェーンがそれを認識するかどうかについて論じています。

デフォルト値は本マシン用にブランチを切っていない

Gitはcore.quotePathをデフォルトで有効にしています。バイト数が0x80を超えるファイル名は、git statusによって\344\270\255のような八進数エスケープとして表示されます。中国語のファイル名自体は存在しますが、あなたはただ毎日自分のリポジトリが何を言っているのか理解できないだけです6。これはUTF-8の高位バイトをエスケープしているものです。Big5の0x5Cは別の話です。見た目はどちらもバックスラッシュですが、原因が異なります。

ターミナルの実際の出力:git status --shortで本文の中国語ファイル名が引用符付きの八進数エスケープとして表示される様子;-c core.quotePath=falseを追加すると、同じファイル名が中国語で表示される

同じファイルに対して、デフォルト値の下には\345\212\237という連なりがあります。ここでのバックスラッシュはGitが付加したエスケープであり、「功」の中の0x5Cとは無関係です。Taiwan.mdの貢献者によって作成され、CC BY-SA 4.0です。

Python 3がWindows上でopen()を呼び出す際にencoding='utf-8'を指定しなかった場合、システムロケールを引き継ぐ可能性があります。同じUTF-8ファイルでも、Linuxでは正しく読み込めますが、このマシンでcp950を使ってデコードしようとすると、句読点や注音(ピンイン)が壊れます7。私自身も一度経験しました。PowerShell 5.1のGet-Content | Set-Contentを使ってUTF-8ファイルに変換した際、長いダッシュ記号がdiffで??になってしまったのです。これもデフォルト税の一種であり、第二のテーマではありませんでした。

ステータスメッセージに絵文字を伴わせた場合、このcp950コンソールは直接クラッシュします。そのコードセットにはそれらの記号が含まれていないため、Pythonは出力できません。例外が最上位で爆発します。Linux CIではこのことはテストされません。なぜならそれはこのマシン上で実行されていないからです。

Git、Python、CIの例にある$HOME/project/srcのようなパスは、zh-TW版Windowsのために別のブランチを切ったわけではありませんでした。

洪朝貴氏は2015年にiThomeのインタビューを受け、政府ファイルを開く際にどの形式を使うべきか、どれくらいの期間生存できるかについて語っています。記事は彼の意図を次のように伝えています。「もし政府がMicrosoft製品だけでファイルを操作する場合、それはMicrosoftの寿命が中華民国よりも長いと信じているに等しい」と8。この発言はファイル形式とその保存期間に関するものです。データがどのデフォルトツールセットに縛られているかによって、時間が経つにつれて誰が読み取れるかが決まります。オープンソースの協働は特定のマシンのデフォルト環境に結びついています。市民テクノロジーと政府ファイル形式との間の綱引きについては、開源社群とg0vを参照してください。台湾の開発者が長期的に吸収してきたこのギャップという文化については、台湾オープンソース精神を参照してください。

パス区切り文字、ターミナルのエンコーディング、CIの例にある$HOMEは、本マシン用に枝分かれしたわけではありませんでした。4546件のパスが誤ったカテゴリに分類された日には、どの行もエラーを報告しませんでした。統計上は正常に見えましたが、あなたがこのマシンの前に座っているときだけです。

関連資料

画像の出典

  • 「功」のBig5コードとバックスラッシュ(hero):Taiwan.mdの貢献者による図解であり、CC BY-SA 4.0です。public/article-images/technology/big5-gong-5c-backslash.webpに保存されています。下段の行はPython 3が実際に '許功蓋'.encode('big5') を実行した出力であり、コードポイントはWikipediaの大五碼項目と一致します4。
  • split('/') と PureWindowsPath:Taiwan.mdの貢献者による図解であり、CC BY-SA 4.0です。public/article-images/technology/windows-path-split-vs-pathlib.svgに保存されています。内容はPython 3の実際の実行結果を示しており、PureWindowsPathはどのOS上でもWindowsの規則に従ってパスを分割するため、Windowsマシンがなくても再現可能です。
  • Git core.quotePath の八進数出力:Taiwan.mdの貢献者による図解であり、CC BY-SA 4.0です。public/article-images/technology/git-quotepath-octal-cjk.svgに保存されています。内容はリポジトリに本文ファイル名を追加した際のgit status --shortの実際の出力であり、この動作はOSとは無関係です。

参考文献

  1. taiwan-md PR #1260 — 2026年7月26日マージ。修正前、Windows上のcategoriesはrootのみで4546件でしたが、修正後はTechnology zh: 59件となりました。cp950コンソールをクラッシュさせる絵文字も削除されました。↩
  2. Microsoft Learn:Windows システム上のファイルパス形式 — .NETドキュメントでは、従来のDOSパスがバックスラッシュをディレクトリ区切り文字として使用し、正斜線はバックスラッシュに変換されると説明されています。↩
  3. 洪朝貴氏:プログラミングで遭遇するBig5コードの問題 — 講義ページでは、第二バイトがASCIIの危険域に入る常用漢字(加也程陣功)を列挙し、スキャンツールb5tmを紹介しています。末尾には職位の記載はありません。2015年iThomeでは副教授と紹介されています。筆者は1997年から2023年まで朝陽資管で勤務し、2023年8月に退職しました。↩2
  4. Wikipedia:Big5 — 「功」を0xA55C、「許」を0xB35C、「蓋」を0xBB5Cとして記載し、この問題が「許功蓋」と呼ばれていることを説明しています。↩2
  5. 黑暗執行緒:潜盾機-VS2015プログラミングファイルのBIG5互換性問題解決 — 2015年の記録で、Visual Studio 2015がBIG5のソースコードをコンパイルする際に許功蓋がコンパイルエラーを引き起こしたことが記されています。記事には「VS2015にさよならせざるを得なかった」という記述があります。↩
  6. git-config:core.quotePath — 公式ドキュメントでは、バイト数が0x80を超えるパスは八進数エスケープとして表示されると説明されています。↩
  7. Python 3:open() — 関数説明では、エンコーディングを指定しない場合、システムロケールがデフォルトのエンコーディングとして使用される可能性があると指摘されています。↩
  8. iThome:洪朝貴氏インタビュー — 2015年のインタビューで、筆者は朝陽科技大学情報管理学科の副教授と紹介されています。元のページは頻繁に403エラーを返したため、Microsoftの寿命に関する発言は検索結果から確認できる記事の内容を引用したものであり、逐語訳ではありません。↩
この記事について この記事はコミュニティとAIの協力により作成されました。
タグ
オープンソース Windows Big5 UTF-8 文字コード 繁体中国語
共有

関連記事

こちらもおすすめ

テクノロジー 正式記事

キーボード上の文明的衝突:東アジアの文字入力法の百年進化

世界のキーボードが統一される中で、異なる文明はどのように自らの文字を26のアルファベットに収めたのか?台湾の注音から韓国の二伐式まで、入力法は静かな文化防衛戦であった。

閱讀全文
ライフスタイル 正式記事

台湾税関の通関とEZ WAY:「申報相符」を押したその瞬間、あなたは誰に委任したのか

スマホが震え、プッシュ通知には理解し難い品名が並ぶ。「申報相符」を押すと、法的には通関委任が完了する。台湾全土で759万人がこのアプリに登録し、2026年8月のある投稿が話題になるまで、多くの人が初めて運営元を知った:財務省が36.11%出資し、官股が過半数に達していない関貿網路。同じ時期、2,000元の免税基準が政府によって2度目の引き下げ提案がなされている。この利便性の裏にあるコスト、誰が払い、誰が最初から最後まで発言できなかったのか。

閱讀全文
文化 正式記事

台湾の口語コード:「すみません」から「Dを豚と発音する」まで、日常会話に潜む四つの表現の出自

台湾では、「すみません」は本気の謝罪の前段階として使われることがあります。「え?」は単なる聞き間違いではなく、言語を越えた対話修復機能です。また、@が「小老鼠(ちいさなねずみ)」と呼ばれることや、Dが試験問題の交換時に「豚/朱」と発音される現象など、この四つの表現は礼儀、誤解、電子メール、そして台湾語の音韻を日常に織り込み、台湾の話し方が単なる発音体系ではなく、共に生きる人々の識別方法であることを示唆しています。

閱讀全文
文化 進化中・コミュニティ投稿

台湾の諧音禁忌文化:なぜ「四」が社会全体で階層を飛ばされるのか?

病院に4階がないことから車牌「8888」が高額落札されるまで、台湾人の諧音への敏感さは世界随一

閱讀全文