JavaScript Tips | 文字列ユーティリティ:生成 - マスク文字列

JavaScript JavaScript
スポンサーリンク

「マスク文字列」で何をしたいのかをはっきりさせる

まず、「マスク文字列」でやりたいことを言葉にしてみます。

画面に本物の値は出したくないけれど、「それっぽく」見せたい。
例:************-****-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*******

こうなると、「どれが正しい仕様?」となりがちです。

なので、

  • maskAll
  • maskKeepLast
  • maskKeepFirst
  • maskEmail

のようなユーティリティを一箇所に置いて、
「マスクのルールはここに集約する」と決めておくと、
仕様変更にも強く、コードも読みやすくなります。

「どこまで見せてよいか」はビジネス側と決める

マスクは、単なる見た目の話ではなく、情報漏えいリスクの話でもあります。

  • 電話番号の末尾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

のようなユーティリティを置いて、
「マスクしたいときは必ずここを通す」というルールにしてみてください。

その瞬間、あなたのマスク処理は
場当たり的な *** 連打から、
意図とポリシーを持った「マスク文字列ユーティリティ」に一段レベルアップします。

タイトルとURLをコピーしました