「マスク文字列」で何をしたいのかをはっきりさせる
まず、「マスク文字列」でやりたいことを言葉にしてみます。
画面に本物の値は出したくないけれど、「それっぽく」見せたい。
例:******** や ****-****-1234 のように、一部だけ隠す。
つまり、「元の文字列をそのまま見せない代わりに、“マスクされた文字列”を生成するユーティリティ」を作る、という話です。
ここで大事なのは、用途によってやり方が変わることです。
- 全部をマスクしたい(パスワード表示など)
- 一部だけ残して、残りをマスクしたい(電話番号・カード番号など)
この2パターンを押さえておくと、業務でほぼ困りません。
基本形:全部を同じ文字でマスクする
一番シンプルな「全マスク」ユーティリティ
まずは、「長さだけ同じで、中身は全部 * にする」パターンです。
function maskAll(value, maskChar = "*") {
if (value == null) return "";
const s = String(value);
if (s === "") return "";
return maskChar.repeat(s.length);
}
JavaScriptやっていることを噛み砕きます。
null/undefinedが来たら空文字を返す。- 数値が来ても対応できるように
String(value)で文字列化。 - 空文字ならそのまま空文字。
maskChar.repeat(s.length)で、元の文字数と同じだけマスク文字を並べる。
動きのイメージはこうです。
maskAll("password"); // "********"
maskAll("123456"); // "******"
maskAll(123456); // "******"
maskAll(""); // ""
JavaScriptパスワードやシークレットキーなど、「一切中身を見せたくない」ものには、この形が一番安全です。
応用:末尾だけ残して、残りをマスクする
よくある要件「最後の4桁だけ見せたい」
電話番号やカード番号などで、よくこういう表示を見ます。
****-****-1234***-***-5678
これは、「末尾の数文字だけ残して、前を全部マスクする」というパターンです。
末尾 N 文字だけ残すユーティリティ
function maskKeepLast(value, keep = 4, maskChar = "*") {
if (value == null) return "";
const s = String(value);
if (s === "") return "";
if (s.length <= keep) {
// 短すぎる場合は、そのまま返す or 全マスクなど、方針を決める
return s;
}
const maskedLength = s.length - keep;
const maskedPart = maskChar.repeat(maskedLength);
const visiblePart = s.slice(-keep);
return maskedPart + visiblePart;
}
JavaScriptポイントはここです。
keepは「末尾に残す文字数」。- 全体の長さが
keep以下なら、どうするかを決める(ここではそのまま返す)。 s.length - keep文字分をマスク文字で埋める。s.slice(-keep)で末尾keep文字を取り出す。
動きのイメージはこうです。
maskKeepLast("09012345678"); // "*******5678"
maskKeepLast("1234567890123456"); // "************3456"
maskKeepLast("1234", 4); // "1234"(そのまま)
maskKeepLast("123", 4); // "123"(そのまま)
JavaScript電話番号・カード番号・会員番号など、「一部だけ見せたい」場面でそのまま使えます。
応用:先頭だけ残して、残りをマスクする
「最初の数文字で誰かは分かるけど、全部は見せない」
例えば、ユーザー名やメールアドレスの一部を隠したいときに、
yama****ta****@example.com
のように、「先頭だけ残して、残りをマスクする」こともあります。
先頭 N 文字だけ残すユーティリティ
function maskKeepFirst(value, keep = 2, maskChar = "*") {
if (value == null) return "";
const s = String(value);
if (s === "") return "";
if (s.length <= keep) {
return s;
}
const visiblePart = s.slice(0, keep);
const maskedLength = s.length - keep;
const maskedPart = maskChar.repeat(maskedLength);
return visiblePart + maskedPart;
}
JavaScript動きのイメージはこうです。
maskKeepFirst("yamada", 2); // "ya***"
maskKeepFirst("taro", 1); // "t***"
maskKeepFirst("ab", 3); // "ab"(そのまま)
JavaScript「誰かはなんとなく分かるけど、フルでは見せない」というバランスを取りたいときに便利です。
少し実務寄り:メールアドレスのマスク
ローカル部だけ部分的に隠したい
メールアドレスは、ローカル部@ドメイン という構造をしています。
taro.yamada@example.com
よくあるマスクの仕方は、「ローカル部だけ部分的に隠す」です。
function maskEmail(email, maskChar = "*") {
if (email == null) return "";
const s = String(email);
const atIndex = s.indexOf("@");
if (atIndex <= 0) {
// メールアドレスっぽくない場合は、全体をマスクするなど方針次第
return maskAll(s, maskChar);
}
const local = s.slice(0, atIndex);
const domain = s.slice(atIndex); // "@example.com" を含む
const maskedLocal = maskKeepFirst(local, 1, maskChar);
return maskedLocal + domain;
}
JavaScript動きはこうなります。
maskEmail("taro@example.com"); // "t***@example.com"
maskEmail("yamada.taro@example.com"); // "y*********@example.com"
JavaScript「誰のメールアドレスかはなんとなく分かるけど、フルでは見せない」という、
実務でよくあるバランスを簡単に実現できます。
設計として意識してほしいこと
「マスクのルール」をユーティリティに閉じ込める
マスク処理は、画面ごとにバラバラに書き始めると、すぐにカオスになります。
- 画面A:電話番号は
*******1234 - 画面B:電話番号は
***-***-1234 - 画面C:電話番号は
090*******
こうなると、「どれが正しい仕様?」となりがちです。
なので、
maskAllmaskKeepLastmaskKeepFirstmaskEmail
のようなユーティリティを一箇所に置いて、
「マスクのルールはここに集約する」と決めておくと、
仕様変更にも強く、コードも読みやすくなります。
「どこまで見せてよいか」はビジネス側と決める
マスクは、単なる見た目の話ではなく、情報漏えいリスクの話でもあります。
- 電話番号の末尾4桁を見せてよいか。
- メールアドレスのローカル部をどこまで見せてよいか。
- 社員番号・顧客番号をどこまで見せてよいか。
これはエンジニアだけで決める話ではなく、
ビジネス側・セキュリティポリシーと一緒に決めるべき内容です。
ユーティリティは、「決まったルールを正確に実装する場所」として設計しておくと、
役割分担がとてもクリアになります。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
maskAll("secret-value");
maskKeepLast("09012345678", 4);
maskKeepFirst("yamada", 2);
maskEmail("taro.yamada@example.com");
JavaScript「どこが残って、どこが * になるか」を目で確認してみてください。
そのうえで、自分のプロジェクトに
export function maskAll(...) { ... }
export function maskKeepLast(...) { ... }
export function maskKeepFirst(...) { ... }
export function maskEmail(...) { ... }
JavaScriptのようなユーティリティを置いて、
「マスクしたいときは必ずここを通す」というルールにしてみてください。
その瞬間、あなたのマスク処理は
場当たり的な *** 連打から、
意図とポリシーを持った「マスク文字列ユーティリティ」に一段レベルアップします。
