Appleの単語リストをダンプした
I dumped Apple’s word list (helgesver.re)
要約
この記事では、macOSのシステム辞書に含まれる単語にAppleがどのように「下品」「攻撃的」「機密」といったフラグを付けているかを調査しています。著者はプライベートAPIを通じてこれらのフラグを抽出し、特に「トランプ」という単語が他の故人やテロリストと共に「機密」カテゴリに分類されていることを発見しました。この分類は、キーボードの予測候補表示に影響を与える可能性があり、特定の単語の不適切なサジェストを防ぐためのものだと推測されています。
全文翻訳
Appleの単語リストをダンプした
2026年11月3日
TL;DR
~/Library/Keyboard/VulgarWordUsage.dbは実在します。これはアプリごと、受信者ごとに、どの下品な単語を使用するかを記録し、オートコレクトがあなたを「ducking」するのを防ぐように学習します。私のMacでは空で、ネイティブアプリに下品な単語を入力しても埋まりませんでした。- 興味深いのはアップストリームです。Appleのシステム辞書は、各単語に3つのティア(下品、攻撃的、機密)と最大11個のトピックフラグ(性、薬物、宗教、政治、暴力など)を付けています。
- これらに対する公開APIはありません。私は
Lexicon.frameworkのいくつかのプライベートC関数でフラグを読み取りました。コードはCとSwiftで以下にあります。15言語の完全なダンプはこのgistにあります(検閲なし、コンテンツに関する注意書きを参照)。 - ハイライト:オイディプスは下品です。トムとミックは攻撃的です。pee、poo、niggle、underlingは機密です。そして「トランプ」は、ヒトラー、毛沢東、ウサマ・ビンラディン、タリバンと共に、英語の機密ティアにおける唯一の現役政治家です。バイデン、オバマ、プーチンはクリーンです。
コンテンツに関する注意:この記事では、単語が下品かどうかの全体像を示すために、スラーを含む単語を検閲なしで印刷します。例外はnワードです。これは英語や他のいくつかの言語のリストに含まれていますが、私はそれを書き出すつもりはありません。
ツイートから始まった
[画像: Nick (@nicksdot) によるツイート:「TIL: macOSには、私たちの冒涜の使用を追跡するデータベースがあります」と表示され、Finderにuser_model_database.sqlite-walとVulgarWordUsage.dbが表示されている。Helgeが「どこにありますか?」と返信し、Nickが「~/Library/Keyboard/VulgarWordUsage.db」と答えている。]
Nickがこれを投稿しました。私はその場所を尋ね、彼は答えました。私の冒涜を追跡するデータベースは、私が放置できるものではありませんでした。そこで私は自分のものを見てみました。
データベース
$ sqlite3 -readonly ~/Library/Keyboard/VulgarWordUsage.db .schema
CREATE TABLE properties (ROWID INTEGER PRIMARY KEY, key, value, UNIQUE (key));
CREATE TABLE IF NOT EXISTS "vword_usage" (
ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
app TEXT, -- app identifier
recipient TEXT, -- recipient identifier
vword TEXT, -- vulgar word
word_reading TEXT, -- the reading form of a word (relevant for Japanese)
usage_count INTEGER DEFAULT 0,
last_use_timestamp REAL DEFAULT 0, -- last use timestamp (seconds since the reference date)
journaled
);
CREATE UNIQUE INDEX app_recipient_vword_word_reading_idx ON vword_usage(app, recipient, vword, word_reading);
これにより、キーボードは、あなたが特定の友人に対してMessagesでfuckと言うが、上司へのMailでは言わないことを知ることができます。ユニークインデックスは(app, recipient, word, reading)にあり、それが粒度です。
私のものには行がゼロ件あります。propertiesテーブルにはversion = 2とそれ以外は何も保持されていません。ファイルは2024年4月に最後に書き込まれました。
何のためにあるのか
2023年6月のWWDCで、Craig FederighiはiOS 17のオートコレクト書き換えをこの言葉で発表しました:「あなたがただダッキングしたい単語をタイプしたい瞬間には、キーボードもそれを学習します。」(TechCrunch, NPR)。
このデータベースは、それが学習する方法です。macOSの共有ライブラリキャッシュ内のシンボル名は、フローを物語っています:
TI::VulgarWordUsageDatabaseWrapper::set_current_app_id(CFString)
TI::VulgarWordUsageDatabaseWrapper::set_current_recipient_ids(vector<string>)
TI::VulgarWordUsageDatabaseWrapper::increment_usage_count(word, reading, recipients)
TI::VulgarWordUsageDatabaseWrapper::decrement_usage_count(...)
TI::VulgarWordUsageDatabaseWrapper::can_autocorrect(word, app, recipients)
TI::VulgarWordUsageDatabaseWrapper::can_autocorrect_somewhere(word, reading)
KB::FilterNonVulgarIfTopCandidateVulgar::filter_candidates(...)
KB::Candidate::every_vulgar_word_is_allowlisted(VulgarWordUsageDatabaseWrapper*, ...)
さらに、Passing recipient IDs to the vulgar word usage database wrapper; number of IDs: %luのようなログ文字列もあります。
平易な言葉で言うと:
- あなたがタイプを始めると、キーボードエンジンはラッパーに、あなたがどのアプリにいて、誰に書いているかを伝えます。
- 下品な単語をタイプしてそれを保持すると、その単語のカウントがそのアプリと受信者に対して増加します。単語を元に戻すと、カウントは元に戻ります。
- エンジンが候補をランク付けする際、候補内のすべての下品な単語がこのコンテキストで許可されているかどうかを尋ねます。許可されていない場合、クリーンな代替案が勝ちます:ダッキング。
_KSUserSynchroniser sharedAcrossLanguagesVulgarWordUsageValueというシンボルは、他の学習済み単語のようにデバイス間で同期することを示唆しています。
私のは空です
それを埋めようとしました。agent-desktopを使用して、新しいTextEditドキュメントを開き、well fuck this shit, damn it.とタイプしました。まずテキスト挿入として、次に個々のキープレスとして。何も変わりませんでした:行もログ行もなく、ファイルの変更日は2024年のままでした。
理由はわかりませんし、解明できませんでした。おそらくMacはここで何も記録しないか、あるいは特定のアプリや設定でのみ記録するのかもしれません。もしあなたのものに行があるなら、何をしましたか教えてください。
それは短い記事になるでしょう。しかし、データベースはすでに下品だと知られている単語しかカウントしません。では、誰がそれを決めるのでしょうか?
単語リストはどこにあるのか
dyld共有キャッシュで「vulgar」を検索すると、LXプレフィックス(LXVulgarWordUsageDatabaseCreate, LXVulgarWordUsageDatabaseCanAutocorrect, …)を持つC APIと、より有用なことに、辞書エントリ上の2つの関数が見つかりました:
_LXEntryGetCategoryFlags
_LXEntryGetMetaFlags
LXはLexicon.framework、つまり/System/Library/LinguisticData/の下にある言語ごとの辞書を読むプライベートフレームワークです。それらの辞書のすべての単語は、2つの32ビットフラグフィールドを持つLXEntryです。下品さの評価があるとしたら、それはそれらのビットの中にあります。
公開APIはない
調べました。NSSpellChecker, UITextChecker, NaturalLanguage, UILexiconは下品さを公開していません。SensitiveContentAnalysisは画像とビデオをカバーしますが、テキストはカバーしません。「profanity」という言葉がdeveloper.apple.comに現れる唯一の場所は、App Storeの年齢評価とレビューガイドラインです。
したがって:プライベート関数です。Lexiconにはヘッダーがありませんが、C関数はエクスポートされており、CoreFoundationの規約に従っているため、そのシグネチャを推測するのは簡単です。このプログラムは、ロケールの辞書を開き、すべてのエントリをウォークし、両方のフラグフィールドを印刷します:
// lx.c — dump every word in a system lexicon with its flags.
// clang -O1 -o lx lx.c -F/System/Library/PrivateFrameworks -framework Lexicon -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
#include <stdbool.h>
#include <stdio.h>
typedef const void *LXLexiconRef, *LXCursorRef, *LXEntryRef;
extern CFStringRef kLXLexiconLocaleKey;
LXLexiconRef LXLexiconCreate(CFDictionaryRef options, CFErrorRef *error);
LXCursorRef LXLexiconCreateRootCursor(LXLexiconRef);
void LXCursorEnumerateEntriesRecursively(LXCursorRef, void (^)(LXEntryRef, bool *stop));
CFStringRef LXEntryCopyString(LXEntryRef);
uint32_t LXEntryGetCategoryFlags(LXEntryRef);
uint32_t LXEntryGetMetaFlags(LXEntryRef);
int main(int argc, char **argv) {
CFStringRef locale = CFStringCreateWithCString(NULL, argc > 1 ? argv[1] : "en_US", kCFStringEncodingUTF8);
const void *keys[] = {kLXLexiconLocaleKey}, *values[] = {locale};
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
LXLexiconRef lexicon = LXLexiconCreate(options, NULL);
if (!lexicon) return 1;
LXCursorEnumerateEntriesRecursively(LXLexiconCreateRootCursor(lexicon), ^(LXEntryRef entry, bool *stop) {
char word[512] = "";
CFStringRef s = LXEntryCopyString(entry);
if (s) { CFStringGetCString(s, word, sizeof word, kCFStringEncodingUTF8); CFRelease(s); }
printf("%08x\t%08x\t%s\n", LXEntryGetCategoryFlags(entry), LXEntryGetMetaFlags(entry), word);
});
}
$ ./lx en_US | wc -l
199019
$ ./lx en_US | awk -F'\t' '$3 == "fuck" || $3 == "table" || $3 == "Trump"'
00000000 00800002 fuck
00000000 00000000 table
00002000 02000081 Trump
Swiftでの同じこと。プライベートフレームワークにリンクする必要がないように、dlopenとdlsymで実行時に関数をロードします。ティアのいずれかを持つ単語のみを印刷します:
// lexflags.swift — swiftc -O lexflags.swift -o lexflags && ./lexflags en_US
import Foundation
let lexicon = dlopen("/System/Library/PrivateFrameworks/Lexicon.framework/Lexicon", RTLD_NOW)!
func sym<T>(_ name: String, as _: T.Type) -> T { unsafeBitCast(dlsym(lexicon, name)!, to: T.self) }
typealias LXRef = UnsafeRawPointer
let create = sym("LXLexiconCreate", as: (@convention(c) (CFDictionary, UnsafeMutablePointer<Unmanaged<CFError>?>?) -> LXRef?).self)
let rootCursor = sym("LXLexiconCreateRootCursor", as: (@convention(c) (LXRef) -> LXRef?).self)
let enumerate = sym("LXCursorEnumerateEntriesRecursively", as: (@convention(c) (LXRef, @convention(block) (LXRef, UnsafeMutablePointer<Bool>) -> Void) -> Void).self)
let copyString = sym("LXEntryCopyString", as: (@convention(c) (LXRef) -> Unmanaged<CFString>?).self)
let metaFlags = sym("LXEntryGetMetaFlags", as: (@convention(c) (LXRef) -> UInt32).self)
let category = sym("LXEntryGetCategoryFlags", as: (@convention(c) (LXRef) -> UInt32).self)
let localeKey = dlsym(lexicon, "kLXLexiconLocaleKey")!.load(as: CFString.self)
let locale = CommandLine.arguments.dropFirst().first ?? "en_US"
guard let lex = create([localeKey: locale] as CFDictionary, nil), let root = rootCursor(lex) else {
fatalError("could not open lexicon for \(locale)")
}
let tiers: [(UInt32, String)] = [(0x0080_0000, "vulgar"), (0x0100_0000, "offensive"), (0x0200_0000, "sensitive")]
enumerate(root) { entry, _ in
let meta = metaFlags(entry)
guard let tier = tiers.first(where: { meta & $0.0 != 0 })?.1,
let word = copyString(entry)?.takeRetainedValue() else { return }
print(tier, String(format: "%05x", category(entry)), word, separator: "\t")
}
どちらも読み取り専用です。キーボードが使用するのと同じ辞書を開き、それを印刷します。
ビットのデコード
Appleはこれらのフラグを文書化していないため、以下のすべての意味は推測です。ビットごとに単語をグループ化し、各グループのテーマが明らかになるまでサンプルを読みました。システムコードは、そのうちの1つに役立ちます。offensiveVulgarSensitiveという列挙型ケースが、下品な単語コードのすぐ隣にあり、3つの隣接するメタビットがそれに一致します。
3つのティア(メタフラグ)
| ビット | ティア | en_US 単語 | 例 |
|---|---|---|---|
0x00800000 | 下品 | 1,050 | fuck, shit, cunt, cock, crap, wtf, fml, bullshitting, fucktard, shizzle, merde |
0x01000000 | 攻撃的 | 663 | kike, wop, dago, fag, Paki, japs, Klansman, retard, Oriental, ass, asshole |
0x02000000 | 機密 | 2,558 | damn, bitch, idiot, LSD, abortion, gun, suicide, anus, pee, poo |
en_USでは、単語は最大で1つのティアを持ちます:それらは決して重複しません。199,019エントリのうち、4,271が1つのティアを持っています。
大まかに言うと:下品は罵り言葉と性的なスラング、攻撃的は集団に向けられたスラー、そして機密はキーボードが不意に提供すべきではないすべてです:軽い罵り言葉、侮辱、薬物、武器、過激主義、病気、身体機能。
トピック(カテゴリフラグ)
もう一方のフィールドはトピックビットマスクであり、単語は複数のトピックを持つことができます:
| ビット | トピック | en_US 単語 | 例 |
|---|---|---|---|
0x00100 | 排泄 | 123 | feces, barf, crapper, piddle, pooped |
0x00200 | 体の部分 | 958 | nipples, navel, buttock, perineum, triceps |
0x00400 | 侮辱、アイデンティティ関連 | 823 | idiot, cretin, hick, pleb, sexist, homophobic, blacklist |
0x00800 | 病気 | 93 | Covid, herpes, PTSD, leprosy, monkeypox |
0x01000 | 薬物 | 222 | heroin, shroom, crackhead, hotbox, OD |
0x02000 | 政治、過激主義 | 266 | Hamas, Goebbels, Leninism, democrat, swastikas, Trump |
0x04000 | 宗教、冒涜 | 420 | Sikhism, jihadi, Beelzebub, damn, hell, jeez |
0x08000 | 性 | 473 | nude, nookie, lecher, harlots, Pornhub, Hooters |
0x10000 | 暴力、死 | 373 | suicide, lynch, murders, hangings, slave, slaveholder |
0x20000 | 武器、テロ | 268 | AK-47, grenadier, jihad, sarin, kamikaze, yellowcake |
0x40000 | 包括的な「機密コンテキスト」 | 1,080 | God, Allah, Jews, gay, trans, bi, crazy, fat, ugly, sex, die |
トピックフラグとティアは独立しています。2,052の英語の単語にはトピックがありますがティアはありません:gay, fat, God, Allah, sex はすべて「機密コンテキスト」としてタグ付けされていますが、下品、攻撃的、または機密ではありません。私の推測では、トピックはヒント(「これをランク付けする際は注意してください」)であり、ティアはルールです。
下位のメタビットは退屈です:固有名詞、略語、iMacやtvOSのようなキャメルケースのブランド名。そこには見るべきものはありません。
変なもの
ここからが面白くなります。いくつかのフラグは明らかに正しく、いくつかはおかしくさせられました。
下品
- オイディプス: 下品。おそらくmotherfuckerに隣接するジョーク、またはコンプレックスのため。ソフォクレスは喜ぶでしょう。
- reams: 下品。「誰かをこっぴどく叱る」という意味で。
- cooties: 下品。あなたの9歳児が罵っているということです。
- orgy, sext, merde: まあ、納得です。
攻撃的
- トムとミック: 攻撃的。「アンクル・トム」とアイルランド人へのスラーですが、非常に一般的なファーストネームでもあります。
- オリエンタル: 攻撃的。
- パプーゼス: 攻撃的。
- conservatards: 攻撃的。スラーティアで見つかった唯一の政治的侮辱です。
- niggardly: 攻撃的。これは「けち」を意味し、古ノルド語に由来し、スラーとは無関係です。これは実際の論争を引き起こしており、おそらくそれがそこにある理由です。
- assとasshole: 下品ではなく、攻撃的です。
機密
- peeとpoo: 排泄トピックを持つ機密。premenstrual, leprosy, herpesvirusも同様です。
- niggle(小さな心配事、スカンジナビア起源)とunderling(古英語で部下を意味する)は機密であり、侮辱トピックを共有しています。似たような単語はフラグが付けられていません:sniggerはクリーンですがniggleはフラグが付けられており、minion, lackey, flunky, stoogeはクリーンですがunderlingはフラグが付けられています。これらはルールではなく、手作業で選ばれたエントリのように見えます。
- blacklistとwhitelistは、侮辱/アイデンティティトピックを持つ機密です。これは、業界がblocklistとallowlistに移行したことと一致します。Apple自身のフレーズフィルターファイルは
blocklist.datという名前です。 - BravesとChiefs(ネイティブアメリカンのマスコットを持つチーム名)、Londonderry(Derryの論争のある名前)、Gentile, Jehovah, Mongol, Frenchierはすべて機密です。
- Isisは政治トピックを持つ機密です。エジプトの女神には申し訳ありません。
- slave, slavery, slaveholderは暴力トピックを持つ機密です。
- idiotは英語では機密です。ノルウェー語はより厳しく、idiotを攻撃的ティアに分類しています。
トランプフラグ
機密ティアには109個の大文字の単語があります。そのすべてを以下に示します:
Al-Qaeda, Al-Qaida, Aryan, Aryans, Auschwitz, Bacchus, Beelzebub, Birkenau, Brave(s), Buchenwald, Chief(s), Chippendale(s), Christ-y, Christer(s), Crip(s), Dachau, Eichmann, Frenchier, Gentile(s), Gestapo(s), Goebbels, Goering, Hamas, Hezbollah, Himmler, Hitler, Hitlerian, Hitlerism, Hitlerite(s), Hitlerjugend, Hooters, Isis, Islamophobe(s), Islamophobic, Jehovah(s), Jewfro(s), Jezebel(s), Kalashnikov(s), Kristallnacht, Kuomintang, Londonderry, Luftwaffe, Mao, Mauthausen, Mickie(s), Mollie(s), Mongol(s), Mossad, Nazi(s), Nazism, Osama, Pornhub, Quaalude(s), Reich, Reichsmark, Reichstag, Sachsenhausen, Satan, Satanism, Shoah, Sinophobe(s), Sinophobic, Sodom, Stasi, Taliban, Treblinka, Trump, Trumps, Unabomber, Uzi(s)
(複数形と所有格は簡潔さのために省略)
そのリストにある他のすべての実在の人物は死んでおり、ほとんどがナチス関係者、独裁者、またはテロリストです。そこにトランプがいます:
category meta word
00002000 02000081 Trump sensitive tier + politics topic
00002000 02000081 Trumps
00002000 02000081 Trump's
00000000 00000000 trump (the card-game word: clean)
00000000 00000000 trumped
比較のために:
| 単語 | en_US |
|---|---|
| Trump | 機密、政治トピック |
| Hitler | 機密、政治トピック |
| Biden | クリーン |
| Obama | クリーン |
| Putin | クリーン |
| Stalin | クリーン |
| Musk | 辞書にない |
en_GBはen_USと一致します。他の言語は異なります:ドイツ語の辞書にはTrumpはクリーン(そしてHitlerは攻撃的ティアに分類)されており、スウェーデン語はPutinを機密としてフラグ付けしています。
フラグが何をするかがここで重要です。私が知る限り、機密単語とは、キーボードが単独で提案すべきではない単語です。それでもタイプでき、修正されることはありません。「ユーザーが明らかにそちらに向かっている場合を除き、QuickTypeバーからこれを除外する」と考えてください。これは禁止よりもはるかに穏やかなものです。
特定の名前に対してAppleがそれを望むもっともらしい理由があります。2025年2月、iPhoneの音声入力で、人々が「racist」と言ったときに一時的に「Trump」と表示されました。それはバイラルになり、Appleはそれを音声モデルの「音韻的重複」と呼び、1日以内に修正をリリースしました(9to5Mac)。私のMac上の辞書ファイルは2025年7月のものです。この名前を不意の提案から除外するルールがあれば、同様のことがキーボードを通じて再び起こるのを防ぐことができます。それが理由だと証明することはできませんし、比較のために古い辞書も持っていません。しかし、それは理にかなっています。
ノルウェーの政治、比較のために
私はノルウェー人であり、確認する必要があったので:
| 単語 | トピック | ティア |
|---|---|---|
| FrP, Høyre, Venstre, Rødt, SV, KrF, MDG | 政治 | なし |
| Støre | 政治 | なし |
| Solberg, Erna, Sylvi | なし | なし |
| Listhaug | n/a | 辞書にない |
| Breivik, Quisling, Hitler | なし | 機密 |
すべての政党は政治トピックを受け取り、どれもティアを受け取りません。機密ティアに含まれるノルウェー人は、大量殺人犯とナチスの協力者だけです。
他の言語
同じ3つのティアは、私が試したすべてのヨーロッパの辞書に存在し、キリル文字のものも含まれています。カウントはエントリであり、レンマではないため、ポーランド語やロシア語のような高度に屈折する言語は、実際よりも悪く見えます:罵り言葉のすべての格と活用形が別々のエントリになっています。
| ロケール | 下品 | 攻撃的 | 機密 | 注目すべき点 |
|---|---|---|---|---|
| en_US | 1,050 | 663 | 2,558 | idiot は機密 |
| en_GB | 1,055 | 872 | 2,337 | chav は攻撃的;chink は攻撃的ではなく下品として分類 |
| nb_NO | 2,393 | 1,324 | 6,446 | idiot は攻撃的 |
| da_DK | 1,179 | 3,314 | 8,551 | fjols(「愚か者」)は攻撃的 |
| sv_SE | 637 | 1,247 | 16,193 | idiot は下品;Putin は機密 |
| fi_FI | 569 | 872 | 47 | 機密ティア全体がkakka(「うんち」)、kakkakasa(「うんちの山」)、saakeli |
| de_DE | 3,218 | 3,518 | 9,446 | Hitler と beknackt(「愚かな」)は攻撃的;Trump はクリーン |
| nl_NL | 57 | 1,180 | 3,805 | 下品な単語は57個のみだが、kanker(「癌」、典型的なオランダ語の罵り言葉)はそのうちの1つ |
| fr_FR | 2,151 | 262 | 5,562 | boche は攻撃的 |
| es_ES | 3,931 | 313 | 13,431 | sudacas と fachas は攻撃的 |
| it_IT | 3,886 | 377 | 6,543 | terrone は攻撃的、nazismi も同様 |
| pt_BR | 1,590 | 1,891 | 3,332 | machista と velhinhos(「小さなお年寄り」)は攻撃的 |
| pl_PL | 9,698 | 1,436 | 6,190 | ここで最大のティアは下品、主に活用形(dupczysz, srasz) |
| ru_RU | 10,821 | 3,239 | 24,721 | 同じ話:мат は多く活用する |
ビットはどこでも同じ意味を持つわけではないようです。アラビア語とヘブライ語は数十万の「機密」エントリを返しますが、それらの辞書はおそらくビットを別の目的で再利用しており、私はそれらを省略しました。韓国語、カタラン語、ハンガリー語は何も返さず、日本語は私のダンプツールをクラッシュさせます。
ノルウェー語からのサンプル(英語以外でタイプするときに使うので):
- 下品: faen, jævla, dritt, fitte, kuk, pule, pissehull, rævhull, pulekanin, kåt, morrabrød。
- 攻撃的: idiot, sigøyner, kinamann, riskokers(文字通り「炊飯器」、アジア人へのスラー)、ノルウェー語のnワード。
- 機密: helvete, satan, homo, quisling, Breivik, skinhead, abortnekt, trusene(「パンティ」)。
ティアの単語はほとんど予想通りですが、エッジは言語ごとに異なり、そこには人間が編集した部分が現れます。ノルウェー語はidiotを攻撃的と呼び、英語はそれを機密と呼びます。ドイツはヒトラーをスラーと考えています。
フレーズ、単語だけでなく
2番目の独立したフィルターがあります。すべての英語言語モデルにはblocklist.bundleがあり、QuickPath(スワイプキーボード)にはqp_blocklist.bundleがあります:
/System/Library/LinguisticData/RequiredAssets_en.bundle/AssetData/en.lm/
├── blocklist.bundle/{blocklist.dat, blocklistidmap.dat}
└── qp_blocklist.bundle/{blocklist.dat, blocklistidmap.dat}
blocklistidmap.datは20バイトのヘッダーに続き、(lexicon token ID, class ID)のペアの32ビット整数です。トークンIDを辞書にマッピングすると、930クラスの2,544単語が得られます。ほとんどのクラスは屈折グループです:
931 fuck | fucked | fucking | fucks
1181 molest | molestation | molested | molester | molesting
1514 died | dies | dying
1611 Holocaust | holocaust | holocausts
1614 denied | denies | deny | denying
923 Semite | Semites | Semitic
1487 ghetto | ghettoes | ghettos
1720 animals | brown | cats
blocklist.datはそれらのクラスID上のパックされたトライであり、シーケンスをブロックします:「deny」の後に「Holocaust」、そして1720がbrown、animals、catsをペアにするもの。brownをanimalsとcatsの隣に置くクラスは、リストが単一の単語ではなく特定のフレーズをターゲットにしていることを示唆していますが、どのフレーズかはトライをデコードしないとわかりません。実行時のチェックはLanguageModeling.frameworkのLMLanguageModelTokenSequenceIsBlocklistedです。私は、その4番目と5番目の引数に出力ポインタが含まれていることを学ぶところまで行きましたが、私のプローブはまだ断続的にクラッシュするため、実際のフレーズはまだ読んでいません。それはフォローアップ用です。
注意事項
- 意味は推測です。 Appleはこれらのビットのいずれも文書化していません。ティア名はシステムコードの列挙型から来ており、トピックは数千のサンプルを読むことから来ています。どちらも一貫していますが、それでも解釈です。
- フラグ付けは検閲ではありません。 私が知る限り、これらのフラグはキーボードが提案するものを決定するのであって、あなたがタイプできるものを決定するのではありません。
- 1台のマシン。 ここにあるすべては、macOS 15.6 (24G84) のLinguisticDataビルド438(2025年7月)から来ています。iOSや他のmacOSバージョンでは異なる辞書が出荷される可能性があります。
- プライベートAPI。 関数は、アップデートごとに変更されたり、消滅したりする可能性があります。これをアプリに出荷しないでください。
自分で試す
# あなた自身の学習済み冒涜データベース(Macではおそらく空)
sqlite3 -readonly ~/Library/Keyboard/VulgarWordUsage.db 'select * from vword_usage'
# 上記のSwiftバージョンをビルドし、ティアでフィルタリングする
swiftc -O lexflags.swift -o lexflags
./lexflags en_US | awk -F'\t' '$1 == "vulgar" {print $3}' | sort -u | less
./lexflags nb_NO | awk -F'\t' '$3 == "faen" || $3 == "helvete" || $3 == "idiot"'
何かをビルドしたくない場合は、gistに15ロケールのティア付き単語すべてがTSV形式で、コードとそれらを再生成するスクリプトがあります。これはmacOS 15.6のスナップショットであり、最新の状態に保たれる予定はありません。
オイディプスよりも面白いものを見つけたら、ぜひ教えてください。
[画像]