医療・研究データのID匿名化を一括で行うデスクトップアプリケーション
フォルダをドラッグ&ドロップするだけで、フォルダ名・ファイル名・テキストファイル内容・DICOMタグに含まれるIDを一括匿名化。Feistel暗号化による可逆変換、対応表CSVの自動生成、DICOMタグ限定モードなど、研究データの取り扱いに必要な機能を揃えています。
入力データの構造を自動判別し、ID名サブフォルダがある場合・親フォルダに直接DICOMがある場合・CSV/Excelのみの場合のいずれにも対応します。CSV/Excel内のID列は値のパターンから自動検出し、名前列はヘッダキーワードから自動検出して匿名化します。
匿名化ツール.exe をダウンロードし、任意のフォルダに配置※ ウイルス対策ソフトが誤検知する場合があります。その場合は例外設定に追加してください。
Feistel暗号化モード
1234567 → K8392041)対応表作成モード
KMS_{0001}_aaa)_対応表.csv を自動生成DICOMタグのみモード
_0, _1... の連番を自動付与入力フォルダの中身を自動判別し、以下の3パターンに対応します。すべてのパターンでFeistel暗号化・対応表作成・DICOMタグのみの各モードが使用可能です。
パターンA: ID名サブフォルダ + 親DIR内ファイル
最も一般的なパターンです。親フォルダの中にID(数字N桁)で始まるサブフォルダがあり、その中に各患者のデータが格納されている構造です。
入力フォルダ/
├── 患者一覧.xlsx ← 親DIR内のCSV/Excelも自動匿名化
├── study_list.csv
├── 1234567_検査A/ ← ID名サブフォルダ
│ ├── 1234567.dcm
│ ├── result_1234567.csv
│ └── ...
├── 2345678_検査B/
│ └── ...
処理順序: サブフォルダを処理 → 親DIR内のCSV/Excelを処理
パターンB: 親DIRに直接DICOMファイル
サブフォルダがなく、DICOMファイルが親フォルダに直接格納されている場合です。DICOMタグ内の PatientID からIDを自動取得して匿名化します。
入力フォルダ/
├── 1234567.dcm
├── 1234568.dcm
├── 患者リスト.csv ← あれば一緒に匿名化
_対応表.csv を自動生成(既存があれば追記)パターンC: CSV/Excelのみ
DICOMもサブフォルダもなく、CSV/Excelファイルのみの場合です。ファイル内のID列を自動検出して匿名化します。
入力フォルダ/
├── 患者一覧.xlsx
├── 検査結果.csv
_対応表.csv を自動生成(既存があれば追記)親DIR内のCSV/Excelファイルは、列の内容を分析してID列と名前列を自動判別します。
ID列の検出(ヘッダ名に依存しない)
ヘッダ名(「患者ID」「プランID」等)ではなく、列の値そのもので判定します。これにより「プランID(1-2桁)」と「患者ID(7桁)」が同じファイルにあっても正しく区別できます。
| 判定方法 | 条件 | 説明 |
|---|---|---|
| 既知ID一致 | 値が既知IDと 2件以上 一致 | サブフォルダ名やDICOMタグから得たIDと照合 |
| 桁数パターン(フォールバック) | 値の 70%以上 がID桁数と一致する数値 | 既知IDがない場合に使用 |
| 日付除外 | YYYYMMDD形式やExcelシリアル日付を自動除外 | 8桁IDと日付、5桁IDとシリアル日付の混同を防止 |
名前列の検出(ヘッダキーワードベース)
以下のキーワードがヘッダに含まれる列を名前列として検出し、該当行のIDが特定できた場合に空白化します。
| 検出強度 | キーワード |
|---|---|
| 強一致 | 患者名, PatientName, 被験者名, 対象者名, 氏名, 名前, 姓名 |
| 中一致 | LastName, FirstName, FamilyName, GivenName, カナ, フリガナ, ふりがな, ローマ字, Romaji, Kana |
| 完全一致のみ | 姓, 名, Name, Last, First |
姓・名が別々の列に分かれている場合や、ローマ字表記の列も検出対象です。
フォルダ名・ファイル名 — IDを含む名前を匿名化IDに置換(ON/OFF可能)
テキストファイル内容 — 以下の形式に含まれるIDを置換:
| 形式 | 拡張子 |
|---|---|
| プレーンテキスト | .csv .txt .tsv .log .ini .yaml .yml .toml .bin |
| 構造化テキスト | .json .xml |
| Office文書 | .xlsx .docx .pptx |
DICOMタグ — 患者名・患者ID・生年月日など15種類のタグを個別にON/OFF可能:
| タグ名 | 説明 | デフォルト値 |
|---|---|---|
| PatientName | 患者名 | {id}(匿名化IDに置換) |
| PatientID | 患者ID | {id} |
| PatientBirthDate | 生年月日 | 空欄(削除) |
| PatientSex | 患者性別 | 空欄 |
| StudyDate / SeriesDate / AcquisitionDate / ContentDate | 各種日付 | 空欄 |
| AccessionNumber | アクセッション番号 | 空欄 |
| InstitutionName / Manufacturer | 施設名・製造元 | 空欄 |
| ReferringPhysicianName / OperatorsName | 紹介医・操作者名 | 空欄 |
| StudyDescription / SeriesDescription | 検査・シリーズ説明 | 空欄 |
| 出力先 | 説明 |
|---|---|
| アプリと同じ場所 | exeファイルがあるフォルダに出力 |
| 元フォルダと同じ場所 | 元データの隣に「_匿名化」サフィックス付きで出力(デフォルト) |
| 指定した場所 | 任意のフォルダを指定 |
⚠ セキュリティ上の注意:
Feistelモードでは、すべてのID変換がSEED値を鍵として行われます。仮にある患者の「元ID → 匿名化ID」の対応が漏洩しても、SEED値がなければ他の患者のID対応を逆算することはできません。
では、既知の対応ペアからSEED値を逆算できるか? SEED値は95種の文字から20文字を生成(約131ビットのエントロピー)し、さらにPBKDF2-SHA256で10万回反復して256ビット鍵に変換されます。この鍵空間を総当たりで探索するには、毎秒1兆回の試行でも約1025年(宇宙の年齢の約1,000兆倍)が必要であり、事実上不可能です。
Q. SEED値を忘れた場合、匿名化を解除できますか?
A. Feistelモードの場合、SEED値がなければ解除できません。SEED.conf を安全な場所にバックアップしてください。
Q. 同じIDは常に同じ匿名化IDになりますか?
A. Feistelモードでは、同じSEED値を使う限り常に同じ結果になります。対応表モードでは対応表CSVで管理されます。
Q. 匿名化済みデータに新しいデータを追加できますか?
A. 対応表モードでは差分処理に対応しています。既存の対応表を維持したまま、新規IDのみ追加処理できます。
Q. DICOMファイルかどうかの判定基準は?
A. 拡張子が .dcm のファイル、または拡張子がないファイルで先頭128バイト後に DICM マジックバイトがあるファイルを認識します。
Q. 親フォルダにある患者一覧CSV/Excelも匿名化されますか?
A. はい。ID名サブフォルダの処理後に、親フォルダ直下のCSV/Excelも自動で匿名化されます。ID列は値のパターンから自動検出され、名前列はヘッダキーワードから検出されます。
Q. CSVに「プランID」「患者番号」「患者ID」など複数のID列がある場合、正しく区別できますか?
A. ヘッダ名ではなく列の値で判定するため、1-2桁の「プランID」「患者番号」と7桁の「患者ID」は正しく区別されます。既知のIDと値が一致する列のみが匿名化対象になります。
Q. サブフォルダがなくDICOMやCSVだけのフォルダでも使えますか?
A. はい。サブフォルダがない場合は自動的に親フォルダ内のDICOMまたはCSV/Excelを検出して処理します。Feistel暗号化・対応表作成のどちらのモードでも動作します。
匿名化ツール 利用許諾
サードパーティライセンス
本アプリケーションは Python, customtkinter, pydicom, openpyxl, windnd(いずれもMITまたはPSFライセンス)を使用しています。ビルドにはPyInstaller(GPL-2.0 with Bootloader Exception)を使用。詳細は同梱の THIRD_PARTY_LICENSES.txt を参照してください。
2026年3月
2026年3月